//--------------------------------------------------------------
bool createMovieFromURL(string urlIn,  Movie &movie) {
    char * url = (char *)urlIn.c_str();
    Handle urlDataRef;

    OSErr err;

    urlDataRef = NewHandle(strlen(url) + 1);
    if ( ( err = MemError()) != noErr) {
        ofLog(OF_LOG_ERROR,"createMovieFromURL: error creating url handle");
        return false;
    }

    BlockMoveData(url, *urlDataRef, strlen(url) + 1);

    err = NewMovieFromDataRef(&movie, newMovieActive,nil, urlDataRef, URLDataHandlerSubType);
    DisposeHandle(urlDataRef);

    if(err != noErr) {
        ofLog(OF_LOG_ERROR,"createMovieFromURL: error loading url");
        return false;
    } else {
        return true;
    }

    return false;
}
예제 #2
0
// Refer to http://developer.apple.com/technotes/tn/tn1195.html Technical Note TN1195 "Tagging Handle and Pointer Data References in QuickTime"
::Movie openMovieFromMemory( const void *data, size_t dataSize, const string &fileNameHint, const string &mimeTypeHint )
{
	Handle dataRefHandle = createPointerDataRefWithExtensions( const_cast<void*>( data ), dataSize, fileNameHint, mimeTypeHint );

	::Movie result;
/*	QTNewMoviePropertyElement movieProps[10];
	ItemCount moviePropCount = 0;
	DataReferenceRecord dataRef = {0};
	
	moviePropCount = openMovieBaseProperties( movieProps );

	// Store the movie properties in the array
	movieProps[moviePropCount].propClass = kQTPropertyClass_DataLocation;
	movieProps[moviePropCount].propID = kQTDataLocationPropertyID_QTDataHandler;
	movieProps[moviePropCount].propValueSize = sizeof(aQTDataRef);
	movieProps[moviePropCount].propValueAddress = (void*)&dataRefHandle;
	movieProps[moviePropCount].propStatus = 0;
	moviePropCount++;

	OSErr err;
	if( (err = NewMovieFromProperties(moviePropCount, movieProps, 0, NULL, &result) ) != noErr ) {
		throw QuickTimeErrorLoadingExc();
	}*/

	short myResID = 0;
	OSErr err = NewMovieFromDataRef( &result, newMovieActive | newMovieAsyncOK, &myResID, dataRefHandle, 'ptr ' );
	if( err )
		throw QuickTimeErrorLoadingExc();
	
	return result;
}
//--------------------------------------------------------------
bool createMovieFromURL(string urlIn,  Movie &movie){
	char * url = (char *)urlIn.c_str();
	Handle urlDataRef;

	OSErr err;

	urlDataRef = NewHandle(strlen(url) + 1);
	if ( ( err = MemError()) != noErr){
		ofLogError("ofQuickTimePlayer") << "createMovieFromURL(): couldn't create url handle from \"" << urlIn << "\": OSErr " << err;
		return false;
	}

	BlockMoveData(url, *urlDataRef, strlen(url) + 1);

	err = NewMovieFromDataRef(&movie, newMovieActive,nil, urlDataRef, URLDataHandlerSubType);
	DisposeHandle(urlDataRef);

	if(err != noErr){
		ofLogError("ofQuickTimePlayer") << "createMovieFromURL(): couldn't load url \"" << urlIn << "\": OSErr " << err;
		return false;
	}else{
		return true;
	}

	return false;
}
예제 #4
0
Movie QTDR_GetMovieFromURL (char *theURL)
{
	Movie		myMovie = NULL;
	Handle		myDataRef = NULL;
	
	myDataRef = QTDR_MakeURLDataRef(theURL);
	if (myDataRef != NULL) {
		NewMovieFromDataRef(&myMovie, newMovieActive, NULL, myDataRef, URLDataHandlerSubType);
		DisposeHandle(myDataRef);
	}
	
	return(myMovie);
}
예제 #5
0
Movie QTDR_GetMovieFromResource (FSSpecPtr theFile, OSType theResType, SInt16 theResID)
{
	Movie		myMovie = NULL;
	Handle		myDataRef = NULL;
					
	myDataRef = QTDR_MakeResourceDataRef(theFile, theResType, theResID);
	if (myDataRef != NULL) {
		NewMovieFromDataRef(&myMovie, newMovieActive, NULL, myDataRef, ResourceDataHandlerSubType);
		DisposeHandle(myDataRef);
	}
		
	return(myMovie);
}
예제 #6
0
Movie QTDR_GetMovieFromHandle (Handle theHandle)
{
	Movie		myMovie = NULL;
	Handle		myDataRef = NULL;
					
	myDataRef = QTDR_MakeHandleDataRef(theHandle);
	if (myDataRef != NULL) {
		NewMovieFromDataRef(&myMovie, newMovieActive, NULL, myDataRef, HandleDataHandlerSubType);
		DisposeHandle(myDataRef);
	}
		
	return(myMovie);
}
예제 #7
0
Movie QTDR_GetMovieFromFile (FSSpecPtr theFile)
{
	Movie		myMovie = NULL;
	Handle		myDataRef = NULL;
					
	myDataRef = QTDR_MakeFileDataRef(theFile);
	if (myDataRef != NULL) {
		NewMovieFromDataRef(&myMovie, newMovieActive, NULL, myDataRef, rAliasType);
		DisposeHandle(myDataRef);
	}
		
	return(myMovie);
}
예제 #8
0
quicktime_player* quicktime_player::open( const char *path ) {
    OSErr err;
    OSType dataRefType;
    Handle dataRef = NULL;
    short resID = 0;
    impl *m = new impl;

    std::string pathStd = path;
    #ifdef WIN32
    for (std::string::iterator p = pathStd.begin(); p != pathStd.end(); ++p) if (*p == '/') *p = '\\';
    #endif
    
    CFStringRef cfPath = CFStringCreateWithCString(NULL, pathStd.c_str(), kCFStringEncodingISOLatin1);
    err = QTNewDataReferenceFromFullPathCFString(cfPath, (QTPathStyle)kQTNativeDefaultPathStyle, 0, &dataRef, &dataRefType);
    CFRelease(cfPath);
    if (err != noErr) {
        delete m;
        return NULL;
    }

    err = NewMovieFromDataRef(&m->movie, newMovieActive, &resID, dataRef, dataRefType);
    DisposeHandle(dataRef);
    if (err != noErr) {
        delete m;
        return NULL;
    }   

    m->track = GetMovieIndTrackType(m->movie, 1, VisualMediaCharacteristic, movieTrackCharacteristic);
    m->media = GetTrackMedia(m->track);

    Rect bounds;
    GetMovieBox(m->movie, &bounds);
    m->width = bounds.right;
    m->height = bounds.bottom;

    m->buffer = (unsigned char*)malloc(4 * m->width * m->height);
    err = QTNewGWorldFromPtr(&m->gworld, k32BGRAPixelFormat, &bounds, NULL, NULL, 0, m->buffer, 4 * m->width);
    if (err != noErr) {
        delete m;
        return NULL;
    }
    SetMovieGWorld(m->movie, m->gworld, NULL);

    return new quicktime_player(m);
}
예제 #9
0
std::unique_ptr<ImportFileHandle> QTImportPlugin::Open(const wxString & Filename)
{
   OSErr err;
   FSRef inRef;
   Movie theMovie = NULL;
   Handle dataRef = NULL;
   OSType dataRefType = 0;
   short resID = 0;

#if defined(__WXMAC__)
   err = wxMacPathToFSRef(Filename, &inRef);
#else
   // LLL:  This will not work for pathnames with Unicode characters...find
   //       another method.
   err = FSPathMakeRef((UInt8 *)OSFILENAME(Filename), &inRef, NULL);
#endif

   if (err != noErr) {
      return nullptr;
   }

   err = QTNewDataReferenceFromFSRef(&inRef, 0, &dataRef, &dataRefType);
   if (err != noErr) {
      return nullptr;
   }

   // instantiate the movie
   err = NewMovieFromDataRef(&theMovie,
                             newMovieActive | newMovieDontAskUnresolvedDataRefs,
                             &resID,
                             dataRef,
                             dataRefType);
   DisposeHandle(dataRef);
   if (err != noErr) {
      return nullptr;
   }

   return std::make_unique<QTImportFileHandle>(Filename, theMovie);
}
예제 #10
0
bool wxSound::DoPlay(unsigned flags) const
{
    Stop();

    Movie movie;

    switch(m_type)
    {
    case wxSound_MEMORY:
        {
            if (!wxInitQT())
                return false;
            Handle myHandle, dataRef = nil;
            MovieImportComponent miComponent;
            Track targetTrack = nil;
            TimeValue addedDuration = 0;
            long outFlags = 0;
            OSErr err;
            ComponentResult result;

            myHandle = NewHandleClear((Size)m_waveLength);

            BlockMove(m_hSnd, *myHandle, m_waveLength);

            err = PtrToHand(&myHandle, &dataRef, sizeof(Handle));

            if (memcmp(&m_hSnd[8], "WAVE", 4) == 0)
                miComponent = OpenDefaultComponent(MovieImportType, kQTFileTypeWave);
            else if (memcmp(&m_hSnd[8], "AIFF", 4) == 0)
                miComponent = OpenDefaultComponent(MovieImportType, kQTFileTypeAIFF);
            else if (memcmp(&m_hSnd[8], "AIFC", 4) == 0)
                miComponent = OpenDefaultComponent(MovieImportType, kQTFileTypeAIFC);
            else
            {
                wxLogSysError(wxT("wxSound - Location in memory does not contain valid data"));
                return false;
            }

            movie = NewMovie(0);

            result = MovieImportDataRef(miComponent,                dataRef,
                                        HandleDataHandlerSubType,   movie,
                                        nil,                        &targetTrack,
                                        nil,                        &addedDuration,
                                        movieImportCreateTrack,     &outFlags);

            if (result != noErr)
            {
                wxLogSysError(wxString::Format(wxT("Couldn't import movie data\nError:%i"), (int)result));
            }

            SetMovieVolume(movie, kFullVolume);
            GoToBeginningOfMovie(movie);

            DisposeHandle(myHandle);
        }
        break;
    case wxSound_RESOURCE:
        {
            SoundComponentData data;
            unsigned long numframes, offset;

            ParseSndHeader((SndListHandle)m_hSnd, &data, &numframes, &offset);
            //m_waveLength = numFrames * data.numChannels;

            SndChannelPtr pSndChannel;
            SndNewChannel(&pSndChannel, sampledSynth,
                initNoInterp
                + (data.numChannels == 1 ? initMono : initStereo), NULL);

            if(SndPlay(pSndChannel, (SndListHandle) m_hSnd, flags & wxSOUND_ASYNC ? 1 : 0) != noErr)
                return false;

            if (flags & wxSOUND_ASYNC)
            {
                lastSoundTimer = ((wxSMTimer*&)m_pTimer)
                    = new wxSMTimer(pSndChannel, m_hSnd, flags & wxSOUND_LOOP ? 1 : 0,
                                    &lastSoundIsPlaying);
                lastSoundIsPlaying = true;

                ((wxTimer*)m_pTimer)->Start(MOVIE_DELAY, wxTIMER_CONTINUOUS);
            }
            else
                SndDisposeChannel(pSndChannel, TRUE);

            return true;
        }
        break;
    case wxSound_FILE:
        {
            if (!wxInitQT())
                return false;

            OSErr err = noErr ;

            Handle dataRef = NULL;
            OSType dataRefType;

            err = QTNewDataReferenceFromFullPathCFString(wxMacCFStringHolder(m_sndname,wxLocale::GetSystemEncoding()),
                (UInt32)kQTNativeDefaultPathStyle, 0, &dataRef, &dataRefType);

            wxASSERT(err == noErr);

            if (NULL != dataRef || err != noErr)
            {
                err = NewMovieFromDataRef( &movie, newMovieDontAskUnresolvedDataRefs , NULL, dataRef, dataRefType );
                wxASSERT(err == noErr);
                DisposeHandle(dataRef);
            }

            if (err != noErr)
            {
                wxLogSysError(
                    wxString::Format(wxT("wxSound - Could not open file: %s\nError:%i"), m_sndname.c_str(), err )
                    );
                return false;
            }
        }
        break;
    default:
        return false;
    }//end switch(m_type)

    //Start the movie!
    StartMovie(movie);

    if (flags & wxSOUND_ASYNC)
    {
        //Start timer and play movie asyncronously
        lastSoundTimer = ((wxQTTimer*&)m_pTimer) =
            new wxQTTimer(movie, flags & wxSOUND_LOOP ? 1 : 0,
                          &lastSoundIsPlaying);
        lastSoundIsPlaying = true;
        ((wxQTTimer*)m_pTimer)->Start(MOVIE_DELAY, wxTIMER_CONTINUOUS);
    }
    else
    {
        wxASSERT_MSG(!(flags & wxSOUND_LOOP), wxT("Can't loop and play syncronously at the same time"));

        //Play movie until it ends, then exit
        //Note that due to quicktime caching this may not always
        //work 100% correctly
        while (!IsMovieDone(movie))
            MoviesTask(movie, 1);

        DisposeMovie(movie);
    }

    return true;
}
예제 #11
0
int convertToMP4PathThrough(CFStringRef inFile, CFStringRef outFile)
{
	OSStatus error;
	MovieExportComponent movieExporter = NULL;
	Handle inDataRef=0, outDataRef=0;
	OSType inDataRefType, outDataRefType;
	short inResID = 0;
	Movie theMovie=0;
	int ret = -1;

	error = OpenADefaultComponent(MovieExportType, kQTFileTypeMP4, &movieExporter);
	if(error) {
		fprintf(stderr,"OpenADefaultComponent error: cannot find the QuickTime conponent\n");
		goto last;
	}
	error = QTNewDataReferenceFromFullPathCFString(inFile, kQTNativeDefaultPathStyle, 0, &inDataRef, &inDataRefType);
	if(error) {
		fprintf(stderr,"QTNewDataReferenceFromFullPathCFString error: input file path is invalid\n");
		goto last;
	}
	error = QTNewDataReferenceFromFullPathCFString(outFile, kQTNativeDefaultPathStyle, 0, &outDataRef, &outDataRefType);
	if(error) {
		fprintf(stderr,"QTNewDataReferenceFromFullPathCFString error: output file path is invalid\n");
		goto last;
	}
	error = NewMovieFromDataRef(&theMovie, newMovieActive, &inResID, inDataRef, inDataRefType);
	if(error) {
		fprintf(stderr,"NewMovieFromDataRef error: cannot open the input file\n");
		goto last;
	}

	Track theTrack = getSoundTrack(theMovie);
	Media theMedia = GetTrackMedia(theTrack);
	DeleteTrackSegment(theTrack, 0, GetTrackDuration(theTrack));
	SetMovieTimeScale(theMovie, GetMediaTimeScale(theMedia));
	InsertMediaIntoTrack(theTrack, 0, 0, GetMediaDuration(theMedia), fixed1);

	Boolean useHighResolutionAudio = true;
	QTSetComponentProperty(
		movieExporter,
		kQTPropertyClass_MovieExporter,
		kQTMovieExporterPropertyID_EnableHighResolutionAudioFeatures,
		sizeof(Boolean),
		&useHighResolutionAudio
	);

	UInt32 ftyp = 'mp42';
	QTSetComponentProperty(
		movieExporter,
		kQTPropertyClass_MovieExporter,
		'ftyp',
		4,
		&ftyp
	);

	QTAtomContainer ac;
	MovieExportGetSettingsAsAtomContainer(movieExporter, &ac);
	QTAtom ensoAtom = QTFindChildByID(ac, kParentAtomIsContainer, kQTSettingsMovieExportEnableSound, 1, NULL);
	if(ensoAtom) {
		long size, *data;
		QTGetAtomDataPtr(ac,ensoAtom,&size,(Ptr *)&data);
		data[0] = EndianS32_NtoB('past');
		QTSetAtomData(ac, ensoAtom, size, data);
		MovieExportSetSettingsFromAtomContainer(movieExporter, ac);
	}
	DisposeHandle(ac);
	
	/*Boolean cancelled;
	error = MovieExportDoUserDialog(movieExporter, theMovie, NULL, 0, GetMovieDuration(theMovie), &cancelled);
	if(cancelled) goto last;
	if(error) {
		printf("MovieExportDoUserDialog error\n");
		goto last;
	}*/
	
	error = ConvertMovieToDataRef(theMovie, 0, outDataRef, outDataRefType, kQTFileTypeMP4, FOUR_CHAR_CODE('TVOD'), createMovieFileDeleteCurFile|createMovieFileDontCreateResFile, movieExporter);
	if(error) {
        fprintf(stderr,"ConvertMovieToDataRef error: cannot translate .mov into .m4a (%d)\n",error);
		goto last;
	}

	ret = 0;
	
last:
	if(movieExporter) CloseComponent(movieExporter);
	if(theMovie) DisposeMovie(theMovie);
	if(inDataRef) DisposeHandle(inDataRef);
	if(outDataRef) DisposeHandle(outDataRef);

	return ret;
}
예제 #12
0
파일: qtsplitter.c 프로젝트: Kelimion/wine
static HRESULT QT_Process_Movie(QTSplitter* filter)
{
    HRESULT hr = S_OK;
    OSErr err;
    WineDataRefRecord ptrDataRefRec;
    Handle dataRef = NULL;
    Track trk;
    short id = 0;
    DWORD tid;
    LONGLONG time;

    TRACE("Trying movie connect\n");

    ptrDataRefRec.pReader = filter->pInputPin.pReader;
    ptrDataRefRec.streamSubtype = filter->pInputPin.subType;
    PtrToHand( &ptrDataRefRec, &dataRef, sizeof(WineDataRefRecord));

    err = NewMovieFromDataRef(&filter->pQTMovie, newMovieActive|newMovieDontInteractWithUser|newMovieDontAutoUpdateClock|newMovieDontAskUnresolvedDataRefs|newMovieAsyncOK, &id, dataRef, 'WINE');

    DisposeHandle(dataRef);

    if (err != noErr)
    {
        FIXME("QuickTime cannot handle media type(%i)\n",err);
        return VFW_E_TYPE_NOT_ACCEPTED;
    }

    PrePrerollMovie(filter->pQTMovie, 0, fixed1, NULL, NULL);
    PrerollMovie(filter->pQTMovie, 0, fixed1);
    GoToBeginningOfMovie(filter->pQTMovie);
    SetMovieActive(filter->pQTMovie,TRUE);

    if (GetMovieLoadState(filter->pQTMovie) < kMovieLoadStateLoaded)
        MoviesTask(filter->pQTMovie,100);

    trk = GetMovieIndTrackType(filter->pQTMovie, 1, VisualMediaCharacteristic, movieTrackCharacteristic | movieTrackEnabledOnly);
    TRACE("%p is a video track\n",trk);
    if (trk)
       hr = QT_Process_Video_Track(filter, trk);

    if (FAILED(hr))
        return hr;

    trk = GetMovieIndTrackType(filter->pQTMovie, 1, AudioMediaCharacteristic, movieTrackCharacteristic | movieTrackEnabledOnly);
    TRACE("%p is a audio track\n",trk);
    if (trk)
        hr = QT_Process_Audio_Track(filter, trk);

    time = GetMovieDuration(filter->pQTMovie);
    filter->movie_scale = GetMovieTimeScale(filter->pQTMovie);
    filter->sourceSeeking.llDuration = ((double)time / filter->movie_scale) * 10000000;
    filter->sourceSeeking.llStop = filter->sourceSeeking.llDuration;

    TRACE("Movie duration is %s\n",wine_dbgstr_longlong(filter->sourceSeeking.llDuration));

    filter->loaderThread = CreateThread(NULL, 0, QTSplitter_loading_thread, filter, 0, &tid);
    if (filter->loaderThread)
        TRACE("Created loading thread 0x%08x\n", tid);
    filter->splitterThread = CreateThread(NULL, 0, QTSplitter_thread, filter, 0, &tid);
    if (filter->splitterThread)
        TRACE("Created processing thread 0x%08x\n", tid);
    else
        hr = HRESULT_FROM_WIN32(GetLastError());

    return hr;
}
예제 #13
0
파일: sound.cpp 프로젝트: 3v1n0/wxWidgets
bool wxOSXQuickTimeSoundData::Play(unsigned flags)
{
    if ( m_movie )
        Stop();

    m_flags = flags;

    if (!wxInitQT())
        return false;

    if( m_soundHandle )
    {
        Handle dataRef = nil;
        MovieImportComponent miComponent;
        Track targetTrack = nil;
        TimeValue addedDuration = 0;
        long outFlags = 0;
        OSErr err;
        ComponentResult result;

        err = PtrToHand(&m_soundHandle, &dataRef, sizeof(Handle));

        HLock(m_soundHandle);
        if (memcmp(&(*m_soundHandle)[8], "WAVE", 4) == 0)
            miComponent = OpenDefaultComponent(MovieImportType, kQTFileTypeWave);
        else if (memcmp(&(*m_soundHandle)[8], "AIFF", 4) == 0)
            miComponent = OpenDefaultComponent(MovieImportType, kQTFileTypeAIFF);
        else if (memcmp(&(*m_soundHandle)[8], "AIFC", 4) == 0)
            miComponent = OpenDefaultComponent(MovieImportType, kQTFileTypeAIFC);
        else
        {
            HUnlock(m_soundHandle);
            wxLogSysError(wxT("wxSound - Location in memory does not contain valid data"));
            return false;
        }

        HUnlock(m_soundHandle);
        m_movie = NewMovie(0);

        result = MovieImportDataRef(miComponent,                dataRef,
                                    HandleDataHandlerSubType,   m_movie,
                                    nil,                        &targetTrack,
                                    nil,                        &addedDuration,
                                    movieImportCreateTrack,     &outFlags);

        if (result != noErr)
        {
            wxLogSysError(wxString::Format(wxT("Couldn't import movie data\nError:%i"), (int)result));
        }

        SetMovieVolume(m_movie, kFullVolume);
        GoToBeginningOfMovie(m_movie);
    }
    else
    {
        OSErr err = noErr ;

        Handle dataRef = NULL;
        OSType dataRefType;

        err = QTNewDataReferenceFromFullPathCFString(wxCFStringRef(m_sndname,wxLocale::GetSystemEncoding()),
                                                     (UInt32)kQTNativeDefaultPathStyle, 0, &dataRef, &dataRefType);

        wxASSERT(err == noErr);

        if (NULL != dataRef || err != noErr)
        {
            err = NewMovieFromDataRef( &m_movie, newMovieDontAskUnresolvedDataRefs , NULL, dataRef, dataRefType );
            wxASSERT(err == noErr);
            DisposeHandle(dataRef);
        }

        if (err != noErr)
        {
            wxLogSysError(
                          wxString::Format(wxT("wxSound - Could not open file: %s\nError:%i"), m_sndname.c_str(), err )
                          );
            return false;
        }
    }

    //Start the m_movie!
    StartMovie(m_movie);

    if (flags & wxSOUND_ASYNC)
    {
        CreateAndStartTimer();
    }
    else
    {
        wxASSERT_MSG(!(flags & wxSOUND_LOOP), wxT("Can't loop and play syncronously at the same time"));

        //Play movie until it ends, then exit
        //Note that due to quicktime caching this may not always
        //work 100% correctly
        while (!IsMovieDone(m_movie))
            MoviesTask(m_movie, 1);

        DoStop();
    }

    return true;
}
예제 #14
0
////////////////////////////////////////////////////////////////////////////////
// private
bool LLMediaImplQuickTime::load( const std::string url )
{
	if ( url.empty() )
		return false;

	//In case std::string::c_str() makes a copy of the url data,
	//make sure there is memory to hold it before allocating memory for handle.
	//if fails, NewHandleClear(...) should return NULL.
	const char* url_string = url.c_str() ;
	Handle handle = NewHandleClear( ( Size )( url.length() + 1 ) );
    if ( NULL == handle )
		return false;
	if(noErr != MemError() || NULL == *handle)
	{
		return false ;
	}

	BlockMove( url_string, *handle, ( Size )( url.length() + 1 ) );

	//std::cout << "LLMediaImplQuickTime::load( " << url << " )" << std::endl;

	// TODO: supposed to use NewMovieFromDataParams now
	OSErr err = NewMovieFromDataRef( &mMovieHandle, newMovieActive | newMovieDontInteractWithUser | newMovieAsyncOK | newMovieIdleImportOK, nil, handle, URLDataHandlerSubType );
	DisposeHandle( handle );
	if ( noErr != err )
		return false;

	// do pre-roll actions (typically fired for streaming movies but not always)
	PrePrerollMovie( mMovieHandle, 0, GetMoviePreferredRate( mMovieHandle ), moviePrePrerollCompleteCallback, ( void * )this );

	// get movie rect (and check for min/max)
	Rect movie_rect;
	setMovieBoxEnhanced( &movie_rect );

	// make a new movie controller
	mMovieController = NewMovieController( mMovieHandle, &movie_rect, mcNotVisible | mcTopLeftMovie );

#if defined(__APPLE__) || defined(MACOSX)
	setMediaDepth( 4 );
#else
	setMediaDepth( 3 );
#endif

	// tell manager about the media size
	setMediaSize( movie_rect.right - movie_rect.left, movie_rect.bottom - movie_rect.top);

	// movie controller
	MCSetActionFilterWithRefCon( mMovieController, mcActionFilterCallBack, ( long )this );

	SetMoviePlayHints( mMovieHandle, hintsAllowDynamicResize, hintsAllowDynamicResize );

	// function that gets called when a frame is drawn
	SetMovieDrawingCompleteProc( mMovieHandle, movieDrawingCallWhenChanged, movieDrawingCompleteCallback, ( long )this );

	// emit an event to say that a media source was loaded
	LLMediaEvent event( this );
	mEventEmitter.update( &LLMediaObserver::onMediaLoaded, event );

	// set up inital state
	sizeChanged();

	return true;
}
QuickTimeFileReader::QuickTimeFileReader(FileSource source,
                                         DecodeMode decodeMode,
                                         CacheMode mode,
                                         size_t targetRate,
                                         ProgressReporter *reporter) :
    CodedAudioFileReader(mode, targetRate),
    m_source(source),
    m_path(source.getLocalFilename()),
    m_d(new D),
    m_reporter(reporter),
    m_cancelled(false),
    m_completion(0),
    m_decodeThread(0)
{
    m_channelCount = 0;
    m_fileRate = 0;

    Profiler profiler("QuickTimeFileReader::QuickTimeFileReader", true);

SVDEBUG << "QuickTimeFileReader: path is \"" << m_path << "\"" << endl;

    long QTversion;

#ifdef WIN32
    InitializeQTML(0); // FIXME should check QT version
#else
    m_d->err = Gestalt(gestaltQuickTime,&QTversion);
    if ((m_d->err != noErr) || (QTversion < 0x07000000)) {
        m_error = QString("Failed to find compatible version of QuickTime (version 7 or above required)");
        return;
    }
#endif 

    EnterMovies();
	
    Handle dataRef; 
    OSType dataRefType;

//    CFStringRef URLString = CFStringCreateWithCString
 //       (0, m_path.toLocal8Bit().data(), 0);


    QByteArray ba = m_path.toLocal8Bit();

    CFURLRef url = CFURLCreateFromFileSystemRepresentation
        (kCFAllocatorDefault,
         (const UInt8 *)ba.data(),
         (CFIndex)ba.length(),
         false);


//    m_d->err = QTNewDataReferenceFromURLCFString
    m_d->err = QTNewDataReferenceFromCFURL
        (url, 0, &dataRef, &dataRefType);

    if (m_d->err) { 
        m_error = QString("Error creating data reference for QuickTime decoder: code %1").arg(m_d->err);
        return;
    }
    
    short fileID = movieInDataForkResID; 
    short flags = 0; 
    m_d->err = NewMovieFromDataRef
        (&m_d->movie, flags, &fileID, dataRef, dataRefType);

    DisposeHandle(dataRef);
    if (m_d->err) { 
        m_error = QString("Error creating new movie for QuickTime decoder: code %1").arg(m_d->err); 
        return;
    }

    Boolean isProtected = 0;
    Track aTrack = GetMovieIndTrackType
        (m_d->movie, 1, SoundMediaType,
         movieTrackMediaType | movieTrackEnabledOnly);

    if (aTrack) {
        Media aMedia = GetTrackMedia(aTrack);	// get the track media
        if (aMedia) {
            MediaHandler mh = GetMediaHandler(aMedia);	// get the media handler we can query
            if (mh) {
                m_d->err = QTGetComponentProperty(mh,
                                                  kQTPropertyClass_DRM,
                                                  kQTDRMPropertyID_IsProtected,
                                                  sizeof(Boolean), &isProtected,nil);
            } else {
                m_d->err = 1;
            }
        } else {
            m_d->err = 1;
        }
    } else {
        m_d->err = 1;
    }
	
    if (m_d->err && m_d->err != kQTPropertyNotSupportedErr) { 
        m_error = QString("Error checking for DRM in QuickTime decoder: code %1").arg(m_d->err);
        return;
    } else if (!m_d->err && isProtected) { 
        m_error = QString("File is protected with DRM");
        return;
    } else if (m_d->err == kQTPropertyNotSupportedErr && !isProtected) {
        std::cerr << "QuickTime: File is not protected with DRM" << std::endl;
    }

    if (m_d->movie) {
        SetMovieActive(m_d->movie, TRUE);
        m_d->err = GetMoviesError();
        if (m_d->err) {
            m_error = QString("Error in QuickTime decoder activation: code %1").arg(m_d->err);
            return;
        }
    } else {
	m_error = QString("Error in QuickTime decoder: Movie object not valid");
	return;
    }
    
    m_d->err = MovieAudioExtractionBegin
        (m_d->movie, 0, &m_d->extractionSessionRef);
    if (m_d->err) {
        m_error = QString("Error in QuickTime decoder extraction init: code %1").arg(m_d->err);
        return;
    }

    m_d->err = MovieAudioExtractionGetProperty
        (m_d->extractionSessionRef,
         kQTPropertyClass_MovieAudioExtraction_Audio, kQTMovieAudioExtractionAudioPropertyID_AudioStreamBasicDescription,
         sizeof(m_d->asbd),
         &m_d->asbd,
         nil);

    if (m_d->err) {
        m_error = QString("Error in QuickTime decoder property get: code %1").arg(m_d->err);
        return;
    }
	
    m_channelCount = m_d->asbd.mChannelsPerFrame;
    m_fileRate = m_d->asbd.mSampleRate;

    std::cerr << "QuickTime: " << m_channelCount << " channels, " << m_fileRate << " kHz" << std::endl;

    m_d->asbd.mFormatFlags =
        kAudioFormatFlagIsFloat |
        kAudioFormatFlagIsPacked |
        kAudioFormatFlagsNativeEndian;
    m_d->asbd.mBitsPerChannel = sizeof(float) * 8;
    m_d->asbd.mBytesPerFrame = sizeof(float) * m_d->asbd.mChannelsPerFrame;
    m_d->asbd.mBytesPerPacket = m_d->asbd.mBytesPerFrame;
	
    m_d->err = MovieAudioExtractionSetProperty
        (m_d->extractionSessionRef,
         kQTPropertyClass_MovieAudioExtraction_Audio,
         kQTMovieAudioExtractionAudioPropertyID_AudioStreamBasicDescription,
         sizeof(m_d->asbd),
         &m_d->asbd);

    if (m_d->err) {
        m_error = QString("Error in QuickTime decoder property set: code %1").arg(m_d->err);
        m_channelCount = 0;
        return;
    }
    m_d->buffer.mNumberBuffers = 1;
    m_d->buffer.mBuffers[0].mNumberChannels = m_channelCount;
    m_d->buffer.mBuffers[0].mDataByteSize =
        sizeof(float) * m_channelCount * m_d->blockSize;
    m_d->data = new float[m_channelCount * m_d->blockSize];
    m_d->buffer.mBuffers[0].mData = m_d->data;

    initialiseDecodeCache();

    if (decodeMode == DecodeAtOnce) {

        if (m_reporter) {
            connect(m_reporter, SIGNAL(cancelled()), this, SLOT(cancelled()));
            m_reporter->setMessage
                (tr("Decoding %1...").arg(QFileInfo(m_path).fileName()));
        }

        while (1) {
            
            UInt32 framesRead = m_d->blockSize;
            UInt32 extractionFlags = 0;
            m_d->err = MovieAudioExtractionFillBuffer
                (m_d->extractionSessionRef, &framesRead, &m_d->buffer,
                 &extractionFlags);
            if (m_d->err) {
                m_error = QString("Error in QuickTime decoding: code %1")
                    .arg(m_d->err);
                break;
            }

            //!!! progress?

//    std::cerr << "Read " << framesRead << " frames (block size " << m_d->blockSize << ")" << std::endl;

            // QuickTime buffers are interleaved unless specified otherwise
            addSamplesToDecodeCache(m_d->data, framesRead);

            if (framesRead < m_d->blockSize) break;
        }
        
        finishDecodeCache();
        endSerialised();

        m_d->err = MovieAudioExtractionEnd(m_d->extractionSessionRef);
        if (m_d->err) {
            m_error = QString("Error ending QuickTime extraction session: code %1").arg(m_d->err);
        }

        m_completion = 100;

    } else {
        if (m_reporter) m_reporter->setProgress(100);

        if (m_channelCount > 0) {
            m_decodeThread = new DecodeThread(this);
            m_decodeThread->start();
        }
    }

    std::cerr << "QuickTimeFileReader::QuickTimeFileReader: frame count is now " << getFrameCount() << ", error is \"\"" << m_error << "\"" << std::endl;
}
//------------------------------------------------------------
void ofQuicktimeSoundPlayer::loadSound(string fileName, bool stream){

	
	fileName = ofToDataPath(fileName);
	
	// TODO: hmm?
	bMultiPlay = false;

	// [1] init fmod, if necessary

	initializeQuicktime();

	// [2] try to unload any previously loaded sounds
	// & prevent user-created memory leaks
	// if they call "loadSound" repeatedly, for example

	if (bLoadedOk == true){
		unloadSound();
	}
	// [3] load sound

	OSErr error;
    
    //CFBundleRef gameBundle = CFBundleGetMainBundle();
    
    // Find the file in the application bundle.
    CFURLRef movieFileLocation;
    movieFileLocation = CFURLCreateFromFileSystemRepresentation(NULL, (UInt8*)fileName.c_str(), strlen(fileName.c_str()), false);
	
	//CFBundleCopyResourceURL(gameBundle, filename, fileExtension, subdirectory); 
    
    if (movieFileLocation == NULL)
        return;
    
    Handle dataRef;
    OSType dataRefType;
    
    dataRef = NewHandle(sizeof(AliasHandle));
    
    // Get the movie file set up so we can load it in memory.
    // The second parameter to QTNewDataReferenceFromCFURL is flags.
    // It should be set to 0.
    error = QTNewDataReferenceFromCFURL(movieFileLocation, 0, &dataRef, &dataRefType);
    if(error != noErr) {
        DisposeHandle(dataRef);
        CFRelease(movieFileLocation);
        return;
    }
    
    // Get the movie into memory
    short fileID = movieInDataForkResID;
    short flags = 0;
    error = NewMovieFromDataRef(&soundToPlay, flags, &fileID, dataRef, dataRefType);
    
    // Dispose of the memory we allocated.
    DisposeHandle(dataRef);
    CFRelease(movieFileLocation);
	
	// TODO: check here!  
	bLoadedOk = true;
	

}