Cinder

  • Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • 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 #include "cinder/Cinder.h"
00024 #include "cinder/qtime/QuickTime.h"
00025 #include "cinder/ImageIo.h"
00026 #include "cinder/Stream.h"
00027 
00028 #include <string>
00029 
00030 // These forward declarations prevent us from having to bring all of QuickTime into the global namespace in MSW
00032 #if defined( CINDER_MSW )
00033     typedef struct ComponentInstanceRecord      ComponentInstanceRecord;
00034     typedef ComponentInstanceRecord *           ComponentInstance;
00035     typedef ComponentInstance                   DataHandler;
00036     typedef struct TrackType**                  Track;
00037     typedef struct MediaType**                  Media;
00038     typedef struct OpaqueICMCompressionSession*         ICMCompressionSessionRef;
00039     typedef struct OpaqueICMCompressionSessionOptions*  ICMCompressionSessionOptionsRef;
00040     typedef const struct OpaqueICMEncodedFrame* ICMEncodedFrameRef;
00041     typedef signed long                         OSStatus;
00042     typedef unsigned long                       CodecType;
00043     typedef unsigned long                       ICMCompressionPassModeFlags;
00044 #else
00045     #include <QuickTime/QuickTime.h>
00046     #include <QuickTime/ImageCompression.h>
00047 #endif // defined( CINDER_MSW )
00048 
00049 
00050 namespace cinder { namespace qtime {
00051 
00052 class MovieWriter {
00053     struct Obj;
00054 
00055   public:
00057     class Format {
00058       public:
00059         Format();
00060         Format( uint32_t codec, float quality );
00061         Format( const ICMCompressionSessionOptionsRef settings, uint32_t codec, float quality, float frameRate, bool enableMultiPass );
00062         Format( const Format &format );
00063         ~Format();
00064 
00065         const Format& operator=( const Format &format );
00066 
00068         uint32_t    getCodec() const { return mCodec; }
00070         Format&     setCodec( uint32_t codec ) { mCodec = codec; return *this; }
00072         Format&     setQuality( float quality );
00074         float       getDefaultDuration() const { return mDefaultTime; }
00076         Format&     setDefaultDuration( float defaultDuration ) { mDefaultTime = defaultDuration; return *this; }
00078         long        getTimeScale() const { return mTimeBase; }
00080         Format&     setTimeScale( long timeScale ) { mTimeBase = timeScale; return *this; }
00082         float       getGamma() const { return mGamma; }
00084         Format&     setGamma( float gamma ) { mGamma = gamma; return *this; }
00086         Format&     enableTemporal( bool enable = true );
00088         Format&     enableReordering( bool enable = true );
00090         Format&     setMaxKeyFrameRate( int32_t rate );
00092         Format&     enableFrameTimeChanges( bool enable = true );
00094         bool        isMultiPass() const { return mEnableMultiPass; }
00096         Format&     enableMultiPass( bool enable = true ) { mEnableMultiPass = enable; return *this; }
00097 
00098       private:
00099         void        initDefaults();
00100 
00101         uint32_t    mCodec;
00102         long        mTimeBase;
00103         float       mDefaultTime;
00104         float       mGamma;
00105         bool        mEnableMultiPass;
00106 
00107         ICMCompressionSessionOptionsRef     mOptions;
00108 
00109         friend class MovieWriter;
00110         friend struct Obj;
00111     };
00112 
00113 
00114     MovieWriter() {}
00115     MovieWriter( const std::string &path, int32_t width, int32_t height, const Format &format = Format::Format() );
00116 
00118     float   getDefaultDuration() const { return mObj->mFormat.mDefaultTime; }
00120     int32_t getWidth() const { return mObj->mWidth; }
00122     int32_t getHeight() const { return mObj->mHeight; }
00124     Vec2i   getSize() const { return Vec2i( getWidth(), getHeight() ); }
00126     float   getAspectRatio() const { return getWidth() / (float)getHeight(); }
00128     Area    getBounds() const { return Area( 0, 0, getWidth(), getHeight() ); }
00129 
00131     const Format&   getFormat() const { return mObj->mFormat; }
00132 
00135     static bool     getUserCompressionSettings( Format *result, ImageSourceRef previewImage = ImageSourceRef() );
00136 
00139     void addFrame( const ImageSourceRef &imageSource, float duration = -1.0f ) { mObj->addFrame( imageSource, duration ); }
00140     
00142     uint32_t    getNumFrames() const { return mObj->mNumFrames; }
00143 
00145     void finish() { mObj->finish(); }
00146     
00147     enum { CODEC_H264 = 'avc1', CODEC_JPEG = 'jpeg', CODEC_MP4 = 'mp4v', CODEC_PNG = 'png ', CODEC_RAW = 'raw ', CODEC_ANIMATION = 'rle ' };
00148 
00149   private:
00151     struct Obj {
00152         Obj( const std::string &path, int32_t width, int32_t height, const Format &format );
00153         ~Obj();
00154         
00155         void    addFrame( const ImageSourceRef &imageSource, float duration );
00156         void    createCompressionSession();
00157         void    finish();
00158         
00159         static OSStatus encodedFrameOutputCallback( void *refCon, ::ICMCompressionSessionRef session, OSStatus err, ICMEncodedFrameRef encodedFrame, void *reserved );
00160 
00161 		::Movie                           mMovie;
00162         ::DataHandler                   mDataHandler;
00163         ::Track                         mTrack;
00164         ::Media                         mMedia;
00165         ::ICMCompressionSessionRef      mCompressionSession;
00166         ::ICMCompressionPassModeFlags   mMultiPassModeFlags;        
00167         std::string     mPath;
00168         uint32_t        mNumFrames;
00169         int64_t         mCurrentTimeValue;
00170         
00171         int32_t     mWidth, mHeight;
00172         Format      mFormat;
00173         bool        mRequestedMultiPass, mDoingMultiPass, mFinished;        
00174 
00175         IoStreamRef     mMultiPassFrameCache;
00176 
00177         std::vector<std::pair<int64_t,int64_t> >    mFrameTimes;
00178     };
00180     
00181     shared_ptr<Obj>     mObj;  
00182 
00183   public:
00185 
00186     typedef shared_ptr<Obj> MovieWriter::*unspecified_bool_type;
00187     operator unspecified_bool_type() const { return ( mObj.get() == 0 ) ? 0 : &MovieWriter::mObj; }
00188     void reset() { mObj.reset(); }
00190 };
00191 
00192 class MovieWriterExc : public Exception {
00193 };
00194 class MovieWriterExcInvalidPath : public MovieWriterExc {
00195 };
00196 class MovieWriterExcFrameEncode : public MovieWriterExc {
00197 };
00198 class MovieWriterExcAlreadyFinished : public MovieWriterExc {
00199 };
00200 
00201 } } // namespace cinder::qtime