Commit 796bb923 authored by Maarten Lankhorst's avatar Maarten Lankhorst Committed by Alexandre Julliard

quartz: Move IMediaSeeking from the parser pin to the parser filter.

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.
parent ebf6bbd5
......@@ -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);
......
......@@ -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
......
......@@ -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);
......
......@@ -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,
......
......@@ -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))
......
......@@ -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)
{
......
......@@ -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);
......@@ -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");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment