quartz: Move IMediaSeeking from the parser pin to the parser filter.
authorMaarten Lankhorst <m.b.lankhorst@gmail.com>
Tue, 18 Mar 2008 23:05:00 +0000 (16:05 -0700)
committerAlexandre Julliard <julliard@winehq.org>
Wed, 19 Mar 2008 10:24:46 +0000 (11:24 +0100)
This interface really shouldn't be in a pin, but rather in the
implementation of the filter, since any seeking is done on the entire
filtergraph, so implementing it in the filter makes more sense.

dlls/quartz/avisplit.c
dlls/quartz/control.c
dlls/quartz/control_private.h
dlls/quartz/filtergraph.c
dlls/quartz/mpegsplit.c
dlls/quartz/parser.c
dlls/quartz/parser.h
dlls/quartz/waveparser.c

index 5f601a6df23169375afeb1ecf57d1080fad43172..140b0dfe29c179972d329d15f71b81a8a032d9bf 100644 (file)
 
 WINE_DEFAULT_DEBUG_CHANNEL(quartz);
 
+typedef struct StreamData
+{
+    DWORD dwSampleSize;
+    FLOAT fSamplesPerSec;
+    DWORD dwLength;
+} StreamData;
+
 typedef struct AVISplitterImpl
 {
     ParserImpl Parser;
@@ -52,6 +59,7 @@ typedef struct AVISplitterImpl
     LONGLONG CurrentChunkOffset; /* in media time */
     LONGLONG EndOfFile;
     AVIMAINHEADER AviHeader;
+    StreamData *streams;
 } AVISplitterImpl;
 
 static HRESULT AVISplitter_NextChunk(LONGLONG * pllCurrentChunkOffset, RIFFCHUNK * pCurrentChunk, const REFERENCE_TIME * tStart, const REFERENCE_TIME * tStop, const BYTE * pbSrcStream, int inner)
@@ -241,6 +249,7 @@ static HRESULT AVISplitter_Sample(LPVOID iface, IMediaSample * pSample)
             if (SUCCEEDED(hr))
             {
                 REFERENCE_TIME tAviStart, tAviStop;
+                StreamData *stream = This->streams + streamId;
 
                 /* FIXME: hack */
                 if (pOutputPin->dwSamplesProcessed == 0)
@@ -250,14 +259,14 @@ static HRESULT AVISplitter_Sample(LPVOID iface, IMediaSample * pSample)
 
                 pOutputPin->dwSamplesProcessed++;
 
-                if (pOutputPin->dwSampleSize)
-                    tAviStart = (LONGLONG)ceil(10000000.0 * (float)(pOutputPin->dwSamplesProcessed - 1) * (float)IMediaSample_GetActualDataLength(This->pCurrentSample) / ((float)pOutputPin->dwSampleSize * pOutputPin->fSamplesPerSec));
+                if (stream->dwSampleSize)
+                    tAviStart = (LONGLONG)ceil(10000000.0 * (float)(pOutputPin->dwSamplesProcessed - 1) * (float)IMediaSample_GetActualDataLength(This->pCurrentSample) / ((float)stream->dwSampleSize * stream->fSamplesPerSec));
                 else
-                    tAviStart = (LONGLONG)ceil(10000000.0 * (float)(pOutputPin->dwSamplesProcessed - 1) / (float)pOutputPin->fSamplesPerSec);
-                if (pOutputPin->dwSampleSize)
-                    tAviStop = (LONGLONG)ceil(10000000.0 * (float)pOutputPin->dwSamplesProcessed * (float)IMediaSample_GetActualDataLength(This->pCurrentSample) / ((float)pOutputPin->dwSampleSize * pOutputPin->fSamplesPerSec));
+                    tAviStart = (LONGLONG)ceil(10000000.0 * (float)(pOutputPin->dwSamplesProcessed - 1) / (float)stream->fSamplesPerSec);
+                if (stream->dwSampleSize)
+                    tAviStop = (LONGLONG)ceil(10000000.0 * (float)pOutputPin->dwSamplesProcessed * (float)IMediaSample_GetActualDataLength(This->pCurrentSample) / ((float)stream->dwSampleSize * stream->fSamplesPerSec));
                 else
-                    tAviStop = (LONGLONG)ceil(10000000.0 * (float)pOutputPin->dwSamplesProcessed / (float)pOutputPin->fSamplesPerSec);
+                    tAviStop = (LONGLONG)ceil(10000000.0 * (float)pOutputPin->dwSamplesProcessed / (float)stream->fSamplesPerSec);
 
                 IMediaSample_SetTime(This->pCurrentSample, &tAviStart, &tAviStop);
 
@@ -337,6 +346,7 @@ static HRESULT AVISplitter_ProcessStreamList(AVISplitterImpl * This, const BYTE
     DWORD dwLength = 0;
     ALLOCATOR_PROPERTIES props;
     static const WCHAR wszStreamTemplate[] = {'S','t','r','e','a','m',' ','%','0','2','d',0};
+    StreamData *stream;
 
     props.cbAlign = 1;
     props.cbPrefix = 0;
@@ -456,8 +466,13 @@ static HRESULT AVISplitter_ProcessStreamList(AVISplitterImpl * This, const BYTE
     TRACE("fSamplesPerSec = %f\n", (double)fSamplesPerSec);
     TRACE("dwSampleSize = %x\n", dwSampleSize);
     TRACE("dwLength = %x\n", dwLength);
+    This->streams = CoTaskMemRealloc(This->streams, sizeof(StreamData) * (This->Parser.cStreams+1));
+    stream = This->streams + This->Parser.cStreams;
+    stream->fSamplesPerSec = fSamplesPerSec;
+    stream->dwSampleSize = dwSampleSize;
+    stream->dwLength = dwLength; /* TODO: Use this for mediaseeking */
 
-    hr = Parser_AddPin(&(This->Parser), &piOutput, &props, &amt, fSamplesPerSec, dwSampleSize, dwLength);
+    hr = Parser_AddPin(&(This->Parser), &piOutput, &props, &amt);
 
     return hr;
 }
@@ -605,6 +620,7 @@ HRESULT AVISplitter_create(IUnknown * pUnkOuter, LPVOID * ppv)
     This = CoTaskMemAlloc(sizeof(AVISplitterImpl));
 
     This->pCurrentSample = NULL;
+    This->streams = NULL;
 
     hr = Parser_Create(&(This->Parser), &CLSID_AviSplitter, AVISplitter_Sample, AVISplitter_QueryAccept, AVISplitter_InputPin_PreConnect, AVISplitter_Cleanup);
 
index 4a7eb0247347f33549f0b39d72f40e0a60c4ba0d..5c7c547a7d67d4aa377d59a3ec447e9ecfea083f 100644 (file)
@@ -29,7 +29,7 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(quartz);
 
-HRESULT MediaSeekingImpl_Init(LPVOID pUserData, CHANGEPROC fnChangeStop, CHANGEPROC fnChangeStart, CHANGEPROC fnChangeRate, MediaSeekingImpl * pSeeking)
+HRESULT MediaSeekingImpl_Init(IBaseFilter *pUserData, CHANGEPROC fnChangeStop, CHANGEPROC fnChangeStart, CHANGEPROC fnChangeRate, MediaSeekingImpl * pSeeking)
 {
     assert(fnChangeStop && fnChangeStart && fnChangeRate);
 
@@ -242,9 +242,8 @@ HRESULT WINAPI MediaSeekingImpl_SetRate(IMediaSeeking * iface, double dRate)
     BOOL bChangeRate = (dRate != This->dRate);
 
     TRACE("(%e)\n", dRate);
-       
+
     This->dRate = dRate;
-       
     if (bChangeRate)
         return This->fnChangeRate(This->pUserData);
     else
index 8352ab703761849331895345db1fcde195a36816..c594f60581864ca36d84fd44413fa9e1a1ed2b12 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
-typedef HRESULT (* CHANGEPROC)(LPVOID pUserData);
+typedef HRESULT (* CHANGEPROC)(IBaseFilter *pUserData);
 
 typedef struct MediaSeekingImpl
 {
        const IMediaSeekingVtbl * lpVtbl;
 
        ULONG refCount;
-       LPVOID pUserData;
+       IBaseFilter *pUserData;
        CHANGEPROC fnChangeStop;
        CHANGEPROC fnChangeStart;
        CHANGEPROC fnChangeRate;
@@ -36,7 +36,7 @@ typedef struct MediaSeekingImpl
        LONGLONG llDuration; /* FIXME: needed? */
 } MediaSeekingImpl;
 
-HRESULT MediaSeekingImpl_Init(LPVOID pUserData, CHANGEPROC fnChangeStop, CHANGEPROC fnChangeStart, CHANGEPROC fnChangeRate, MediaSeekingImpl * pSeeking);
+HRESULT MediaSeekingImpl_Init(IBaseFilter *pUserData, CHANGEPROC fnChangeStop, CHANGEPROC fnChangeStart, CHANGEPROC fnChangeRate, MediaSeekingImpl * pSeeking);
 
 HRESULT WINAPI MediaSeekingImpl_GetCapabilities(IMediaSeeking * iface, DWORD * pCapabilities);
 HRESULT WINAPI MediaSeekingImpl_CheckCapabilities(IMediaSeeking * iface, DWORD * pCapabilities);
index 887c6821d23fc789f4abdd5d29e0ab9a87f4136a..d30103db5cb247cdee61624b171e4301e9d7226d 100644 (file)
@@ -1582,7 +1582,7 @@ static HRESULT WINAPI MediaControl_Stop(IMediaControl *iface) {
     SendFilterMessage(iface, SendStop);
     This->state = State_Stopped;
     LeaveCriticalSection(&This->cs);
-    return S_FALSE;
+    return S_OK;
 }
 
 static HRESULT WINAPI MediaControl_GetState(IMediaControl *iface,
index e721eef0bbf70de6261dedb2c0ad19af515b8099..3cebc3716182afc8e380bc013296e9ea61b6323b 100644 (file)
@@ -52,12 +52,13 @@ WINE_DEFAULT_DEBUG_CHANNEL(quartz);
 #define MPEG_AUDIO_HEADER 1
 #define MPEG_NO_HEADER 0
 
-
 typedef struct MPEGSplitterImpl
 {
     ParserImpl Parser;
     IMediaSample *pCurrentSample;
     LONGLONG EndOfFile;
+    DWORD dwSampleSize, dwLength;
+    FLOAT fSamplesPerSec;
 } MPEGSplitterImpl;
 
 static int MPEGSplitter_head_check(const BYTE *header)
@@ -169,12 +170,12 @@ static HRESULT MPEGSplitter_process_sample(LPVOID iface, IMediaSample * pSample)
             {
                 REFERENCE_TIME tMPEGStart, tMPEGStop;
 
-                pOutputPin->dwSamplesProcessed = (BYTES_FROM_MEDIATIME(tStart)+used_bytes) / pOutputPin->dwSampleSize;
+                pOutputPin->dwSamplesProcessed = (BYTES_FROM_MEDIATIME(tStart)+used_bytes) / This->dwSampleSize;
 
                 tMPEGStart = (tStart + MEDIATIME_FROM_BYTES(used_bytes-bytes_written)) /
-                             (pOutputPin->fSamplesPerSec*pOutputPin->dwSampleSize);
+                             (This->fSamplesPerSec*This->dwSampleSize);
                 tMPEGStop  = (tStart + MEDIATIME_FROM_BYTES(used_bytes)) /
-                             (pOutputPin->fSamplesPerSec*pOutputPin->dwSampleSize);
+                             (This->fSamplesPerSec*This->dwSampleSize);
 
                 /* If the start of the sample has a valid MPEG header, it's a
                  * sync point */
@@ -219,12 +220,12 @@ static HRESULT MPEGSplitter_process_sample(LPVOID iface, IMediaSample * pSample)
             {
                 REFERENCE_TIME tMPEGStart, tMPEGStop;
 
-                pOutputPin->dwSamplesProcessed = (BYTES_FROM_MEDIATIME(tStart)+used_bytes) / pOutputPin->dwSampleSize;
+                pOutputPin->dwSamplesProcessed = (BYTES_FROM_MEDIATIME(tStart)+used_bytes) / This->dwSampleSize;
 
                 tMPEGStart = (tStart + MEDIATIME_FROM_BYTES(used_bytes-bytes_written)) /
-                             (pOutputPin->fSamplesPerSec*pOutputPin->dwSampleSize);
+                             (This->fSamplesPerSec*This->dwSampleSize);
                 tMPEGStop  = (tStart + MEDIATIME_FROM_BYTES(used_bytes)) /
-                             (pOutputPin->fSamplesPerSec*pOutputPin->dwSampleSize);
+                             (This->fSamplesPerSec*This->dwSampleSize);
 
                 if (MPEGSplitter_head_check(pbDstStream) == MPEG_AUDIO_HEADER)
                     IMediaSample_SetSyncPoint(This->pCurrentSample, TRUE);
@@ -490,12 +491,10 @@ static HRESULT MPEGSplitter_pre_connect(IPin *iface, IPin *pConnectPin)
                 props.cbBuffer = 0x4000 / format->nBlockAlign *
                                  format->nBlockAlign;
                 props.cBuffers = 1;
-
-                hr = Parser_AddPin(&(This->Parser), &piOutput, &props, &amt,
-                                   (float)format->nAvgBytesPerSec /
-                                    (float)format->nBlockAlign,
-                                   format->nBlockAlign,
-                                   total);
+                This->fSamplesPerSec = (float)format->nAvgBytesPerSec / (float)format->nBlockAlign;
+                This->dwSampleSize = format->nBlockAlign;
+                This->dwLength = total;
+                hr = Parser_AddPin(&(This->Parser), &piOutput, &props, &amt);
             }
 
             if (FAILED(hr))
index 94eb614842d603c71ceba800f0ba605ed10e2889..da664ac6db65c176edd3d772d68568a87351999d 100644 (file)
@@ -43,15 +43,15 @@ static const IPinVtbl Parser_OutputPin_Vtbl;
 static const IPinVtbl Parser_InputPin_Vtbl;
 
 static HRESULT Parser_OutputPin_QueryAccept(LPVOID iface, const AM_MEDIA_TYPE * pmt);
-static HRESULT Parser_ChangeStart(LPVOID iface);
-static HRESULT Parser_ChangeStop(LPVOID iface);
-static HRESULT Parser_ChangeRate(LPVOID iface);
+static HRESULT Parser_ChangeStart(IBaseFilter *iface);
+static HRESULT Parser_ChangeStop(IBaseFilter *iface);
+static HRESULT Parser_ChangeRate(IBaseFilter *iface);
 
 static HRESULT Parser_InputPin_Construct(const PIN_INFO * pPinInfo, SAMPLEPROC pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, IPin ** ppPin);
 
-static inline Parser_OutputPin *impl_from_IMediaSeeking( IMediaSeeking *iface )
+static inline ParserImpl *impl_from_IMediaSeeking( IMediaSeeking *iface )
 {
-    return (Parser_OutputPin *)((char*)iface - FIELD_OFFSET(Parser_OutputPin, mediaSeeking.lpVtbl));
+    return (ParserImpl *)((char*)iface - FIELD_OFFSET(ParserImpl, mediaSeeking.lpVtbl));
 }
 
 
@@ -80,6 +80,9 @@ HRESULT Parser_Create(ParserImpl* pParser, const CLSID* pClsid, PFN_PROCESS_SAMP
     piInput.pFilter = (IBaseFilter *)pParser;
     lstrcpynW(piInput.achName, wcsInputPinName, sizeof(piInput.achName) / sizeof(piInput.achName[0]));
 
+    MediaSeekingImpl_Init((IBaseFilter*)pParser, Parser_ChangeStop, Parser_ChangeStart, Parser_ChangeRate, &pParser->mediaSeeking);
+    pParser->mediaSeeking.lpVtbl = &Parser_Seeking_Vtbl;
+
     hr = Parser_InputPin_Construct(&piInput, fnProcessSample, (LPVOID)pParser, fnQueryAccept, &pParser->csFilter, (IPin **)&pParser->pInputPin);
 
     if (SUCCEEDED(hr))
@@ -98,21 +101,16 @@ HRESULT Parser_Create(ParserImpl* pParser, const CLSID* pClsid, PFN_PROCESS_SAMP
     return hr;
 }
 
-static HRESULT Parser_OutputPin_Init(const PIN_INFO * pPinInfo, ALLOCATOR_PROPERTIES * props, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, const AM_MEDIA_TYPE * pmt, float fSamplesPerSec, LPCRITICAL_SECTION pCritSec, Parser_OutputPin * pPinImpl)
+static HRESULT Parser_OutputPin_Init(const PIN_INFO * pPinInfo, ALLOCATOR_PROPERTIES * props, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, const AM_MEDIA_TYPE * pmt, LPCRITICAL_SECTION pCritSec, Parser_OutputPin * pPinImpl)
 {
     pPinImpl->pmt = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));
     CopyMediaType(pPinImpl->pmt, pmt);
     pPinImpl->dwSamplesProcessed = 0;
-    pPinImpl->dwSampleSize = 0;
-    pPinImpl->fSamplesPerSec = fSamplesPerSec;
-
-    MediaSeekingImpl_Init((LPVOID)pPinInfo->pFilter, Parser_ChangeStop, Parser_ChangeStart, Parser_ChangeRate, &pPinImpl->mediaSeeking);
-    pPinImpl->mediaSeeking.lpVtbl = &Parser_Seeking_Vtbl;
 
     return OutputPin_Init(pPinInfo, props, pUserData, pQueryAccept, pCritSec, &pPinImpl->pin);
 }
 
-static HRESULT Parser_OutputPin_Construct(const PIN_INFO * pPinInfo, ALLOCATOR_PROPERTIES * props, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, const AM_MEDIA_TYPE * pmt, float fSamplesPerSec, LPCRITICAL_SECTION pCritSec, IPin ** ppPin)
+static HRESULT Parser_OutputPin_Construct(const PIN_INFO * pPinInfo, ALLOCATOR_PROPERTIES * props, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, const AM_MEDIA_TYPE * pmt, LPCRITICAL_SECTION pCritSec, IPin ** ppPin)
 {
     Parser_OutputPin * pPinImpl;
 
@@ -125,7 +123,7 @@ static HRESULT Parser_OutputPin_Construct(const PIN_INFO * pPinInfo, ALLOCATOR_P
     if (!pPinImpl)
         return E_OUTOFMEMORY;
 
-    if (SUCCEEDED(Parser_OutputPin_Init(pPinInfo, props, pUserData, pQueryAccept, pmt, fSamplesPerSec, pCritSec, pPinImpl)))
+    if (SUCCEEDED(Parser_OutputPin_Init(pPinInfo, props, pUserData, pQueryAccept, pmt, pCritSec, pPinImpl)))
     {
         pPinImpl->pin.pin.lpVtbl = &Parser_OutputPin_Vtbl;
 
@@ -152,6 +150,8 @@ static HRESULT WINAPI Parser_QueryInterface(IBaseFilter * iface, REFIID riid, LP
         *ppv = (LPVOID)This;
     else if (IsEqualIID(riid, &IID_IBaseFilter))
         *ppv = (LPVOID)This;
+    else if (IsEqualIID(riid, &IID_IMediaSeeking))
+        *ppv = (LPVOID)&This->mediaSeeking;
 
     if (*ppv)
     {
@@ -290,10 +290,12 @@ static HRESULT WINAPI Parser_Pause(IBaseFilter * iface)
         {
             for (i = 1; i < This->cStreams + 1; i++)
             {
-                Parser_OutputPin* StreamPin = (Parser_OutputPin *)This->ppPins[i];
-                OutputPin_DeliverNewSegment((OutputPin *)This->ppPins[i], 0, (LONGLONG)ceil(10000000.0 * (float)StreamPin->dwLength / StreamPin->fSamplesPerSec), 1.0);
-                StreamPin->mediaSeeking.llDuration = (LONGLONG)ceil(10000000.0 * (float)StreamPin->dwLength / StreamPin->fSamplesPerSec);
-                StreamPin->mediaSeeking.llStop = (LONGLONG)ceil(10000000.0 * (float)StreamPin->dwLength / StreamPin->fSamplesPerSec);
+                LONGLONG duration;
+                DOUBLE speed;
+
+                IMediaSeeking_GetDuration((IMediaSeeking *)&This->mediaSeeking, &duration);
+                IMediaSeeking_GetRate((IMediaSeeking *)&This->mediaSeeking, &speed);
+                OutputPin_DeliverNewSegment((OutputPin *)This->ppPins[i], 0, duration, speed);
                 OutputPin_CommitAllocator((OutputPin *)This->ppPins[i]);
             }
 
@@ -497,8 +499,7 @@ static const IBaseFilterVtbl Parser_Vtbl =
     Parser_QueryVendorInfo
 };
 
-HRESULT Parser_AddPin(ParserImpl * This, const PIN_INFO * piOutput, ALLOCATOR_PROPERTIES * props,
-                      const AM_MEDIA_TYPE * amt, float fSamplesPerSec, DWORD dwSampleSize, DWORD dwLength)
+HRESULT Parser_AddPin(ParserImpl * This, const PIN_INFO * piOutput, ALLOCATOR_PROPERTIES * props, const AM_MEDIA_TYPE * amt)
 {
     IPin ** ppOldPins;
     HRESULT hr;
@@ -508,12 +509,10 @@ HRESULT Parser_AddPin(ParserImpl * This, const PIN_INFO * piOutput, ALLOCATOR_PR
     This->ppPins = CoTaskMemAlloc((This->cStreams + 2) * sizeof(IPin *));
     memcpy(This->ppPins, ppOldPins, (This->cStreams + 1) * sizeof(IPin *));
 
-    hr = Parser_OutputPin_Construct(piOutput, props, NULL, Parser_OutputPin_QueryAccept, amt, fSamplesPerSec, &This->csFilter, This->ppPins + This->cStreams + 1);
+    hr = Parser_OutputPin_Construct(piOutput, props, NULL, Parser_OutputPin_QueryAccept, amt, &This->csFilter, This->ppPins + This->cStreams + 1);
 
     if (SUCCEEDED(hr))
     {
-        ((Parser_OutputPin *)(This->ppPins[This->cStreams + 1]))->dwSampleSize = dwSampleSize;
-        ((Parser_OutputPin *)(This->ppPins[This->cStreams + 1]))->dwLength = dwLength;
         ((Parser_OutputPin *)(This->ppPins[This->cStreams + 1]))->pin.pin.pUserData = (LPVOID)This->ppPins[This->cStreams + 1];
         This->cStreams++;
         CoTaskMemFree(ppOldPins);
@@ -551,19 +550,19 @@ static HRESULT Parser_RemoveOutputPins(ParserImpl * This)
     return S_OK;
 }
 
-static HRESULT Parser_ChangeStart(LPVOID iface)
+static HRESULT Parser_ChangeStart(IBaseFilter *iface)
 {
     FIXME("(%p)\n", iface);
     return S_OK;
 }
 
-static HRESULT Parser_ChangeStop(LPVOID iface)
+static HRESULT Parser_ChangeStop(IBaseFilter *iface)
 {
     FIXME("(%p)\n", iface);
     return S_OK;
 }
 
-static HRESULT Parser_ChangeRate(LPVOID iface)
+static HRESULT Parser_ChangeRate(IBaseFilter *iface)
 {
     FIXME("(%p)\n", iface);
     return S_OK;
@@ -572,21 +571,21 @@ static HRESULT Parser_ChangeRate(LPVOID iface)
 
 static HRESULT WINAPI Parser_Seeking_QueryInterface(IMediaSeeking * iface, REFIID riid, LPVOID * ppv)
 {
-    Parser_OutputPin *This = impl_from_IMediaSeeking(iface);
+    ParserImpl *This = impl_from_IMediaSeeking(iface);
 
     return IUnknown_QueryInterface((IUnknown *)This, riid, ppv);
 }
 
 static ULONG WINAPI Parser_Seeking_AddRef(IMediaSeeking * iface)
 {
-    Parser_OutputPin *This = impl_from_IMediaSeeking(iface);
+    ParserImpl *This = impl_from_IMediaSeeking(iface);
 
     return IUnknown_AddRef((IUnknown *)This);
 }
 
 static ULONG WINAPI Parser_Seeking_Release(IMediaSeeking * iface)
 {
-    Parser_OutputPin *This = impl_from_IMediaSeeking(iface);
+    ParserImpl *This = impl_from_IMediaSeeking(iface);
 
     return IUnknown_Release((IUnknown *)This);
 }
@@ -628,7 +627,9 @@ static HRESULT WINAPI Parser_OutputPin_QueryInterface(IPin * iface, REFIID riid,
     else if (IsEqualIID(riid, &IID_IPin))
         *ppv = (LPVOID)iface;
     else if (IsEqualIID(riid, &IID_IMediaSeeking))
-        *ppv = (LPVOID)&This->mediaSeeking;
+    {
+        return IBaseFilter_QueryInterface((IBaseFilter*)&This->pin.pin.pinInfo.pFilter, &IID_IMediaSeeking, ppv);
+    }
 
     if (*ppv)
     {
index 590e6a50a6c819183f80cede9629e5d3ec7d0999..876f0fc3db5de558a93b04f3024dd1679e652249 100644 (file)
@@ -41,6 +41,7 @@ struct ParserImpl
     PullPin * pInputPin;
     IPin ** ppPins;
     ULONG cStreams;
+    MediaSeekingImpl mediaSeeking;
 };
 
 typedef struct Parser_OutputPin
@@ -48,13 +49,9 @@ typedef struct Parser_OutputPin
     OutputPin pin;
 
     AM_MEDIA_TYPE * pmt;
-    float fSamplesPerSec;
     DWORD dwSamplesProcessed;
-    DWORD dwSampleSize;
-    DWORD dwLength;
-    MediaSeekingImpl mediaSeeking;
 } Parser_OutputPin;
 
-HRESULT Parser_AddPin(ParserImpl * This, const PIN_INFO * piOutput, ALLOCATOR_PROPERTIES * props,
-                      const AM_MEDIA_TYPE * amt, float fSamplesPerSec, DWORD dwSampleSize, DWORD dwLength);
+HRESULT Parser_AddPin(ParserImpl * This, const PIN_INFO * piOutput, ALLOCATOR_PROPERTIES * props, const AM_MEDIA_TYPE * amt);
+
 HRESULT Parser_Create(ParserImpl*, const CLSID*, PFN_PROCESS_SAMPLE, PFN_QUERY_ACCEPT, PFN_PRE_CONNECT, PFN_CLEANUP);
index fabd0d63629d564959344f6d502d1469ffb7d149..3d4bd746bf747bf49653993c43e066c424d22cf9 100644 (file)
@@ -47,6 +47,9 @@ typedef struct WAVEParserImpl
     IMediaSample * pCurrentSample;
     LONGLONG StartOfFile; /* in media time */
     LONGLONG EndOfFile;
+    DWORD dwSampleSize;
+    FLOAT fSamplesPerSec;
+    DWORD dwLength;
 } WAVEParserImpl;
 
 static HRESULT WAVEParser_Sample(LPVOID iface, IMediaSample * pSample)
@@ -133,14 +136,14 @@ static HRESULT WAVEParser_Sample(LPVOID iface, IMediaSample * pSample)
 
                 pOutputPin->dwSamplesProcessed++;
 
-                if (pOutputPin->dwSampleSize)
-                    tAviStart = (LONGLONG)ceil(10000000.0 * (float)(pOutputPin->dwSamplesProcessed - 1) * (float)IMediaSample_GetActualDataLength(This->pCurrentSample) / ((float)pOutputPin->dwSampleSize * pOutputPin->fSamplesPerSec));
+                if (This->dwSampleSize)
+                    tAviStart = (LONGLONG)ceil(10000000.0 * (float)(pOutputPin->dwSamplesProcessed - 1) * (float)IMediaSample_GetActualDataLength(This->pCurrentSample) / ((float)This->dwSampleSize * This->fSamplesPerSec));
                 else
-                    tAviStart = (LONGLONG)ceil(10000000.0 * (float)(pOutputPin->dwSamplesProcessed - 1) / (float)pOutputPin->fSamplesPerSec);
-                if (pOutputPin->dwSampleSize)
-                    tAviStop = (LONGLONG)ceil(10000000.0 * (float)pOutputPin->dwSamplesProcessed * (float)IMediaSample_GetActualDataLength(This->pCurrentSample) / ((float)pOutputPin->dwSampleSize * pOutputPin->fSamplesPerSec));
+                    tAviStart = (LONGLONG)ceil(10000000.0 * (float)(pOutputPin->dwSamplesProcessed - 1) / (float)This->fSamplesPerSec);
+                if (This->dwSampleSize)
+                    tAviStop = (LONGLONG)ceil(10000000.0 * (float)pOutputPin->dwSamplesProcessed * (float)IMediaSample_GetActualDataLength(This->pCurrentSample) / ((float)This->dwSampleSize * This->fSamplesPerSec));
                 else
-                    tAviStop = (LONGLONG)ceil(10000000.0 * (float)pOutputPin->dwSamplesProcessed / (float)pOutputPin->fSamplesPerSec);
+                    tAviStop = (LONGLONG)ceil(10000000.0 * (float)pOutputPin->dwSamplesProcessed / (float)This->fSamplesPerSec);
 
                 IMediaSample_SetTime(This->pCurrentSample, &tAviStart, &tAviStop);
 
@@ -220,10 +223,8 @@ static HRESULT WAVEParser_InputPin_PreConnect(IPin * iface, IPin * pConnectPin)
     PIN_INFO piOutput;
     ALLOCATOR_PROPERTIES props;
     AM_MEDIA_TYPE amt;
-    float fSamplesPerSec = 0.0f;
-    DWORD dwSampleSize = 0;
-    DWORD dwLength = 0;
     WAVEParserImpl * pWAVEParser = (WAVEParserImpl *)This->pin.pinInfo.pFilter;
+    LONGLONG length, avail;
 
     piOutput.dir = PINDIR_OUTPUT;
     piOutput.pFilter = (IBaseFilter *)This;
@@ -292,8 +293,11 @@ static HRESULT WAVEParser_InputPin_PreConnect(IPin * iface, IPin * pConnectPin)
     props.cbPrefix = 0;
     props.cbBuffer = 4096;
     props.cBuffers = 2;
-    
-    hr = Parser_AddPin(&(pWAVEParser->Parser), &piOutput, &props, &amt, fSamplesPerSec, dwSampleSize, dwLength);
+    pWAVEParser->dwSampleSize = ((WAVEFORMATEX*)amt.pbFormat)->nBlockAlign;
+    IAsyncReader_Length(This->pReader, &length, &avail);
+    pWAVEParser->dwLength = length / (ULONGLONG)pWAVEParser->dwSampleSize;
+    pWAVEParser->fSamplesPerSec = ((WAVEFORMATEX*)amt.pbFormat)->nAvgBytesPerSec / ((WAVEFORMATEX*)amt.pbFormat)->nBlockAlign;
+    hr = Parser_AddPin(&(pWAVEParser->Parser), &piOutput, &props, &amt);
     
     TRACE("WAVE File ok\n");