diff --git a/dlls/quartz/avisplit.c b/dlls/quartz/avisplit.c index 5f601a6df23..140b0dfe29c 100644 --- a/dlls/quartz/avisplit.c +++ b/dlls/quartz/avisplit.c @@ -44,6 +44,13 @@ 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); diff --git a/dlls/quartz/control.c b/dlls/quartz/control.c index 4a7eb024734..5c7c547a7d6 100644 --- a/dlls/quartz/control.c +++ b/dlls/quartz/control.c @@ -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 diff --git a/dlls/quartz/control_private.h b/dlls/quartz/control_private.h index 8352ab70376..c594f605818 100644 --- a/dlls/quartz/control_private.h +++ b/dlls/quartz/control_private.h @@ -18,14 +18,14 @@ * 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); diff --git a/dlls/quartz/filtergraph.c b/dlls/quartz/filtergraph.c index 887c6821d23..d30103db5cb 100644 --- a/dlls/quartz/filtergraph.c +++ b/dlls/quartz/filtergraph.c @@ -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, diff --git a/dlls/quartz/mpegsplit.c b/dlls/quartz/mpegsplit.c index e721eef0bbf..3cebc371618 100644 --- a/dlls/quartz/mpegsplit.c +++ b/dlls/quartz/mpegsplit.c @@ -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)) diff --git a/dlls/quartz/parser.c b/dlls/quartz/parser.c index 94eb614842d..da664ac6db6 100644 --- a/dlls/quartz/parser.c +++ b/dlls/quartz/parser.c @@ -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) { diff --git a/dlls/quartz/parser.h b/dlls/quartz/parser.h index 590e6a50a6c..876f0fc3db5 100644 --- a/dlls/quartz/parser.h +++ b/dlls/quartz/parser.h @@ -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); diff --git a/dlls/quartz/waveparser.c b/dlls/quartz/waveparser.c index fabd0d63629..3d4bd746bf7 100644 --- a/dlls/quartz/waveparser.c +++ b/dlls/quartz/waveparser.c @@ -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");