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/qtime/QuickTime.h"
00027 #include "cinder/ImageIo.h"
00028 #include "cinder/Stream.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 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 } }