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 MovieBase {
00063 public:
00064 virtual ~MovieBase() {}
00065
00067 bool checkPlayable();
00068
00070 int32_t getWidth() const { return getObj()->mWidth; }
00072 int32_t getHeight() const { return getObj()->mHeight; }
00074 float getAspectRatio() const { return getObj()->mWidth / (float)getObj()->mHeight; }
00076 float getDuration() const { return getObj()->mDuration; }
00078 float getFramerate() const;
00080 int32_t getNumFrames() const;
00082 bool hasAlpha() const;
00083
00085 bool hasVisuals() const;
00087 bool hasAudio() const;
00088
00089
00091 float getCurrentTime() const;
00093 void seekToTime( float seconds );
00095 void seekToFrame( int frame );
00097 void seekToStart();
00099 void seekToEnd();
00101 void setActiveSegment( float startTime, float duration );
00103 void resetActiveSegment();
00104
00106 void setLoop( bool loop = true, bool palindrome = false );
00108 void stepForward();
00110 void stepBackward();
00112 void setRate( float rate );
00113
00115 void setVolume( float volume );
00117 float getVolume() const;
00118
00120 void setupMonoFft( uint32_t numBands );
00122 void setupStereoFft( uint32_t numBands );
00124 void setupMultiChannelFft( uint32_t numBands );
00125
00126 float* getFftData() const;
00127 uint32_t getNumFftBands() const;
00128 uint32_t getNumFftChannels() const;
00129
00131 bool isPlaying() const;
00133 bool isDone() const;
00135 void play();
00137 void stop();
00138
00140 void setNewFrameCallback( void(*aNewFrameCallback)( long, void * ), void *aNewFrameCallbackRefcon );
00141
00143 ::Movie getMovieHandle() const { return getObj()->mMovie; }
00144
00145 protected:
00146 MovieBase() {}
00147 void init();
00148 void updateFrame();
00149 void updateLoadState();
00150
00151 void setupFft( FourCharCode code, uint32_t bandNum, uint8_t channelNum );
00152
00153 static int32_t countFrames( ::Movie theMovie );
00154 TimeValue getStartTimeOfFirstSample() const;
00155
00156 protected:
00157 void initFromPath( const std::string &path );
00158 void initFromLoader( const class MovieLoader &loader );
00159 void initFromMemory( const void *data, size_t dataSize, const std::string &fileNameHint, const std::string &mimeTypeHint );
00160 void initFromDataSource( DataSourceRef dataSource, const std::string &mimeTypeHint );
00161
00162 struct Obj {
00163 Obj();
00164 virtual ~Obj();
00165
00166 void prepareForDestruction();
00167
00168 void lock() { mMutex.lock(); }
00169 void unlock() { mMutex.unlock(); }
00170
00171
00172
00173 virtual void releaseFrame() = 0;
00174 virtual void newFrame( CVImageBufferRef cvImage ) = 0;
00175
00176 int32_t mWidth, mHeight;
00177 int32_t mFrameCount;
00178 float mDuration;
00179 bool mLoaded, mPlayable;
00180 bool mPlayingForward, mLoop, mPalindrome;
00181
00182 QTAudioFrequencyLevels *mFFTData;
00183 FourCharCode mFFTFourCharCode;
00184 uint32_t mFFTNumBandLevels;
00185 uint32_t mFFTNumChannels;
00186 QTVisualContextRef mVisualContext;
00187 ::Movie mMovie;
00188
00189 void (*mNewFrameCallback)(long timeValue, void *refcon);
00190 void *mNewFrameCallbackRefcon;
00191
00192 std::mutex mMutex;
00193 DataSourceRef mDataSource;
00194 };
00195
00196 virtual Obj* getObj() const = 0;
00197 };
00198
00199 class MovieSurface : public MovieBase {
00200 public:
00201 MovieSurface() : MovieBase() {}
00202 MovieSurface( const std::string &path );
00203 MovieSurface( const class MovieLoader &loader );
00205
00206 MovieSurface( const void *data, size_t dataSize, const std::string &fileNameHint, const std::string &mimeTypeHint = "" );
00207 MovieSurface( DataSourceRef dataSource, const std::string mimeTypeHint = "" );
00208
00210 Surface getSurface();
00211
00212 protected:
00213 void allocateVisualContext();
00214
00215 struct Obj : public MovieBase::Obj {
00216 virtual ~Obj();
00217
00218 virtual void releaseFrame();
00219 virtual void newFrame( CVImageBufferRef cvImage );
00220
00221 Surface mSurface;
00222 };
00223
00224 shared_ptr<Obj> mObj;
00225 virtual MovieBase::Obj* getObj() const { return mObj.get(); }
00226
00227 public:
00229
00230 typedef shared_ptr<Obj> MovieSurface::*unspecified_bool_type;
00231 operator unspecified_bool_type() { return ( mObj.get() == 0 ) ? 0 : &MovieSurface::mObj; }
00232 void reset() { mObj.reset(); }
00234 };
00235
00240 class MovieGl : public MovieBase {
00241 public:
00242 MovieGl() : MovieBase() {}
00243 MovieGl( const std::string &path );
00244 MovieGl( const class MovieLoader &loader );
00246
00247 MovieGl( const void *data, size_t dataSize, const std::string &fileNameHint, const std::string &mimeTypeHint = "" );
00248 MovieGl( DataSourceRef dataSource, const std::string mimeTypeHint = "" );
00249
00251 const gl::Texture getTexture();
00252
00253 protected:
00254 void allocateVisualContext();
00255
00256 struct Obj : public MovieBase::Obj {
00257 Obj();
00258 ~Obj();
00259
00260 virtual void releaseFrame();
00261 virtual void newFrame( CVImageBufferRef cvImage );
00262
00263 gl::Texture mTexture;
00264 #if defined( CINDER_MSW )
00265 gl::TextureCache mTextureCache;
00266 #endif
00267 };
00268
00269 shared_ptr<Obj> mObj;
00270 virtual MovieBase::Obj* getObj() const { return mObj.get(); }
00271
00272 public:
00274
00275 typedef shared_ptr<Obj> MovieGl::*unspecified_bool_type;
00276 operator unspecified_bool_type() { return ( mObj.get() == 0 ) ? 0 : &MovieGl::mObj; }
00277 void reset() { mObj.reset(); }
00279 };
00280
00281 class MovieLoader {
00282 public:
00283 MovieLoader() {}
00284 MovieLoader( const Url &url );
00285
00287 bool checkLoaded() const;
00289 bool checkPlayable() const;
00291 bool checkPlaythroughOk() const;
00292
00294 void waitForLoaded() const;
00296 void waitForPlayable() const;
00298 void waitForPlaythroughOk() const;
00299
00301 const Url& getUrl() const { return mObj->mUrl; }
00302
00304 ::Movie getMovieHandle() const { return mObj->mMovie; }
00305
00307 ::Movie transferMovieHandle() const { mObj->mOwnsMovie = false; return mObj->mMovie; }
00308
00309 protected:
00310 void updateLoadState() const;
00311
00312 struct Obj {
00313 Obj( const Url &url );
00314 ~Obj();
00315
00316 mutable bool mOwnsMovie;
00317 ::Movie mMovie;
00318 Url mUrl;
00319 mutable bool mLoaded, mPlayable, mPlaythroughOK;
00320 };
00321
00322 shared_ptr<Obj> mObj;
00323
00324 public:
00326
00327 MovieLoader( const MovieLoader &other ) { mObj = other.mObj; }
00328 MovieLoader& operator=( const MovieLoader &other ) { mObj = other.mObj; return *this; }
00329 bool operator==( const MovieLoader &other ) { return mObj == other.mObj; }
00330 typedef shared_ptr<Obj> MovieLoader::*unspecified_bool_type;
00331 operator unspecified_bool_type() { return ( mObj.get() == 0 ) ? 0 : &MovieLoader::mObj; }
00332 void reset() { mObj.reset(); }
00334 };
00335
00337 extern int32_t getQuickTimeVersion();
00339 extern std::string getQuickTimeVersionString();
00340
00342 extern void quickTimeTask();
00343
00344 class QuickTimeExc : public std::exception {
00345 };
00346
00347 class QuickTimePathInvalidExc : public QuickTimeExc {
00348 };
00349
00350 class QuickTimeFileInvalidExc : public QuickTimeExc {
00351 };
00352
00353 class QuickTimeExcUrlInvalid : public QuickTimeExc {
00354 };
00355
00356 class QuickTimeErrorLoadingExc : public QuickTimeExc {
00357 };
00358
00359 class QuickTimeExcFft : public QuickTimeExc {
00360 };
00361
00362 } }
00363 #endif // ! defined( __LP64__ )