#if TYPE_LONGLONG && TARGET_OS_WIN32 && !defined(__MINGW32__) #define S64Max() 9223372036854775807i64..and...#if TYPE_LONGLONG && TARGET_OS_WIN32 && !defined(__MINGW32__) #define U64Max() 0xffffffffffffffffui64
#pragma once#ifndef __QTMOVIE_H#define __QTMOVIE_H#include <stdio.h>#include <stdbool.h>#if defined (_WIN32)#include <brl.mod/blitz.mod/blitz.h>#include "QuickTimeSDK/CIncludes/QTML.h"#include "QuickTimeSDK/CIncludes/Movies.h"const int kNativeEndianPixMap = 0;#endif#if defined (__APPLE__)#include <brl.mod/blitz.mod/blitz.h>#include <QuickTime/Quicktime.h>#include <QuickTime/Movies.h>#endif/*stop using gworlds:CGBitmapContext around your data buffer, and then call CGBitmapContextCreateImage() to obtain a CGImageRef for just-in- time drawing of that context*/class bmx_qt{public: Movie theMovie; GWorldPtr movieGWorld ; Rect movieRect ; FSSpec m_fileSpec; OSType m_pixelFormat; short resRefNum; //theFile Rect bufferBounds; MovieController theController; short resID; OSErr err; //CGContextRef ccr; //CGColorSpaceRef colorspace; CTabHandle cTable; GDHandle aGD; short monitorPixelDepth; TimeValue currentTime; bmx_qt() { cTable=NULL; aGD=0; theController=NULL; monitorPixelDepth=24; }; ~bmx_qt() { delete this; }};/*typedef long TimeValue;typedef long TimeScale;typedef wide CompTimeValue;typedef SInt64 TimeValue64;struct TimeRecord { CompTimeValue value; // units (duration or absolute) (comptimevalue = wide) TimeScale scale; // units per second TimeBase base; // refernce to the time base };#if TARGET_RT_BIG_ENDIANstruct wide { SInt32 hi; UInt32 lo;};/*/* SET EXTERNS */ extern "C" { bmx_qt * bmx_CreateQT(); int bmx_NewMovieFromFile( bmx_qt * qtclass, char * filename); int bmx_NewMovieFromURL( bmx_qt * qtclass, char * filename); int bmx_NewMovieFromFileRef( bmx_qt * qtclass, int flag); void bmx_DisposeMovie (bmx_qt * qtclass) ; int bmx_OpenMovieFile( bmx_qt * qtclass, SInt8 permission); int bmx_CloseMovieFile(bmx_qt * qtclass); int bmx_NativePathNameToFSSpec(bmx_qt * qtclass, char * filename, int flag); int bmx_FSMakeFSSpec(bmx_qt * qtclass, const unsigned char * filename); int bmx_GetMovieLoadState(bmx_qt * qtclass); void bmx_GetMovieBox( bmx_qt * qtclass); int bmx_GetMovieWidth (bmx_qt * qtclass); int bmx_GetMovieHeight (bmx_qt * qtclass); int bmx_GetMovieTrackCount(bmx_qt * qtclass); void bmx_SetMoviePlayHints(bmx_qt * qtclass , int hint1, int hint2) ; int bmx_NewMovieController( bmx_qt * qtclass, long flags); void bmx_DisposeMovieController (bmx_qt * qtclass); void bmx_SetMovieActive(bmx_qt * qtclass , bool flag); void bmx_StartMovie(bmx_qt * qtclass ); int bmx_UpdateMovie(bmx_qt * qtclass ); void bmx_StopMovie(bmx_qt * qtclass ); int bmx_IsMovieDone(bmx_qt * qtclass ); long bmx_GetMovieNextInterestingTime(bmx_qt * qtclass, int flags); void bmx_SetMovieTimeValue(bmx_qt * qtclass, long newtime); void bmx_GoToBeginningOfMovie(bmx_qt * qtclass ); int bmx_GetMovieDuration(bmx_qt * qtclass); long bmx_GetMovieTime(bmx_qt * qtclass); long bmx_GetMovieTimeScale(bmx_qt * qtclass); void bmx_SetMovieVolume ( bmx_qt * qtclass, float volume); void bmx_MoviesTask(bmx_qt * qtclass, int flags); int bmx_NewGWorld(bmx_qt * qtclass, int w, int h, long flags); int bmx_QTNewGWorldFromPtr( bmx_qt * qtclass,int pixelformat, int w, int h, char *buffer, long rowbytes, GWorldFlags flags); void bmx_SetGWorld(bmx_qt * qtclass); void bmx_SetMovieGWorld(bmx_qt * qtclass); void bmx_DisposeGWorld(bmx_qt * qtclass); int bmx_GetGWorldDevice( bmx_qt * qtclass); int bmx_LockPixels (bmx_qt * qtclass); void bmx_UnlockPixels (bmx_qt * qtclass); void bmx_PreRollMovie( bmx_qt * qtclass , TimeValue time);}/*DEFINE EXTERN FUNCTIONS */bmx_qt * bmx_CreateQT() { return new bmx_qt();}// create a data reference from a full path CFStringMovie GetMovieFromFileString(char * filename, OSErr err, short * id){ Movie theMovie = 0; Handle dataRef = NULL; OSType dataRefType; //OSErr err; CFStringRef inPath = CFStringCreateWithCString (0, filename, 0); // create the data reference err = QTNewDataReferenceFromFullPathCFString(inPath, 0, 0, &dataRef, &dataRefType); //kQTNativeDefaultPathStyle, 0, &dataRef, &dataRefType); if (NULL != dataRef) { // get a movie //err = NewMovieFromDataRef(&theMovie, // (allowUserInteraction ? 0 : // newMovieDontAskUnresolvedDataRefs), // id, dataRef, dataRefType); err = NewMovieFromDataRef(&theMovie, newMovieActive|newMovieDontAskUnresolvedDataRefs, id, dataRef, dataRefType); // remember to dispose of the data reference handle DisposeHandle(dataRef); } return theMovie;}Movie GetMovieFromURLString(char * filename, OSErr err, short * id){ Movie theMovie = 0; Handle dataRef = NULL; OSType dataRefType; //OSErr err; CFStringRef url = CFStringCreateWithCString (0, filename, 0); CFURLRef inPath = CFURLCreateWithString(NULL, url, NULL); // create the data reference //err = QTNewDataReferenceFromFullPathCFString(inPath, kQTNativeDefaultPathStyle, 0, &dataRef, &dataRefType); err = QTNewDataReferenceFromCFURL(inPath, 0, &dataRef, &dataRefType); if (NULL != dataRef) { // get a movie //err = NewMovieFromDataRef(&theMovie, // (allowUserInteraction ? 0 : // newMovieDontAskUnresolvedDataRefs|newMovieAsyncOK), // id, dataRef, dataRefType); err = NewMovieFromDataRef(&theMovie, newMovieActive|newMovieDontAskUnresolvedDataRefs|newMovieAsyncOK, 0, dataRef, dataRefType); //used to have id there where 0 is // remember to dispose of the data reference handle DisposeHandle(dataRef); } return theMovie;}int bmx_NewMovieFromURL( bmx_qt * qtclass, char * filename) { qtclass->theMovie = GetMovieFromURLString(filename, qtclass->err, &qtclass->resID); if (!qtclass->theMovie) return qtclass->err; return 0;}int bmx_NewMovieFromFile( bmx_qt * qtclass, char * filename) { qtclass->theMovie = GetMovieFromFileString(filename, qtclass->err, &qtclass->resID); if (!qtclass->theMovie) return qtclass->err; return 0;}// NewMovieFromFile (&theMovie, theFile, nil, nil, newMovieActive, nil); // Get movie from fileint bmx_NewMovieFromFileRef( bmx_qt * qtclass, int flag) { return NewMovieFromFile( &qtclass->theMovie, qtclass->resRefNum, &qtclass->resID,0, flag, 0);}void bmx_DisposeMovie (bmx_qt * qtclass) { DisposeMovie (qtclass->theMovie);}int bmx_OpenMovieFile( bmx_qt * qtclass, SInt8 permission) { return OpenMovieFile( &qtclass->m_fileSpec, &qtclass->resRefNum, permission);}int bmx_CloseMovieFile( bmx_qt * qtclass) { return CloseMovieFile( qtclass->resRefNum);}int bmx_NativePathNameToFSSpec(bmx_qt * qtclass, char * filename, int flag) { #ifdef _WIN32 return NativePathNameToFSSpec(filename, &qtclass->m_fileSpec, flag);#endif }int bmx_FSMakeFSSpec(bmx_qt * qtclass, const unsigned char * filename) { //being depricated by QT? //c2pstr (filename); return FSMakeFSSpec(0, 0L, filename, &qtclass->m_fileSpec);}int bmx_GetMovieLoadState(bmx_qt * qtclass) { return GetMovieLoadState(qtclass->theMovie);}int bmx_NewGWorld(bmx_qt * qtclass, int w, int h, long flags) { qtclass->bufferBounds.left =0; qtclass->bufferBounds.top =0; qtclass->bufferBounds.right =w; qtclass->bufferBounds.bottom =h; return NewGWorld(&qtclass->movieGWorld, qtclass->monitorPixelDepth, &qtclass->bufferBounds, qtclass->cTable, qtclass->aGD, flags);}//QTNewGWorldFromPtr( GWorldPtr *gw, OSType pixelFormat, const Rect *boundsRect, CTabHandle cTable, GDHandle aGDevice, GWorldFlags flags, void *baseAddr, long rowBytes ); int bmx_QTNewGWorldFromPtr( bmx_qt * qtclass,int pixelformat, int w, int h, char *buffer, long rowbytes, GWorldFlags flags) { qtclass->bufferBounds.left =0; qtclass->bufferBounds.top =0; qtclass->bufferBounds.right =w; qtclass->bufferBounds.bottom =h; return QTNewGWorldFromPtr(&qtclass->movieGWorld, pixelformat, &qtclass->bufferBounds, qtclass->cTable, qtclass->aGD, flags|kNativeEndianPixMap , (char *)buffer, rowbytes);}void bmx_SetGWorld(bmx_qt * qtclass) { SetGWorld(qtclass->movieGWorld, NULL); //GetGWorldDevice( qtclass->movieGWorld));}void bmx_SetMovieGWorld(bmx_qt * qtclass) { SetMovieGWorld(qtclass->theMovie, qtclass->movieGWorld, NULL); //GetGWorldDevice( qtclass->movieGWorld));}int bmx_GetGWorldDevice( bmx_qt * qtclass) { //GDevice aGD; qtclass->aGD = GetGWorldDevice( qtclass->movieGWorld); if(qtclass->aGD) return 0; return -99;}void bmx_DisposeGWorld(bmx_qt * qtclass) { DisposeGWorld(qtclass->movieGWorld);}/* doesn't exist for mswinint bmx_CGBitmapContextCreate (bmx_qt * qtclass, void * buffer, int w, int h, int bitsPerComponent, int bytesPerRow, int flags) { //CGContextRef ccr; //CGBitmapContextCreate (void *data,size_t width,size_t height,size_t bitsPerComponent,size_t bytesPerRow,CGColorSpaceRef colorspace,CGBitmapInfo bitmapInfo); qtclass->ccr = CGBitmapContextCreate (void *buffer,w,h,bitsPerComponent,bytesPerRow,qtclass->colorspace,flags | kCGImageAlphaLast); if (ccr) return 0; return -99;}*//*QTPixelBufferContextCreate ( CFAllocatorRef allocator, CFDictionaryRef attributes, QTVisualContextRef *newPixelBufferContext);*/int bmx_LockPixels (bmx_qt * qtclass) {#ifdef _WIN32 return LockPixels (qtclass->movieGWorld->portPixMap);#endif}void bmx_UnlockPixels (bmx_qt * qtclass) {#ifdef _WIN32 UnlockPixels (qtclass->movieGWorld->portPixMap);#endif}int bmx_NewMovieController( bmx_qt * qtclass, long flags) { ComponentInstance x = NewMovieController( qtclass->theMovie, &qtclass->movieRect, flags); qtclass->theController = x; if(x) return 0; return -99;}void bmx_DisposeMovieController (bmx_qt * qtclass) { // Close movie controller, if any DisposeMovieController(qtclass->theController);}void bmx_MoviesTask(bmx_qt * qtclass, int flags) { if (qtclass->theController) MCIdle(qtclass->theController); MoviesTask(qtclass->theMovie, flags); }void bmx_SetMovieActive(bmx_qt * qtclass , bool flag) { return SetMovieActive(qtclass->theMovie , flag);}void bmx_StartMovie(bmx_qt * qtclass ) { StartMovie(qtclass->theMovie);}int bmx_UpdateMovie(bmx_qt * qtclass ) { return UpdateMovie(qtclass->theMovie);}void bmx_StopMovie(bmx_qt * qtclass ) { StopMovie(qtclass->theMovie);}void bmx_GoToBeginningOfMovie(bmx_qt * qtclass ) { GoToBeginningOfMovie(qtclass->theMovie );}int bmx_IsMovieDone(bmx_qt * qtclass ) { return IsMovieDone(qtclass->theMovie );}long bmx_GetMovieNextInterestingTime(bmx_qt * qtclass, int flags) { //OSType MovieMediaType TimeValue gNextTime; GetMovieNextInterestingTime(qtclass->theMovie, flags, 0, NULL, GetMovieTime( qtclass->theMovie, 0), 0, &gNextTime, NULL); return (long) gNextTime;} void bmx_SetMovieTimeValue(bmx_qt * qtclass, long newtime) { SetMovieTimeValue(qtclass->theMovie, (TimeValue) newtime);}void bmx_SetMovieVolume ( bmx_qt * qtclass, float volume) { SetMovieVolume ( qtclass->theMovie, volume );}void bmx_GetMovieBox( bmx_qt * qtclass) { GetMovieBox( qtclass->theMovie, &qtclass->movieRect);}int bmx_GetMovieWidth (bmx_qt * qtclass) { return qtclass->movieRect.right - qtclass->movieRect.left ;}int bmx_GetMovieHeight (bmx_qt * qtclass) { return qtclass->movieRect.bottom - qtclass->movieRect.top ;}int bmx_GetMovieDuration(bmx_qt * qtclass) { return (int) GetMovieDuration(qtclass->theMovie);}long bmx_GetMovieTime(bmx_qt * qtclass) { TimeValue tv; tv = GetMovieTime( qtclass->theMovie, 0); //&tm qtclass->currentTime =tv; return tv;}long bmx_GetMovieTimeScale(bmx_qt * qtclass) { TimeValue tv; return GetMovieTimeScale( qtclass->theMovie);}int bmx_GetMovieTrackCount(bmx_qt * qtclass) { return GetMovieTrackCount(qtclass->theMovie );}void bmx_SetMoviePlayHints(bmx_qt * qtclass , int hint1, int hint2) { SetMoviePlayHints( qtclass->theMovie , hint1, hint2);}void bmx_PreRollMovie( bmx_qt * qtclass , TimeValue time) { PrerollMovie( qtclass->theMovie, time, GetMoviePreferredRate(qtclass->theMovie) );}/*unsigned DLL_CALLCONV bmx_NewMovieFromFile( int &theMovie, int filenum, int &a, int &b, int flag, int &c) { return NewMovieFromFile( *theMovie, filenum, *a, *b, flag, *c);}*/#endif/* */
ModuleInfo "BCC_OPTS: -O2"
'''' sample test code for Quicktime in BMax'' MSWin & MacOSX'' by AdamRedwoods 2011SuperStrictFramework brl.GLMax2DImport addons.quicktimeImport brl.standardioImport brl.filesystemImport brl.pixmapSetGraphicsDriver GLMax2DDriver()Local gd:TGraphicsDriver = GetGraphicsDriver()Graphics(900,600,0,60,GRAPHICS_BACKBUFFER)Local curdir:String = CurrentDir()'Local filename:String = curdir+"/ironman2_480p.mov"Local filename:String = "http://trailers.apple.com/movies/wb/thedarkknightrises/darkknightrises-tsr1_h480p.mov"'Local filename:String = "http://trailers.apple.com/movies/wb/harrypotterandthedeathlyhallowspart2/hp7part2-tlr2_h480p.mov"'Local mypix:TPixmap = CreatePixmap(900,600,PF_RGB888 ,3)Local myimage:TImage = CreateImage(900,600)Local myQT:TQuickTime = New TQuickTime'myQT.debug = True'If (Not myQT.LoadMovieToPixmap(filename, mypix))If (Not myQT.LoadMovieToImage(filename, myimage )) Print "error" EndEndIfPrint "width: "+myQT.GetMovieWidth()Print "height: "+myQT.GetMovieHeight()Print "duration: "+myQT.GetMovieDuration()Print "tracks: "+myQT.GetMovieTracks()myQT.StartMovie()Local j:FloatLocal i:Int=0Local stopstate:Int=0'SetBlend solidblendRepeat SetClsColor 0,0,0 Cls SetColor 255,255,255 myQT.UpdateMovie() 'SetScale 2.0,2.0 ''now allows scaling, coloring, etc myQT.DrawMovieImage (myimage, 0,0) j = myQT.GetMovieTimeSecs() DrawText ("s:"+j+" "+" t:"+myQT.GetMovieTime(), 1,1) If myQT.IsMovieDone() Then DrawText ("done.",1,10) Flip PollSystem() Local xs:Int = MouseXSpeed() If(AppTerminate()) myQT.StopMovie() myQT.CloseMovie() ''save memory End Else If(MouseDown(1)) 'Print MouseXSpeed() If(Abs(xs)>2) myQT.StopMovie() myQT.SetMovieTime(myQT.GetMovieTime() + xs*100) ''in milliseconds myQT.UpdateMovie() stopstate = True Else If(stopstate And MouseHit(1)) myQT.StartMovie() stopstate =0 Else If MouseHit(1) myQT.StopMovie() stopstate=1 EndIf EndIfForeverEnd