Commit a0224676 authored by Maarten Lankhorst's avatar Maarten Lankhorst Committed by Alexandre Julliard

quartz: Optimize the processing thread to fetch one sample while processing another.

parent 3cbd9639
...@@ -100,7 +100,7 @@ static HRESULT AVISplitter_NextChunk(LONGLONG * pllCurrentChunkOffset, RIFFCHUNK ...@@ -100,7 +100,7 @@ static HRESULT AVISplitter_NextChunk(LONGLONG * pllCurrentChunkOffset, RIFFCHUNK
return S_OK; return S_OK;
} }
static HRESULT AVISplitter_Sample(LPVOID iface, IMediaSample * pSample) static HRESULT AVISplitter_Sample(LPVOID iface, IMediaSample * pSample, DWORD_PTR cookie)
{ {
AVISplitterImpl *This = (AVISplitterImpl *)iface; AVISplitterImpl *This = (AVISplitterImpl *)iface;
LPBYTE pbSrcStream = NULL; LPBYTE pbSrcStream = NULL;
...@@ -438,6 +438,7 @@ static HRESULT AVISplitter_ProcessOldIndex(AVISplitterImpl *This) ...@@ -438,6 +438,7 @@ static HRESULT AVISplitter_ProcessOldIndex(AVISplitterImpl *This)
IAsyncReader_SyncRead(pin->pReader, offset, sizeof(DWORD), (BYTE *)&temp); IAsyncReader_SyncRead(pin->pReader, offset, sizeof(DWORD), (BYTE *)&temp);
relative = (chunkid != temp); relative = (chunkid != temp);
TRACE("dwChunkId: %.4s\n", (char *)&chunkid);
if (chunkid == mmioFOURCC('7','F','x','x') if (chunkid == mmioFOURCC('7','F','x','x')
&& ((char *)&temp)[0] == 'i' && ((char *)&temp)[1] == 'x') && ((char *)&temp)[0] == 'i' && ((char *)&temp)[1] == 'x')
relative = FALSE; relative = FALSE;
...@@ -459,15 +460,17 @@ static HRESULT AVISplitter_ProcessOldIndex(AVISplitterImpl *This) ...@@ -459,15 +460,17 @@ static HRESULT AVISplitter_ProcessOldIndex(AVISplitterImpl *This)
debugstr_an((char *)&temp2, 4), (DWORD)((mov_pos + offset) >> 32), (DWORD)(mov_pos + offset)); debugstr_an((char *)&temp2, 4), (DWORD)((mov_pos + offset) >> 32), (DWORD)(mov_pos + offset));
relative = -1; relative = -1;
} }
else
TRACE("Scanned dwChunkId: %s\n", debugstr_an((char *)&temp2, 4));
} }
} else if (!relative)
TRACE("Scanned dwChunkId: %s\n", debugstr_an((char *)&temp, 4)); TRACE("Scanned dwChunkId: %s\n", debugstr_an((char *)&temp, 4));
TRACE("dwChunkId: %.4s\n", (char *)&chunkid);
TRACE("dwFlags: %08x\n", pAviOldIndex->aIndex[x].dwFlags); TRACE("dwFlags: %08x\n", pAviOldIndex->aIndex[x].dwFlags);
TRACE("dwOffset (%s): %08x\n", relative ? "relative" : "absolute", offset); TRACE("dwOffset (%s): %08x\n", relative ? "relative" : "absolute", offset);
TRACE("dwSize: %08x\n", pAviOldIndex->aIndex[x].dwSize); TRACE("dwSize: %08x\n", pAviOldIndex->aIndex[x].dwSize);
} }
else break;
}
if (relative == -1) if (relative == -1)
{ {
......
...@@ -116,7 +116,6 @@ static const DWORD tabsel_123[2][3][16] = { ...@@ -116,7 +116,6 @@ static const DWORD tabsel_123[2][3][16] = {
{0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,} } {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,} }
}; };
static HRESULT parse_header(BYTE *header, LONGLONG *plen, LONGLONG *pduration) static HRESULT parse_header(BYTE *header, LONGLONG *plen, LONGLONG *pduration)
{ {
LONGLONG duration = *pduration; LONGLONG duration = *pduration;
...@@ -361,7 +360,7 @@ out_append: ...@@ -361,7 +360,7 @@ out_append:
} }
static HRESULT MPEGSplitter_process_sample(LPVOID iface, IMediaSample * pSample) static HRESULT MPEGSplitter_process_sample(LPVOID iface, IMediaSample * pSample, DWORD_PTR cookie)
{ {
MPEGSplitterImpl *This = (MPEGSplitterImpl*)iface; MPEGSplitterImpl *This = (MPEGSplitterImpl*)iface;
BYTE *pbSrcStream; BYTE *pbSrcStream;
...@@ -419,6 +418,7 @@ static HRESULT MPEGSplitter_process_sample(LPVOID iface, IMediaSample * pSample) ...@@ -419,6 +418,7 @@ static HRESULT MPEGSplitter_process_sample(LPVOID iface, IMediaSample * pSample)
goto fail; goto fail;
IMediaSample_SetSyncPoint(This->pCurrentSample, TRUE); IMediaSample_SetSyncPoint(This->pCurrentSample, TRUE);
IMediaSample_SetDiscontinuity(This->pCurrentSample, This->seek); IMediaSample_SetDiscontinuity(This->pCurrentSample, This->seek);
IMediaSample_SetPreroll(This->pCurrentSample, (This->seek && This->position > 0));
This->seek = FALSE; This->seek = FALSE;
} }
hr = FillBuffer(This, &pbSrcStream, &cbSrcStream, This->pCurrentSample); hr = FillBuffer(This, &pbSrcStream, &cbSrcStream, This->pCurrentSample);
......
...@@ -91,7 +91,7 @@ HRESULT Parser_Create(ParserImpl* pParser, const CLSID* pClsid, PFN_PROCESS_SAMP ...@@ -91,7 +91,7 @@ HRESULT Parser_Create(ParserImpl* pParser, const CLSID* pClsid, PFN_PROCESS_SAMP
MediaSeekingImpl_Init((IBaseFilter*)pParser, stop, current, rate, &pParser->mediaSeeking, &pParser->csFilter); MediaSeekingImpl_Init((IBaseFilter*)pParser, stop, current, rate, &pParser->mediaSeeking, &pParser->csFilter);
pParser->mediaSeeking.lpVtbl = &Parser_Seeking_Vtbl; pParser->mediaSeeking.lpVtbl = &Parser_Seeking_Vtbl;
hr = PullPin_Construct(&Parser_InputPin_Vtbl, &piInput, fnProcessSample, (LPVOID)pParser, fnQueryAccept, fnCleanup, &pParser->csFilter, (IPin **)&pParser->pInputPin); hr = PullPin_Construct(&Parser_InputPin_Vtbl, &piInput, fnProcessSample, (LPVOID)pParser, fnQueryAccept, fnCleanup, NULL, &pParser->csFilter, (IPin **)&pParser->pInputPin);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
typedef struct ParserImpl ParserImpl; typedef struct ParserImpl ParserImpl;
typedef HRESULT (*PFN_PROCESS_SAMPLE) (LPVOID iface, IMediaSample * pSample); typedef HRESULT (*PFN_PROCESS_SAMPLE) (LPVOID iface, IMediaSample * pSample, DWORD_PTR cookie);
typedef HRESULT (*PFN_QUERY_ACCEPT) (LPVOID iface, const AM_MEDIA_TYPE * pmt); typedef HRESULT (*PFN_QUERY_ACCEPT) (LPVOID iface, const AM_MEDIA_TYPE * pmt);
typedef HRESULT (*PFN_PRE_CONNECT) (IPin * iface, IPin * pConnectPin); typedef HRESULT (*PFN_PRE_CONNECT) (IPin * iface, IPin * pConnectPin);
typedef HRESULT (*PFN_CLEANUP) (LPVOID iface); typedef HRESULT (*PFN_CLEANUP) (LPVOID iface);
......
...@@ -20,8 +20,12 @@ ...@@ -20,8 +20,12 @@
/* This function will process incoming samples to the pin. /* This function will process incoming samples to the pin.
* Any return value valid in IMemInputPin::Receive is allowed here * Any return value valid in IMemInputPin::Receive is allowed here
*
* Cookie is the cookie that was set when requesting the buffer, if you don't
* implement custom requesting, you can safely ignore this
*/ */
typedef HRESULT (* SAMPLEPROC)(LPVOID userdata, IMediaSample * pSample); typedef HRESULT (* SAMPLEPROC_PUSH)(LPVOID userdata, IMediaSample * pSample);
typedef HRESULT (* SAMPLEPROC_PULL)(LPVOID userdata, IMediaSample * pSample, DWORD_PTR cookie);
/* This function will determine whether a type is supported or not. /* This function will determine whether a type is supported or not.
* It is allowed to return any error value (within reason), as opposed * It is allowed to return any error value (within reason), as opposed
...@@ -42,6 +46,17 @@ typedef HRESULT (* PRECONNECTPROC)(IPin * iface, IPin * pConnectPin); ...@@ -42,6 +46,17 @@ typedef HRESULT (* PRECONNECTPROC)(IPin * iface, IPin * pConnectPin);
*/ */
typedef HRESULT (* CLEANUPPROC) (LPVOID userdata); typedef HRESULT (* CLEANUPPROC) (LPVOID userdata);
/* This function is called whenever a request for a new sample is made,
* If you implement it (it can be NULL for default behavior), you have to
* call IMemAllocator_GetBuffer and IMemAllocator_RequestBuffer
* This is useful if you want to request more then 1 buffer at simultaneously
* If PullPin->flushed is set, it means that all buffers queued previously are gone
*
* This will also cause the Sample Proc to be called with empty buffers to indicate
* failure in retrieving the sample.
*/
typedef HRESULT (* REQUESTPROC) (LPVOID userdata);
typedef struct IPinImpl typedef struct IPinImpl
{ {
const struct IPinVtbl * lpVtbl; const struct IPinVtbl * lpVtbl;
...@@ -62,7 +77,7 @@ typedef struct InputPin ...@@ -62,7 +77,7 @@ typedef struct InputPin
const IMemInputPinVtbl * lpVtblMemInput; const IMemInputPinVtbl * lpVtblMemInput;
IMemAllocator * pAllocator; IMemAllocator * pAllocator;
SAMPLEPROC fnSampleProc; SAMPLEPROC_PUSH fnSampleProc;
CLEANUPPROC fnCleanProc; CLEANUPPROC fnCleanProc;
REFERENCE_TIME tStart; REFERENCE_TIME tStart;
REFERENCE_TIME tStop; REFERENCE_TIME tStop;
...@@ -85,30 +100,37 @@ typedef struct PullPin ...@@ -85,30 +100,37 @@ typedef struct PullPin
/* inheritance C style! */ /* inheritance C style! */
IPinImpl pin; IPinImpl pin;
REFERENCE_TIME rtStart, rtCurrent, rtNext, rtStop;
IAsyncReader * pReader; IAsyncReader * pReader;
IMemAllocator * pAlloc; IMemAllocator * pAlloc;
SAMPLEPROC fnSampleProc; SAMPLEPROC_PULL fnSampleProc;
PRECONNECTPROC fnPreConnect; PRECONNECTPROC fnPreConnect;
HANDLE hThread; REQUESTPROC fnCustomRequest;
HANDLE hEventStateChanged;
CLEANUPPROC fnCleanProc; CLEANUPPROC fnCleanProc;
REFERENCE_TIME rtStart;
REFERENCE_TIME rtStop;
REFERENCE_TIME rtCurrent;
double dRate; double dRate;
FILTER_STATE state;
BOOL stop_playback; BOOL stop_playback;
DWORD cbAlign;
/* Any code that touches the thread must hold the thread lock, /* Any code that touches the thread must hold the thread lock,
* lock order: thread_lock and then the filter critical section * lock order: thread_lock and then the filter critical section
* also signal thread_sleepy so the thread knows to wake up
*/ */
CRITICAL_SECTION thread_lock; CRITICAL_SECTION thread_lock;
HANDLE hThread;
DWORD requested_state;
HANDLE hEventStateChanged, thread_sleepy;
DWORD state;
} PullPin; } PullPin;
#define Req_Sleepy 0
#define Req_Die 1
#define Req_Run 2
#define Req_Pause 3
/*** Constructors ***/ /*** Constructors ***/
HRESULT InputPin_Construct(const IPinVtbl *InputPin_Vtbl, const PIN_INFO * pPinInfo, SAMPLEPROC pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, CLEANUPPROC pCleanUp, LPCRITICAL_SECTION pCritSec, IPin ** ppPin); HRESULT InputPin_Construct(const IPinVtbl *InputPin_Vtbl, const PIN_INFO * pPinInfo, SAMPLEPROC_PUSH pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, CLEANUPPROC pCleanUp, LPCRITICAL_SECTION pCritSec, IPin ** ppPin);
HRESULT OutputPin_Construct(const IPinVtbl *OutputPin_Vtbl, long outputpin_size, const PIN_INFO * pPinInfo, ALLOCATOR_PROPERTIES *props, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, IPin ** ppPin); HRESULT OutputPin_Construct(const IPinVtbl *OutputPin_Vtbl, long outputpin_size, const PIN_INFO * pPinInfo, ALLOCATOR_PROPERTIES *props, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, IPin ** ppPin);
HRESULT PullPin_Construct(const IPinVtbl *PullPin_Vtbl, const PIN_INFO * pPinInfo, SAMPLEPROC pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, CLEANUPPROC pCleanUp, LPCRITICAL_SECTION pCritSec, IPin ** ppPin); HRESULT PullPin_Construct(const IPinVtbl *PullPin_Vtbl, const PIN_INFO * pPinInfo, SAMPLEPROC_PULL pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, CLEANUPPROC pCleanUp, REQUESTPROC pCustomRequest, LPCRITICAL_SECTION pCritSec, IPin ** ppPin);
/**************************/ /**************************/
/*** Pin Implementation ***/ /*** Pin Implementation ***/
......
...@@ -72,7 +72,7 @@ static LONGLONG duration_to_bytepos(WAVEParserImpl *This, LONGLONG duration) ...@@ -72,7 +72,7 @@ static LONGLONG duration_to_bytepos(WAVEParserImpl *This, LONGLONG duration)
return MEDIATIME_FROM_BYTES(bytepos); return MEDIATIME_FROM_BYTES(bytepos);
} }
static HRESULT WAVEParser_Sample(LPVOID iface, IMediaSample * pSample) static HRESULT WAVEParser_Sample(LPVOID iface, IMediaSample * pSample, DWORD_PTR cookie)
{ {
WAVEParserImpl *This = (WAVEParserImpl *)iface; WAVEParserImpl *This = (WAVEParserImpl *)iface;
LPBYTE pbSrcStream = NULL; LPBYTE pbSrcStream = NULL;
......
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