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
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;
LPBYTE pbSrcStream = NULL;
......@@ -438,6 +438,7 @@ static HRESULT AVISplitter_ProcessOldIndex(AVISplitterImpl *This)
IAsyncReader_SyncRead(pin->pReader, offset, sizeof(DWORD), (BYTE *)&temp);
relative = (chunkid != temp);
TRACE("dwChunkId: %.4s\n", (char *)&chunkid);
if (chunkid == mmioFOURCC('7','F','x','x')
&& ((char *)&temp)[0] == 'i' && ((char *)&temp)[1] == 'x')
relative = FALSE;
......@@ -459,15 +460,17 @@ static HRESULT AVISplitter_ProcessOldIndex(AVISplitterImpl *This)
debugstr_an((char *)&temp2, 4), (DWORD)((mov_pos + offset) >> 32), (DWORD)(mov_pos + offset));
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("dwChunkId: %.4s\n", (char *)&chunkid);
TRACE("dwFlags: %08x\n", pAviOldIndex->aIndex[x].dwFlags);
TRACE("dwOffset (%s): %08x\n", relative ? "relative" : "absolute", offset);
TRACE("dwSize: %08x\n", pAviOldIndex->aIndex[x].dwSize);
}
else break;
}
if (relative == -1)
{
......
......@@ -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,} }
};
static HRESULT parse_header(BYTE *header, LONGLONG *plen, LONGLONG *pduration)
{
LONGLONG duration = *pduration;
......@@ -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;
BYTE *pbSrcStream;
......@@ -419,6 +418,7 @@ static HRESULT MPEGSplitter_process_sample(LPVOID iface, IMediaSample * pSample)
goto fail;
IMediaSample_SetSyncPoint(This->pCurrentSample, TRUE);
IMediaSample_SetDiscontinuity(This->pCurrentSample, This->seek);
IMediaSample_SetPreroll(This->pCurrentSample, (This->seek && This->position > 0));
This->seek = FALSE;
}
hr = FillBuffer(This, &pbSrcStream, &cbSrcStream, This->pCurrentSample);
......
......@@ -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);
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))
{
......
......@@ -20,7 +20,7 @@
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_PRE_CONNECT) (IPin * iface, IPin * pConnectPin);
typedef HRESULT (*PFN_CLEANUP) (LPVOID iface);
......
......@@ -20,8 +20,12 @@
/* This function will process incoming samples to the pin.
* 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.
* It is allowed to return any error value (within reason), as opposed
......@@ -42,6 +46,17 @@ typedef HRESULT (* PRECONNECTPROC)(IPin * iface, IPin * pConnectPin);
*/
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
{
const struct IPinVtbl * lpVtbl;
......@@ -62,7 +77,7 @@ typedef struct InputPin
const IMemInputPinVtbl * lpVtblMemInput;
IMemAllocator * pAllocator;
SAMPLEPROC fnSampleProc;
SAMPLEPROC_PUSH fnSampleProc;
CLEANUPPROC fnCleanProc;
REFERENCE_TIME tStart;
REFERENCE_TIME tStop;
......@@ -85,30 +100,37 @@ typedef struct PullPin
/* inheritance C style! */
IPinImpl pin;
REFERENCE_TIME rtStart, rtCurrent, rtNext, rtStop;
IAsyncReader * pReader;
IMemAllocator * pAlloc;
SAMPLEPROC fnSampleProc;
SAMPLEPROC_PULL fnSampleProc;
PRECONNECTPROC fnPreConnect;
HANDLE hThread;
HANDLE hEventStateChanged;
REQUESTPROC fnCustomRequest;
CLEANUPPROC fnCleanProc;
REFERENCE_TIME rtStart;
REFERENCE_TIME rtStop;
REFERENCE_TIME rtCurrent;
double dRate;
FILTER_STATE state;
BOOL stop_playback;
DWORD cbAlign;
/* Any code that touches the thread must hold the thread lock,
* 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;
HANDLE hThread;
DWORD requested_state;
HANDLE hEventStateChanged, thread_sleepy;
DWORD state;
} PullPin;
#define Req_Sleepy 0
#define Req_Die 1
#define Req_Run 2
#define Req_Pause 3
/*** 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 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 ***/
......
......@@ -72,7 +72,7 @@ static LONGLONG duration_to_bytepos(WAVEParserImpl *This, LONGLONG duration)
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;
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