Cinder

  • Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • Examples
  • File List
  • File Members

include/cinder/qtime/MovieWriter.h

Go to the documentation of this file.
00001 /*
00002  Copyright (c) 2010, The Barbarian Group
00003  All rights reserved.
00004  
00005  Redistribution and use in source and binary forms, with or without modification, are permitted provided that
00006  the following conditions are met:
00007  
00008  * Redistributions of source code must retain the above copyright notice, this list of conditions and
00009  the following disclaimer.
00010  * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
00011  the following disclaimer in the documentation and/or other materials provided with the distribution.
00012  
00013  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
00014  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00015  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
00016  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
00017  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00018  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00019  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00020  POSSIBILITY OF SUCH DAMAGE.
00021  */
00022 
00023 #pragma once
00024 
00025 #include "cinder/Cinder.h"
00026 #include "cinder/qtime/QuickTime.h"
00027 #include "cinder/ImageIo.h"
00028 #include "cinder/Stream.h"
00029 
00030 #include <string>
00031 
00032 // These forward declarations prevent us from having to bring all of QuickTime into the global namespace in MSW
00034 #if defined( CINDER_MSW )
00035     typedef struct ComponentInstanceRecord      ComponentInstanceRecord;
00036     typedef ComponentInstanceRecord *           ComponentInstance;
00037     typedef ComponentInstance                   DataHandler;
00038     typedef struct TrackType**                  Track;
00039     typedef struct MediaType**                  Media;
00040     typedef struct OpaqueICMCompressionSession*         ICMCompressionSessionRef;
00041     typedef struct OpaqueICMCompressionSessionOptions*  ICMCompressionSessionOptionsRef;
00042     typedef const struct OpaqueICMEncodedFrame* ICMEncodedFrameRef;
00043     typedef signed long                         OSStatus;
00044     typedef unsigned long                       CodecType;
00045     typedef unsigned long                       ICMCompressionPassModeFlags;
00046 #else
00047     #include <QuickTime/QuickTime.h>
00048     #include <QuickTime/ImageCompression.h>
00049 #endif // defined( CINDER_MSW )
00050 
00051 
00052 namespace cinder { namespace qtime {
00053 
00054 class MovieWriter {
00055     struct Obj;
00056 
00057   public:
00059     class Format {
00060       public:
00061         Format();
00062         Format( uint32_t codec, float quality );
00063         Format( const ICMCompressionSessionOptionsRef settings, uint32_t codec, float quality, float frameRate, bool enableMultiPass );
00064         Format( const Format &format );
00065         ~Format();
00066 
00067         const Format& operator=( const Format &format );
00068 
00070         uint32_t    getCodec() const { return mCodec; }
00072         Format&     setCodec( uint32_t codec ) { mCodec = codec; return *this; }
00074         float       getQuality() const { return mQualityFloat; }
00076         Format&     setQuality( float quality );
00078         float       getDefaultDuration() const { return mDefaultTime; }
00080         Format&     setDefaultDuration( float defaultDuration ) { mDefaultTime = defaultDuration; return *this; }
00082         long        getTimeScale() const { return mTimeBase; }
00084         Format&     setTimeScale( long timeScale ) { mTimeBase = timeScale; return *this; }
00086         float       getGamma() const { return mGamma; }
00088         Format&     setGamma( float gamma ) { mGamma = gamma; return *this; }
00090         bool        isTemporal() const;
00092         Format&     enableTemporal( bool enable = true );
00094         bool        isReordering() const;
00096         Format&     enableReordering( bool enable = true );
00098         int32_t     getMaxKeyFrameRate() const;
00100         Format&     setMaxKeyFrameRate( int32_t rate );
00102         bool        isFrameTimeChanges() const;
00104         Format&     enableFrameTimeChanges( bool enable = true );
00106         bool        isMultiPass() const { return mEnableMultiPass; }
00108         Format&     enableMultiPass( bool enable = true ) { mEnableMultiPass = enable; return *this; }
00109 
00110       private:
00111         void        initDefaults();
00112 
00113         uint32_t    mCodec;
00114         long        mTimeBase;
00115         float       mDefaultTime;
00116         float       mQualityFloat;
00117         float       mGamma;
00118         bool        mEnableMultiPass;
00119 
00120         ICMCompressionSessionOptionsRef     mOptions;
00121 
00122         friend class MovieWriter;
00123         friend struct Obj;
00124     };
00125 
00126 
00127     MovieWriter() {}
00128     MovieWriter( const fs::path &path, int32_t width, int32_t height, const Format &format = Format::Format() );
00129 
00131     float   getDefaultDuration() const { return mObj->mFormat.mDefaultTime; }
00133     int32_t getWidth() const { return mObj->mWidth; }
00135     int32_t getHeight() const { return mObj->mHeight; }
00137     Vec2i   getSize() const { return Vec2i( getWidth(), getHeight() ); }
00139     float   getAspectRatio() const { return getWidth() / (float)getHeight(); }
00141     Area    getBounds() const { return Area( 0, 0, getWidth(), getHeight() ); }
00142 
00144     const Format&   getFormat() const { return mObj->mFormat; }
00145 
00148     static bool     getUserCompressionSettings( Format *result, ImageSourceRef previewImage = ImageSourceRef() );
00149 
00152     void addFrame( const ImageSourceRef &imageSource, float duration = -1.0f ) { mObj->addFrame( imageSource, duration ); }
00153     
00155     uint32_t    getNumFrames() const { return mObj->mNumFrames; }
00156 
00158     void finish() { mObj->finish(); }
00159     
00160     enum { CODEC_H264 = 'avc1', CODEC_JPEG = 'jpeg', CODEC_MP4 = 'mp4v', CODEC_PNG = 'png ', CODEC_RAW = 'raw ', CODEC_ANIMATION = 'rle ' };
00161 
00162   private:
00164     struct Obj {
00165         Obj( const fs::path &path, int32_t width, int32_t height, const Format &format );
00166         ~Obj();
00167         
00168         void    addFrame( const ImageSourceRef &imageSource, float duration );
00169         void    createCompressionSession();
00170         void    finish();
00171         
00172         static OSStatus encodedFrameOutputCallback( void *refCon, ::ICMCompressionSessionRef session, OSStatus err, ICMEncodedFrameRef encodedFrame, void *reserved );
00173 
00174 		::Movie                           mMovie;
00175         ::DataHandler                   mDataHandler;
00176         ::Track                         mTrack;
00177         ::Media                         mMedia;
00178         ::ICMCompressionSessionRef      mCompressionSession;
00179         ::ICMCompressionPassModeFlags   mMultiPassModeFlags;        
00180         fs::path        mPath;
00181         uint32_t        mNumFrames;
00182         int64_t         mCurrentTimeValue;
00183         
00184         int32_t     mWidth, mHeight;
00185         Format      mFormat;
00186         bool        mRequestedMultiPass, mDoingMultiPass, mFinished;        
00187 
00188         IoStreamRef     mMultiPassFrameCache;
00189 
00190         std::vector<std::pair<int64_t,int64_t> >    mFrameTimes;
00191     };
00193     
00194     std::shared_ptr<Obj>        mObj;  
00195 
00196   public:
00198 
00199     typedef std::shared_ptr<Obj> MovieWriter::*unspecified_bool_type;
00200     operator unspecified_bool_type() const { return ( mObj.get() == 0 ) ? 0 : &MovieWriter::mObj; }
00201     void reset() { mObj.reset(); }
00203 };
00204 
00205 class MovieWriterExc : public Exception {
00206 };
00207 class MovieWriterExcInvalidPath : public MovieWriterExc {
00208 };
00209 class MovieWriterExcFrameEncode : public MovieWriterExc {
00210 };
00211 class MovieWriterExcAlreadyFinished : public MovieWriterExc {
00212 };
00213 
00214 } } // namespace cinder::qtime