Cinder

  • Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

include/cinder/qtime/QuickTime.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 #pragma once
00024 
00025 // None of this works in 64 bit on the mac or Windows. We'll need to move to QTKit on the mac.
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 // these are forward-declared to avoid bringing all of QuickTime into the global namespace on Windows
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       getPixelAspectRatio() const;
00078     float       getDuration() const { return getObj()->mDuration; }
00080     float       getFramerate() const;
00082     int32_t     getNumFrames() const;
00084     bool        hasAlpha() const;
00085 
00087     bool        hasVisuals() const;
00089     bool        hasAudio() const;
00090     
00091 
00093     float       getCurrentTime() const;
00095     void        seekToTime( float seconds );
00097     void        seekToFrame( int frame );
00099     void        seekToStart();
00101     void        seekToEnd();
00103     void        setActiveSegment( float startTime, float duration );
00105     void        resetActiveSegment();
00106 
00108     void        setLoop( bool loop = true, bool palindrome = false );
00110     void        stepForward();
00112     void        stepBackward();
00114     void        setRate( float rate );
00115 
00117     void        setVolume( float volume );
00119     float       getVolume() const;
00120 
00122     void        setupMonoFft( uint32_t numBands );
00124     void        setupStereoFft( uint32_t numBands );
00126     void        setupMultiChannelFft( uint32_t numBands );  
00127     
00128     float*      getFftData() const;
00129     uint32_t    getNumFftBands() const;
00130     uint32_t    getNumFftChannels() const;  
00131 
00133     bool    isPlaying() const;
00135     bool    isDone() const;
00137     void    play();
00139     void    stop();
00140 
00142     void    setNewFrameCallback( void(*aNewFrameCallback)( long, void * ), void *aNewFrameCallbackRefcon );
00143 
00145 	::Movie    getMovieHandle() const { return getObj()->mMovie; }
00146 
00147  protected:
00148     MovieBase() {}
00149     void            init();
00150     void            updateFrame();
00151     void            updateLoadState();
00152 
00153     void            setupFft( FourCharCode code, uint32_t bandNum, uint8_t channelNum );
00154 
00155     static int32_t      countFrames( ::Movie theMovie );
00156     TimeValue           getStartTimeOfFirstSample() const;
00157 
00158  protected:
00159     void    initFromPath( const std::string &path );
00160     void    initFromLoader( const class MovieLoader &loader );
00161     void    initFromMemory( const void *data, size_t dataSize, const std::string &fileNameHint, const std::string &mimeTypeHint );
00162     void    initFromDataSource( DataSourceRef dataSource, const std::string &mimeTypeHint );
00163  
00164     struct Obj {
00165         Obj();
00166         virtual ~Obj();
00167     
00168         void prepareForDestruction();
00169     
00170         void lock() { mMutex.lock(); }
00171         void unlock() { mMutex.unlock(); }
00172 
00173         // because the MovieBase* might change over time, but the MovieBase::Obj* will not, we need our callbacks to take an Obj* as a refcon
00174         // which in turn means this functionality must be in the Obj, not the MovieBase
00175         virtual void        releaseFrame() = 0;
00176         virtual void        newFrame( CVImageBufferRef cvImage ) = 0;
00177                 
00178         int32_t                     mWidth, mHeight;
00179         int32_t                     mFrameCount;
00180         float                       mDuration;
00181         bool                        mLoaded, mPlayable;
00182         bool                        mPlayingForward, mLoop, mPalindrome;
00183 
00184         QTAudioFrequencyLevels      *mFFTData;
00185         FourCharCode                mFFTFourCharCode;
00186         uint32_t                    mFFTNumBandLevels;
00187         uint32_t                    mFFTNumChannels;
00188         QTVisualContextRef          mVisualContext;
00189 		::Movie                       mMovie;
00190 
00191         void        (*mNewFrameCallback)(long timeValue, void *refcon);
00192         void        *mNewFrameCallbackRefcon;           
00193 
00194         std::mutex                  mMutex; 
00195         DataSourceRef               mDataSource; // sometimes used to retain a reference to a data source so that it doesn't go away before we do
00196     };
00197     
00198     virtual Obj*        getObj() const = 0;
00199 };
00200 
00201 class MovieSurface : public MovieBase {
00202  public:
00203     MovieSurface() : MovieBase() {}
00204     MovieSurface( const std::string &path );
00205     MovieSurface( const class MovieLoader &loader );
00207 
00208     MovieSurface( const void *data, size_t dataSize, const std::string &fileNameHint, const std::string &mimeTypeHint = "" );
00209     MovieSurface( DataSourceRef dataSource, const std::string mimeTypeHint = "" );
00210 
00212     Surface     getSurface();
00213 
00214  protected:
00215     void                allocateVisualContext();
00216  
00217     struct Obj : public MovieBase::Obj {
00218         virtual ~Obj();
00219         
00220         virtual void        releaseFrame(); 
00221         virtual void        newFrame( CVImageBufferRef cvImage );
00222     
00223         Surface             mSurface;
00224     };
00225     
00226     shared_ptr<Obj>             mObj;
00227     virtual MovieBase::Obj*     getObj() const { return mObj.get(); }
00228 
00229   public:
00231 
00232     typedef shared_ptr<Obj> MovieSurface::*unspecified_bool_type;
00233     operator unspecified_bool_type() const { return ( mObj.get() == 0 ) ? 0 : &MovieSurface::mObj; }
00234     void reset() { mObj.reset(); }
00236 };
00237 
00242 class MovieGl : public MovieBase {
00243   public:
00244     MovieGl() : MovieBase() {}
00245     MovieGl( const std::string &path );
00246     MovieGl( const class MovieLoader &loader );
00248 
00249     MovieGl( const void *data, size_t dataSize, const std::string &fileNameHint, const std::string &mimeTypeHint = "" );
00250     MovieGl( DataSourceRef dataSource, const std::string mimeTypeHint = "" );
00251 
00253     const gl::Texture   getTexture();
00254 
00255   protected:
00256     void                allocateVisualContext();
00257 
00258     struct Obj : public MovieBase::Obj {
00259         Obj();
00260         ~Obj();
00261 
00262         virtual void        releaseFrame();
00263         virtual void        newFrame( CVImageBufferRef cvImage );
00264         
00265         gl::Texture         mTexture;
00266 #if defined( CINDER_MSW )
00267         gl::TextureCache    mTextureCache;
00268 #endif
00269     };
00270     
00271     shared_ptr<Obj>             mObj;
00272     virtual MovieBase::Obj*     getObj() const { return mObj.get(); }
00273 
00274   public:
00276 
00277     typedef shared_ptr<Obj> MovieGl::*unspecified_bool_type;
00278     operator unspecified_bool_type() const { return ( mObj.get() == 0 ) ? 0 : &MovieGl::mObj; }
00279     void reset() { mObj.reset(); }
00281 };
00282 
00283 class MovieLoader {
00284   public:
00285     MovieLoader() {}
00286     MovieLoader( const Url &url );
00287 
00289     bool    checkLoaded() const;
00291     bool    checkPlayable() const;
00293     bool    checkPlaythroughOk() const;
00294 
00296     void    waitForLoaded() const;
00298     void    waitForPlayable() const;
00300     void    waitForPlaythroughOk() const;
00301 
00303     const Url&      getUrl() const { return mObj->mUrl; }
00304 
00306 	::Movie    getMovieHandle() const { return mObj->mMovie; }
00307 
00309 	::Movie transferMovieHandle() const { mObj->mOwnsMovie = false; return mObj->mMovie; }
00310     
00311   protected:
00312     void    updateLoadState() const;
00313  
00314     struct Obj {
00315         Obj( const Url &url );
00316         ~Obj();
00317         
00318         mutable bool    mOwnsMovie;
00319 		::Movie           mMovie;
00320         Url             mUrl;
00321         mutable bool    mLoaded, mPlayable, mPlaythroughOK;
00322     };
00323     
00324     shared_ptr<Obj>     mObj;
00325     
00326   public:
00328 
00329     typedef shared_ptr<Obj> MovieLoader::*unspecified_bool_type;
00330     operator unspecified_bool_type() const { return ( mObj.get() == 0 ) ? 0 : &MovieLoader::mObj; }
00331     void reset() { mObj.reset(); }
00333 };
00334 
00336 void startQuickTime();
00338 extern int32_t getQuickTimeVersion();
00340 extern std::string getQuickTimeVersionString();
00341 
00343 extern void quickTimeTask();
00344 
00345 class QuickTimeExc : public std::exception {
00346 };
00347 
00348 class QuickTimePathInvalidExc : public QuickTimeExc {
00349 };
00350 
00351 class QuickTimeFileInvalidExc : public QuickTimeExc {
00352 };
00353 
00354 class QuickTimeExcUrlInvalid : public QuickTimeExc {
00355 };
00356 
00357 class QuickTimeErrorLoadingExc : public QuickTimeExc {
00358 };
00359 
00360 class QuickTimeExcFft : public QuickTimeExc {
00361 };
00362 
00363 } /* namespace qtime */ } /* namespace cinder */
00364 #endif // ! defined( __LP64__ )