Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #pragma once
00024
00025 #include "cinder/Cinder.h"
00026 #include "cinder/ImageIo.h"
00027 #include "cinder/Stream.h"
00028 #include "cinder/qtime/QuickTime.h"
00029
00030 #include <string>
00031
00032
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 typedef std::shared_ptr<MovieWriter> MovieWriterRef;
00056
00057 class MovieWriter {
00058 struct Obj;
00059
00060 public:
00062 class Format {
00063 public:
00064 Format();
00065 Format( uint32_t codec, float quality );
00066 Format( const ICMCompressionSessionOptionsRef settings, uint32_t codec, float quality, float frameRate, bool enableMultiPass );
00067 Format( const Format &format );
00068 ~Format();
00069
00070 const Format& operator=( const Format &format );
00071
00073 uint32_t getCodec() const { return mCodec; }
00075 Format& setCodec( uint32_t codec ) { mCodec = codec; return *this; }
00077 float getQuality() const { return mQualityFloat; }
00079 Format& setQuality( float quality );
00081 float getDefaultDuration() const { return mDefaultTime; }
00083 Format& setDefaultDuration( float defaultDuration ) { mDefaultTime = defaultDuration; return *this; }
00085 long getTimeScale() const { return mTimeBase; }
00087 Format& setTimeScale( long timeScale ) { mTimeBase = timeScale; return *this; }
00089 float getGamma() const { return mGamma; }
00091 Format& setGamma( float gamma ) { mGamma = gamma; return *this; }
00093 bool isTemporal() const;
00095 Format& enableTemporal( bool enable = true );
00097 bool isReordering() const;
00099 Format& enableReordering( bool enable = true );
00101 int32_t getMaxKeyFrameRate() const;
00103 Format& setMaxKeyFrameRate( int32_t rate );
00105 bool isFrameTimeChanges() const;
00107 Format& enableFrameTimeChanges( bool enable = true );
00109 bool isMultiPass() const { return mEnableMultiPass; }
00111 Format& enableMultiPass( bool enable = true ) { mEnableMultiPass = enable; return *this; }
00112
00113 private:
00114 void initDefaults();
00115
00116 uint32_t mCodec;
00117 long mTimeBase;
00118 float mDefaultTime;
00119 float mQualityFloat;
00120 float mGamma;
00121 bool mEnableMultiPass;
00122
00123 ICMCompressionSessionOptionsRef mOptions;
00124
00125 friend class MovieWriter;
00126 friend struct Obj;
00127 };
00128
00129
00130 MovieWriter() {}
00131 MovieWriter( const fs::path &path, int32_t width, int32_t height, const Format &format = Format::Format() );
00132
00133 static MovieWriterRef create( const fs::path &path, int32_t width, int32_t height, const Format &format = Format::Format() )
00134 { return std::shared_ptr<MovieWriter>( new MovieWriter( path, width, height, format ) ); }
00135
00137 float getDefaultDuration() const { return mObj->mFormat.mDefaultTime; }
00139 int32_t getWidth() const { return mObj->mWidth; }
00141 int32_t getHeight() const { return mObj->mHeight; }
00143 Vec2i getSize() const { return Vec2i( getWidth(), getHeight() ); }
00145 float getAspectRatio() const { return getWidth() / (float)getHeight(); }
00147 Area getBounds() const { return Area( 0, 0, getWidth(), getHeight() ); }
00148
00150 const Format& getFormat() const { return mObj->mFormat; }
00151
00154 static bool getUserCompressionSettings( Format *result, ImageSourceRef previewImage = ImageSourceRef() );
00155
00158 void addFrame( const ImageSourceRef &imageSource, float duration = -1.0f ) { mObj->addFrame( imageSource, duration ); }
00159
00161 uint32_t getNumFrames() const { return mObj->mNumFrames; }
00162
00164 void finish() { mObj->finish(); }
00165
00166 enum { CODEC_H264 = 'avc1', CODEC_JPEG = 'jpeg', CODEC_MP4 = 'mp4v', CODEC_PNG = 'png ', CODEC_RAW = 'raw ', CODEC_ANIMATION = 'rle ' };
00167
00168 private:
00170 struct Obj {
00171 Obj( const fs::path &path, int32_t width, int32_t height, const Format &format );
00172 ~Obj();
00173
00174 void addFrame( const ImageSourceRef &imageSource, float duration );
00175 void createCompressionSession();
00176 void finish();
00177
00178 static OSStatus encodedFrameOutputCallback( void *refCon, ::ICMCompressionSessionRef session, OSStatus err, ICMEncodedFrameRef encodedFrame, void *reserved );
00179
00180 ::Movie mMovie;
00181 ::DataHandler mDataHandler;
00182 ::Track mTrack;
00183 ::Media mMedia;
00184 ::ICMCompressionSessionRef mCompressionSession;
00185 ::ICMCompressionPassModeFlags mMultiPassModeFlags;
00186 fs::path mPath;
00187 uint32_t mNumFrames;
00188 int64_t mCurrentTimeValue;
00189
00190 int32_t mWidth, mHeight;
00191 Format mFormat;
00192 bool mRequestedMultiPass, mDoingMultiPass, mFinished;
00193
00194 IoStreamRef mMultiPassFrameCache;
00195
00196 std::vector<std::pair<int64_t,int64_t> > mFrameTimes;
00197 };
00199
00200 std::shared_ptr<Obj> mObj;
00201
00202 public:
00204
00205 typedef std::shared_ptr<Obj> MovieWriter::*unspecified_bool_type;
00206 operator unspecified_bool_type() const { return ( mObj.get() == 0 ) ? 0 : &MovieWriter::mObj; }
00207 void reset() { mObj.reset(); }
00209 };
00210
00211 class MovieWriterExc : public Exception {
00212 };
00213 class MovieWriterExcInvalidPath : public MovieWriterExc {
00214 };
00215 class MovieWriterExcFrameEncode : public MovieWriterExc {
00216 };
00217 class MovieWriterExcAlreadyFinished : public MovieWriterExc {
00218 };
00219
00220 } }