Aric Stewart : wineqtdecoder: Recreate audio extraction session when we run out of frames.

Alexandre Julliard julliard at winehq.org
Wed May 23 13:22:54 CDT 2012


Module: wine
Branch: master
Commit: 5e4cb217d61f7460a4dcc353d3f8030414ac8d04
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=5e4cb217d61f7460a4dcc353d3f8030414ac8d04

Author: Aric Stewart <aric at codeweavers.com>
Date:   Tue May 22 11:17:09 2012 -0500

wineqtdecoder: Recreate audio extraction session when we run out of frames.

---

 dlls/wineqtdecoder/qtsplitter.c |   77 +++++++++++++++++++++++++++++++++------
 1 files changed, 66 insertions(+), 11 deletions(-)

diff --git a/dlls/wineqtdecoder/qtsplitter.c b/dlls/wineqtdecoder/qtsplitter.c
index b21f198..9b94d7a 100644
--- a/dlls/wineqtdecoder/qtsplitter.c
+++ b/dlls/wineqtdecoder/qtsplitter.c
@@ -479,25 +479,43 @@ kQTMovieAudioExtractionAudioPropertyID_AudioStreamBasicDescription,
     return err;
 }
 
-static DWORD WINAPI QTSplitter_thread(LPVOID data)
+static DWORD WINAPI QTSplitter_loading_thread(LPVOID data)
 {
     QTSplitter *This = (QTSplitter *)data;
-    HRESULT hr = S_OK;
-    TimeValue next_time;
-    CVPixelBufferRef pixelBuffer = NULL;
-    OSStatus err;
-    TimeRecord tr;
 
     if (This->pAudio_Pin)
     {
         /* according to QA1469 a movie has to be fully loaded before we
-           can reliably start the Extraction session */
+           can reliably start the Extraction session.
 
-        while(GetMovieLoadState(This->pQTMovie) < kMovieLoadStateComplete)
-            MoviesTask(This->pQTMovie,1000);
+           If loaded earlier then we only get an extraction session for
+           the part of the movie that is loaded at that time.
 
-        QT_Create_Extract_Session(This);
+            We are trying to load as much of the movie as we can before we
+            start extracting.  However we can recreate the extraction session
+            again when we run out of loaded extraction frames. But we want
+            to try to minimize that.
+         */
+
+        while(GetMovieLoadState(This->pQTMovie) < kMovieLoadStateComplete)
+        {
+            EnterCriticalSection(&This->csReceive);
+            MoviesTask(This->pQTMovie, 100);
+            LeaveCriticalSection(&This->csReceive);
+            Sleep(0);
+        }
     }
+    return 0;
+}
+
+static DWORD WINAPI QTSplitter_thread(LPVOID data)
+{
+    QTSplitter *This = (QTSplitter *)data;
+    HRESULT hr = S_OK;
+    TimeValue next_time;
+    CVPixelBufferRef pixelBuffer = NULL;
+    OSStatus err;
+    TimeRecord tr;
 
     WaitForSingleObject(This->runEvent, -1);
 
@@ -507,7 +525,12 @@ static DWORD WINAPI QTSplitter_thread(LPVOID data)
     GetMovieNextInterestingTime(This->pQTMovie, nextTimeEdgeOK | nextTimeStep, 0, NULL, This->movie_time, 1, &next_time, NULL);
 
     GetMovieTime(This->pQTMovie, &tr);
+
+    if (This->pAudio_Pin)
+        QT_Create_Extract_Session(This);
+
     LeaveCriticalSection(&This->csReceive);
+
     do
     {
         LONGLONG tStart=0, tStop=0;
@@ -585,6 +608,32 @@ static DWORD WINAPI QTSplitter_thread(LPVOID data)
             aData.mBuffers[0].mData = ptr;
 
             err = MovieAudioExtractionFillBuffer(This->aSession, &frames, &aData, &flags);
+            if (frames == 0)
+            {
+                TimeRecord etr;
+
+                /* Ran out of frames, Restart the extraction session */
+                TRACE("Restarting extraction session\n");
+                MovieAudioExtractionEnd(This->aSession);
+                This->aSession = NULL;
+                QT_Create_Extract_Session(This);
+
+                etr = tr;
+                etr.value = SInt64ToWide(This->movie_time);
+                MovieAudioExtractionSetProperty(This->aSession,
+                    kQTPropertyClass_MovieAudioExtraction_Movie,
+                    kQTMovieAudioExtractionMoviePropertyID_CurrentTime,
+                    sizeof(TimeRecord), &etr );
+
+                frames = pvi->nSamplesPerSec * duration;
+                aData.mNumberBuffers = 1;
+                aData.mBuffers[0].mNumberChannels = pvi->nChannels;
+                aData.mBuffers[0].mDataByteSize = data_size;
+                aData.mBuffers[0].mData = ptr;
+
+                MovieAudioExtractionFillBuffer(This->aSession, &frames, &aData, &flags);
+            }
+
             TRACE("Got %i frames\n",(int)frames);
 
             IMediaSample_SetActualDataLength(sample, frames * pvi->nBlockAlign);
@@ -992,10 +1041,16 @@ static HRESULT QT_Process_Movie(QTSplitter* filter)
 
     TRACE("Movie duration is %s\n",wine_dbgstr_longlong(filter->sourceSeeking.llDuration));
 
+    thread = CreateThread(NULL, 0, QTSplitter_loading_thread, filter, 0, &tid);
+    if (thread)
+    {
+        TRACE("Created loading thread 0x%08x\n", tid);
+        CloseHandle(thread);
+    }
     thread = CreateThread(NULL, 0, QTSplitter_thread, filter, 0, &tid);
     if (thread)
     {
-        TRACE("Created thread 0x%08x\n", tid);
+        TRACE("Created processing thread 0x%08x\n", tid);
         CloseHandle(thread);
     }
     else




More information about the wine-cvs mailing list