Cinder

  • Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • Examples
  • 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     Vec2i       getSize() const { return Vec2i( getWidth(), getHeight() ); }    
00076     float       getAspectRatio() const { return getObj()->mWidth / (float)getObj()->mHeight; }
00078     Area        getBounds() const { return Area( 0, 0, getWidth(), getHeight() ); }
00080     float       getPixelAspectRatio() const;
00082     float       getDuration() const { return getObj()->mDuration; }
00084     float       getFramerate() const;
00086     int32_t     getNumFrames() const;
00088     bool        hasAlpha() const;
00089 
00091     bool        hasVisuals() const;
00093     bool        hasAudio() const;
00094 
00096     bool        checkNewFrame();
00097 
00099     float       getCurrentTime() const;
00101     void        seekToTime( float seconds );
00103     void        seekToFrame( int frame );
00105     void        seekToStart();
00107     void        seekToEnd();
00109     void        setActiveSegment( float startTime, float duration );
00111     void        resetActiveSegment();
00112 
00114     void        setLoop( bool loop = true, bool palindrome = false );
00116     void        stepForward();
00118     void        stepBackward();
00120     void        setRate( float rate );
00121 
00123     void        setVolume( float volume );
00125     float       getVolume() const;
00126 
00128     void        setupMonoFft( uint32_t numBands );
00130     void        setupStereoFft( uint32_t numBands );
00132     void        setupMultiChannelFft( uint32_t numBands );  
00133     
00134     float*      getFftData() const;
00135     uint32_t    getNumFftBands() const;
00136     uint32_t    getNumFftChannels() const;  
00137 
00139     bool    isPlaying() const;
00141     bool    isDone() const;
00143     void    play();
00145     void    stop();
00146 
00148     void    setNewFrameCallback( void(*aNewFrameCallback)( long, void * ), void *aNewFrameCallbackRefcon );
00149 
00151 	::Movie    getMovieHandle() const { return getObj()->mMovie; }
00152 
00153  protected:
00154     MovieBase() {}
00155     void            init();
00156     void            updateFrame();
00157     void            updateLoadState();
00158 
00159     void            setupFft( FourCharCode code, uint32_t bandNum, uint8_t channelNum );
00160 
00161     static int32_t      countFrames( ::Movie theMovie );
00162     TimeValue           getStartTimeOfFirstSample() const;
00163 
00164  protected:
00165     void    initFromPath( const fs::path &filePath );
00166     void    initFromLoader( const class MovieLoader &loader );
00167     void    initFromMemory( const void *data, size_t dataSize, const std::string &fileNameHint, const std::string &mimeTypeHint );
00168     void    initFromDataSource( DataSourceRef dataSource, const std::string &mimeTypeHint );
00169  
00170     struct Obj {
00171         Obj();
00172         virtual ~Obj();
00173     
00174         void prepareForDestruction();
00175     
00176         void lock() { mMutex.lock(); }
00177         void unlock() { mMutex.unlock(); }
00178 
00179         // because the MovieBase* might change over time, but the MovieBase::Obj* will not, we need our callbacks to take an Obj* as a refcon
00180         // which in turn means this functionality must be in the Obj, not the MovieBase
00181         virtual void        releaseFrame() = 0;
00182         virtual void        newFrame( CVImageBufferRef cvImage ) = 0;
00183                 
00184         int32_t                     mWidth, mHeight;
00185         int32_t                     mFrameCount;
00186         float                       mDuration;
00187         bool                        mLoaded, mPlayable;
00188         bool                        mPlayingForward, mLoop, mPalindrome;
00189 
00190         QTAudioFrequencyLevels      *mFFTData;
00191         FourCharCode                mFFTFourCharCode;
00192         uint32_t                    mFFTNumBandLevels;
00193         uint32_t                    mFFTNumChannels;
00194         QTVisualContextRef          mVisualContext;
00195 		::Movie                       mMovie;
00196 
00197         void        (*mNewFrameCallback)(long timeValue, void *refcon);
00198         void        *mNewFrameCallbackRefcon;           
00199 
00200         std::mutex                  mMutex; 
00201         DataSourceRef               mDataSource; // sometimes used to retain a reference to a data source so that it doesn't go away before we do
00202     };
00203     
00204     virtual Obj*        getObj() const = 0;
00205 };
00206 
00207 class MovieSurface : public MovieBase {
00208  public:
00209     MovieSurface() : MovieBase() {}
00210     MovieSurface( const fs::path &path );
00211     MovieSurface( const class MovieLoader &loader );
00213 
00214     MovieSurface( const void *data, size_t dataSize, const std::string &fileNameHint, const std::string &mimeTypeHint = "" );
00215     MovieSurface( DataSourceRef dataSource, const std::string mimeTypeHint = "" );
00216 
00218     Surface     getSurface();
00219 
00220  protected:
00221     void                allocateVisualContext();
00222  
00223     struct Obj : public MovieBase::Obj {
00224         virtual ~Obj();
00225         
00226         virtual void        releaseFrame(); 
00227         virtual void        newFrame( CVImageBufferRef cvImage );
00228     
00229         Surface             mSurface;
00230     };
00231     
00232     std::shared_ptr<Obj>        mObj;
00233     virtual MovieBase::Obj*     getObj() const { return mObj.get(); }
00234 
00235   public:
00237 
00238     typedef std::shared_ptr<Obj> MovieSurface::*unspecified_bool_type;
00239     operator unspecified_bool_type() const { return ( mObj.get() == 0 ) ? 0 : &MovieSurface::mObj; }
00240     void reset() { mObj.reset(); }
00242 };
00243 
00248 class MovieGl : public MovieBase {
00249   public:
00250     MovieGl() : MovieBase() {}
00251     MovieGl( const fs::path &path );
00252     MovieGl( const class MovieLoader &loader );
00254 
00255     MovieGl( const void *data, size_t dataSize, const std::string &fileNameHint, const std::string &mimeTypeHint = "" );
00256     MovieGl( DataSourceRef dataSource, const std::string mimeTypeHint = "" );
00257 
00259     const gl::Texture   getTexture();
00260 
00261   protected:
00262     void                allocateVisualContext();
00263 
00264     struct Obj : public MovieBase::Obj {
00265         Obj();
00266         ~Obj();
00267 
00268         virtual void        releaseFrame();
00269         virtual void        newFrame( CVImageBufferRef cvImage );
00270         
00271         gl::Texture         mTexture;
00272 #if defined( CINDER_MSW )
00273         gl::TextureCache    mTextureCache;
00274 #endif
00275     };
00276     
00277     std::shared_ptr<Obj>                mObj;
00278     virtual MovieBase::Obj*     getObj() const { return mObj.get(); }
00279 
00280   public:
00282 
00283     typedef std::shared_ptr<Obj> MovieGl::*unspecified_bool_type;
00284     operator unspecified_bool_type() const { return ( mObj.get() == 0 ) ? 0 : &MovieGl::mObj; }
00285     void reset() { mObj.reset(); }
00287 };
00288 
00289 class MovieLoader {
00290   public:
00291     MovieLoader() {}
00292     MovieLoader( const Url &url );
00293 
00295     bool    checkLoaded() const;
00297     bool    checkPlayable() const;
00299     bool    checkPlaythroughOk() const;
00300 
00302     void    waitForLoaded() const;
00304     void    waitForPlayable() const;
00306     void    waitForPlaythroughOk() const;
00307 
00309     const Url&      getUrl() const { return mObj->mUrl; }
00310 
00312 	::Movie    getMovieHandle() const { return mObj->mMovie; }
00313 
00315 	::Movie transferMovieHandle() const { mObj->mOwnsMovie = false; return mObj->mMovie; }
00316     
00317   protected:
00318     void    updateLoadState() const;
00319  
00320     struct Obj {
00321         Obj( const Url &url );
00322         ~Obj();
00323         
00324         mutable bool    mOwnsMovie;
00325 		::Movie           mMovie;
00326         Url             mUrl;
00327         mutable bool    mLoaded, mPlayable, mPlaythroughOK;
00328     };
00329     
00330     std::shared_ptr<Obj>        mObj;
00331     
00332   public:
00334 
00335     typedef std::shared_ptr<Obj> MovieLoader::*unspecified_bool_type;
00336     operator unspecified_bool_type() const { return ( mObj.get() == 0 ) ? 0 : &MovieLoader::mObj; }
00337     void reset() { mObj.reset(); }
00339 };
00340 
00341 inline int32_t floatToFixed( float fl ) { return ((int32_t)((float)(fl) * ((int32_t) 0x00010000L))); }
00342 
00344 void startQuickTime();
00346 extern int32_t getQuickTimeVersion();
00348 extern std::string getQuickTimeVersionString();
00349 
00351 extern void quickTimeTask();
00352 
00353 class QuickTimeExc : public std::exception {
00354 };
00355 
00356 class QuickTimePathInvalidExc : public QuickTimeExc {
00357 };
00358 
00359 class QuickTimeFileInvalidExc : public QuickTimeExc {
00360 };
00361 
00362 class QuickTimeExcUrlInvalid : public QuickTimeExc {
00363 };
00364 
00365 class QuickTimeErrorLoadingExc : public QuickTimeExc {
00366 };
00367 
00368 class QuickTimeExcFft : public QuickTimeExc {
00369 };
00370 
00371 } /* namespace qtime */ } /* namespace cinder */
00372 #endif // ! defined( __LP64__ )