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
00026 #if ! defined( __LP64__ )
00027
00028 #include "cinder/Cinder.h"
00029 #include "cinder/gl/gl.h"
00030 #include "cinder/Surface.h"
00031 #include "cinder/gl/Texture.h"
00032 #include "cinder/Display.h"
00033 #include "cinder/Url.h"
00034 #include "cinder/DataSource.h"
00035 #include "cinder/Thread.h"
00036
00037 #include <string>
00038
00039 #if defined( CINDER_MAC )
00040 #include <QuickTime/QuickTime.h>
00041 #if defined( __OBJC__ )
00042 @class QTMovie;
00043 #else
00044 class QTMovie;
00045 #endif
00046 #endif
00047
00048
00049
00050 #if defined( CINDER_MSW )
00051 typedef struct MovieType** Movie;
00052 typedef struct OpaqueQTVisualContext* QTVisualContextRef;
00053 typedef long TimeValue;
00054 typedef struct QTAudioFrequencyLevels QTAudioFrequencyLevels;
00055 typedef unsigned long FourCharCode;
00056 typedef struct __CVBuffer* CVBufferRef;
00057 typedef CVBufferRef CVImageBufferRef;
00058 #endif
00059
00060 namespace cinder { namespace qtime {
00061
00062 class MovieLoader;
00063 typedef std::shared_ptr<MovieLoader> MovieLoaderRef;
00064
00065 class MovieBase {
00066 public:
00067 virtual ~MovieBase() {}
00068
00070 bool checkPlayable();
00071
00073 int32_t getWidth() const { return getObj()->mWidth; }
00075 int32_t getHeight() const { return getObj()->mHeight; }
00077 Vec2i getSize() const { return Vec2i( getWidth(), getHeight() ); }
00079 float getAspectRatio() const { return getObj()->mWidth / (float)getObj()->mHeight; }
00081 Area getBounds() const { return Area( 0, 0, getWidth(), getHeight() ); }
00083 float getPixelAspectRatio() const;
00085 float getDuration() const { return getObj()->mDuration; }
00087 float getFramerate() const;
00089 int32_t getNumFrames() const;
00091 bool hasAlpha() const;
00092
00094 bool hasVisuals() const;
00096 bool hasAudio() const;
00097
00099 bool checkNewFrame();
00100
00102 float getCurrentTime() const;
00104 void seekToTime( float seconds );
00106 void seekToFrame( int frame );
00108 void seekToStart();
00110 void seekToEnd();
00112 void setActiveSegment( float startTime, float duration );
00114 void resetActiveSegment();
00115
00117 void setLoop( bool loop = true, bool palindrome = false );
00119 void stepForward();
00121 void stepBackward();
00123 void setRate( float rate );
00124
00126 void setVolume( float volume );
00128 float getVolume() const;
00129
00131 void setupMonoFft( uint32_t numBands );
00133 void setupStereoFft( uint32_t numBands );
00135 void setupMultiChannelFft( uint32_t numBands );
00136
00137 float* getFftData() const;
00138 uint32_t getNumFftBands() const;
00139 uint32_t getNumFftChannels() const;
00140
00142 bool isPlaying() const;
00144 bool isDone() const;
00146 void play();
00148 void stop();
00149
00151 void setNewFrameCallback( void(*aNewFrameCallback)( long, void * ), void *aNewFrameCallbackRefcon );
00152
00154 ::Movie getMovieHandle() const { return getObj()->mMovie; }
00155
00156 protected:
00157 MovieBase() {}
00158 void init();
00159 void updateFrame();
00160 void updateLoadState();
00161
00162 void setupFft( FourCharCode code, uint32_t bandNum, uint8_t channelNum );
00163
00164 static int32_t countFrames( ::Movie theMovie );
00165 TimeValue getStartTimeOfFirstSample() const;
00166
00167 protected:
00168 void initFromPath( const fs::path &filePath );
00169 void initFromLoader( const class MovieLoader &loader );
00170 void initFromMemory( const void *data, size_t dataSize, const std::string &fileNameHint, const std::string &mimeTypeHint );
00171 void initFromDataSource( DataSourceRef dataSource, const std::string &mimeTypeHint );
00172
00173 struct Obj {
00174 Obj();
00175 virtual ~Obj();
00176
00177 void prepareForDestruction();
00178
00179 void lock() { mMutex.lock(); }
00180 void unlock() { mMutex.unlock(); }
00181
00182
00183
00184 virtual void releaseFrame() = 0;
00185 virtual void newFrame( CVImageBufferRef cvImage ) = 0;
00186
00187 int32_t mWidth, mHeight;
00188 int32_t mFrameCount;
00189 float mDuration;
00190 bool mLoaded, mPlayable;
00191 bool mPlayingForward, mLoop, mPalindrome;
00192
00193 QTAudioFrequencyLevels *mFFTData;
00194 FourCharCode mFFTFourCharCode;
00195 uint32_t mFFTNumBandLevels;
00196 uint32_t mFFTNumChannels;
00197 QTVisualContextRef mVisualContext;
00198 ::Movie mMovie;
00199
00200 void (*mNewFrameCallback)(long timeValue, void *refcon);
00201 void *mNewFrameCallbackRefcon;
00202
00203 std::mutex mMutex;
00204 DataSourceRef mDataSource;
00205 };
00206
00207 virtual Obj* getObj() const = 0;
00208 };
00209
00210 class MovieSurface;
00211 typedef std::shared_ptr<MovieSurface> MovieSurfaceRef;
00212
00213 class MovieSurface : public MovieBase {
00214 public:
00215 MovieSurface() : MovieBase() {}
00216 MovieSurface( const fs::path &path );
00217 MovieSurface( const class MovieLoader &loader );
00219
00220 MovieSurface( const void *data, size_t dataSize, const std::string &fileNameHint, const std::string &mimeTypeHint = "" );
00221 MovieSurface( DataSourceRef dataSource, const std::string mimeTypeHint = "" );
00222
00223 static MovieSurfaceRef create( const fs::path &path ) { return std::shared_ptr<MovieSurface>( new MovieSurface( path ) ); }
00224 static MovieSurfaceRef create( const MovieLoaderRef &loader );
00225 static MovieSurfaceRef create( const void *data, size_t dataSize, const std::string &fileNameHint, const std::string &mimeTypeHint = "" )
00226 { return std::shared_ptr<MovieSurface>( new MovieSurface( data, dataSize, fileNameHint, mimeTypeHint ) ); }
00227 static MovieSurfaceRef create( DataSourceRef dataSource, const std::string mimeTypeHint = "" )
00228 { return std::shared_ptr<MovieSurface>( new MovieSurface( dataSource, mimeTypeHint ) ); }
00229
00231 Surface getSurface();
00232
00233 protected:
00234 void allocateVisualContext();
00235
00236 struct Obj : public MovieBase::Obj {
00237 virtual ~Obj();
00238
00239 virtual void releaseFrame();
00240 virtual void newFrame( CVImageBufferRef cvImage );
00241
00242 Surface mSurface;
00243 };
00244
00245 std::shared_ptr<Obj> mObj;
00246 virtual MovieBase::Obj* getObj() const { return mObj.get(); }
00247
00248 public:
00250
00251 typedef std::shared_ptr<Obj> MovieSurface::*unspecified_bool_type;
00252 operator unspecified_bool_type() const { return ( mObj.get() == 0 ) ? 0 : &MovieSurface::mObj; }
00253 void reset() { mObj.reset(); }
00255 };
00256
00257 class MovieGl;
00258 typedef std::shared_ptr<MovieGl> MovieGlRef;
00263 class MovieGl : public MovieBase {
00264 public:
00265 MovieGl() : MovieBase() {}
00266 MovieGl( const fs::path &path );
00267 MovieGl( const class MovieLoader &loader );
00269
00270 MovieGl( const void *data, size_t dataSize, const std::string &fileNameHint, const std::string &mimeTypeHint = "" );
00271 MovieGl( DataSourceRef dataSource, const std::string mimeTypeHint = "" );
00272
00273 static MovieGlRef create( const fs::path &path ) { return std::shared_ptr<MovieGl>( new MovieGl( path ) ); }
00274 static MovieGlRef create( const MovieLoaderRef &loader );
00275 static MovieGlRef create( const void *data, size_t dataSize, const std::string &fileNameHint, const std::string &mimeTypeHint = "" )
00276 { return std::shared_ptr<MovieGl>( new MovieGl( data, dataSize, fileNameHint, mimeTypeHint ) ); }
00277 static MovieGlRef create( DataSourceRef dataSource, const std::string mimeTypeHint = "" )
00278 { return std::shared_ptr<MovieGl>( new MovieGl( dataSource, mimeTypeHint ) ); }
00279
00281 const gl::Texture getTexture();
00282
00283 protected:
00284 void allocateVisualContext();
00285
00286 struct Obj : public MovieBase::Obj {
00287 Obj();
00288 ~Obj();
00289
00290 virtual void releaseFrame();
00291 virtual void newFrame( CVImageBufferRef cvImage );
00292
00293 gl::Texture mTexture;
00294 #if defined( CINDER_MSW )
00295 gl::TextureCache mTextureCache;
00296 #endif
00297 };
00298
00299 std::shared_ptr<Obj> mObj;
00300 virtual MovieBase::Obj* getObj() const { return mObj.get(); }
00301
00302 public:
00304
00305 typedef std::shared_ptr<Obj> MovieGl::*unspecified_bool_type;
00306 operator unspecified_bool_type() const { return ( mObj.get() == 0 ) ? 0 : &MovieGl::mObj; }
00307 void reset() { mObj.reset(); }
00309 };
00310
00311 class MovieLoader {
00312 public:
00313 MovieLoader() {}
00314 MovieLoader( const Url &url );
00315
00316 static MovieLoaderRef create( const Url &url ) { return std::shared_ptr<MovieLoader>( new MovieLoader( url ) ); }
00317
00319 bool checkLoaded() const;
00321 bool checkPlayable() const;
00323 bool checkPlaythroughOk() const;
00324
00326 void waitForLoaded() const;
00328 void waitForPlayable() const;
00330 void waitForPlaythroughOk() const;
00331
00333 const Url& getUrl() const { return mObj->mUrl; }
00334
00336 ::Movie getMovieHandle() const { return mObj->mMovie; }
00337
00339 ::Movie transferMovieHandle() const { mObj->mOwnsMovie = false; return mObj->mMovie; }
00340
00341 protected:
00342 void updateLoadState() const;
00343
00344 struct Obj {
00345 Obj( const Url &url );
00346 ~Obj();
00347
00348 mutable bool mOwnsMovie;
00349 ::Movie mMovie;
00350 Url mUrl;
00351 mutable bool mLoaded, mPlayable, mPlaythroughOK;
00352 };
00353
00354 std::shared_ptr<Obj> mObj;
00355
00356 public:
00358
00359 typedef std::shared_ptr<Obj> MovieLoader::*unspecified_bool_type;
00360 operator unspecified_bool_type() const { return ( mObj.get() == 0 ) ? 0 : &MovieLoader::mObj; }
00361 void reset() { mObj.reset(); }
00363 };
00364
00365 inline int32_t floatToFixed( float fl ) { return ((int32_t)((float)(fl) * ((int32_t) 0x00010000L))); }
00366
00368 void startQuickTime();
00370 extern int32_t getQuickTimeVersion();
00372 extern std::string getQuickTimeVersionString();
00373
00375 extern void quickTimeTask();
00376
00377 class QuickTimeExc : public std::exception {
00378 };
00379
00380 class QuickTimePathInvalidExc : public QuickTimeExc {
00381 };
00382
00383 class QuickTimeFileInvalidExc : public QuickTimeExc {
00384 };
00385
00386 class QuickTimeExcUrlInvalid : public QuickTimeExc {
00387 };
00388
00389 class QuickTimeErrorLoadingExc : public QuickTimeExc {
00390 };
00391
00392 class QuickTimeExcFft : public QuickTimeExc {
00393 };
00394
00395 } }
00396 #endif // ! defined( __LP64__ )