Commit 3a39805e authored by Maarten Lankhorst's avatar Maarten Lankhorst Committed by Alexandre Julliard

quartz: Make wave parser and mpeg splitter zero copy by getting rid of the…

quartz: Make wave parser and mpeg splitter zero copy by getting rid of the seperate allocator for the output pin.
parent ec124be8
......@@ -813,7 +813,7 @@ static HRESULT AVISplitter_InitializeStreams(AVISplitterImpl *This)
static HRESULT AVISplitter_Disconnect(LPVOID iface);
/* FIXME: fix leaks on failure here */
static HRESULT AVISplitter_InputPin_PreConnect(IPin * iface, IPin * pConnectPin)
static HRESULT AVISplitter_InputPin_PreConnect(IPin * iface, IPin * pConnectPin, ALLOCATOR_PROPERTIES *props)
{
PullPin *This = (PullPin *)iface;
HRESULT hr;
......@@ -918,7 +918,8 @@ static HRESULT AVISplitter_InputPin_PreConnect(IPin * iface, IPin * pConnectPin)
IAsyncReader_Length(This->pReader, &total, &avail);
/* FIXME: AVIX files are added ("eXtended") beyond the "AVI" length, and thus won't be played here */
/* FIXME: AVIX files are extended beyond the FOURCC chunk "AVI ", and thus won't be played here,
* once I get one of the files I'll try to fix it */
if (hr == S_OK)
{
This->rtStart = pAviSplit->CurrentChunkOffset = MEDIATIME_FROM_BYTES(pos + sizeof(RIFFLIST));
......@@ -1060,7 +1061,7 @@ HRESULT AVISplitter_create(IUnknown * pUnkOuter, LPVOID * ppv)
This->streams = NULL;
This->oldindex = NULL;
hr = Parser_Create(&(This->Parser), &CLSID_AviSplitter, AVISplitter_Sample, AVISplitter_QueryAccept, AVISplitter_InputPin_PreConnect, AVISplitter_Cleanup, AVISplitter_Disconnect, NULL, NULL, NULL);
hr = Parser_Create(&(This->Parser), &CLSID_AviSplitter, AVISplitter_Sample, AVISplitter_QueryAccept, AVISplitter_InputPin_PreConnect, AVISplitter_Cleanup, AVISplitter_Disconnect, NULL, NULL, NULL, NULL);
if (FAILED(hr))
return hr;
......
......@@ -53,7 +53,7 @@ static inline ParserImpl *impl_from_IMediaSeeking( IMediaSeeking *iface )
}
HRESULT Parser_Create(ParserImpl* pParser, const CLSID* pClsid, PFN_PROCESS_SAMPLE fnProcessSample, PFN_QUERY_ACCEPT fnQueryAccept, PFN_PRE_CONNECT fnPreConnect, PFN_CLEANUP fnCleanup, PFN_DISCONNECT fnDisconnect, CHANGEPROC stop, CHANGEPROC current, CHANGEPROC rate)
HRESULT Parser_Create(ParserImpl* pParser, const CLSID* pClsid, PFN_PROCESS_SAMPLE fnProcessSample, PFN_QUERY_ACCEPT fnQueryAccept, PFN_PRE_CONNECT fnPreConnect, PFN_CLEANUP fnCleanup, PFN_DISCONNECT fnDisconnect, REQUESTPROC fnRequest, CHANGEPROC stop, CHANGEPROC current, CHANGEPROC rate)
{
HRESULT hr;
PIN_INFO piInput;
......@@ -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, NULL, &pParser->csFilter, (IPin **)&pParser->pInputPin);
hr = PullPin_Construct(&Parser_InputPin_Vtbl, &piInput, fnProcessSample, (LPVOID)pParser, fnQueryAccept, fnCleanup, fnRequest, &pParser->csFilter, (IPin **)&pParser->pInputPin);
if (SUCCEEDED(hr))
{
......@@ -489,6 +489,8 @@ HRESULT Parser_AddPin(ParserImpl * This, const PIN_INFO * piOutput, ALLOCATOR_PR
pin->dwSamplesProcessed = 0;
pin->pin.pin.pUserData = (LPVOID)This->ppPins[This->cStreams + 1];
pin->pin.pin.pinInfo.pFilter = (LPVOID)This;
pin->pin.custom_allocator = 1;
This->cStreams++;
CoTaskMemFree(ppOldPins);
}
......@@ -649,6 +651,19 @@ static HRESULT WINAPI Parser_OutputPin_EnumMediaTypes(IPin * iface, IEnumMediaTy
return IEnumMediaTypesImpl_Construct(&emd, ppEnum);
}
static HRESULT WINAPI Parser_OutputPin_Connect(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt)
{
Parser_OutputPin *This = (Parser_OutputPin *)iface;
ParserImpl *parser = (ParserImpl *)This->pin.pin.pinInfo.pFilter;
/* Set the allocator to our input pin's */
EnterCriticalSection(This->pin.pin.pCritSec);
This->pin.alloc = parser->pInputPin->pAlloc;
LeaveCriticalSection(This->pin.pin.pCritSec);
return OutputPin_Connect(iface, pReceivePin, pmt);
}
static HRESULT Parser_OutputPin_QueryAccept(LPVOID iface, const AM_MEDIA_TYPE * pmt)
{
Parser_OutputPin *This = (Parser_OutputPin *)iface;
......@@ -664,7 +679,7 @@ static const IPinVtbl Parser_OutputPin_Vtbl =
Parser_OutputPin_QueryInterface,
IPinImpl_AddRef,
Parser_OutputPin_Release,
OutputPin_Connect,
Parser_OutputPin_Connect,
OutputPin_ReceiveConnection,
OutputPin_Disconnect,
IPinImpl_ConnectedTo,
......@@ -692,6 +707,7 @@ static HRESULT WINAPI Parser_PullPin_Disconnect(IPin * iface)
{
if (This->pConnectedTo)
{
PullPin *ppin = (PullPin *)This;
FILTER_STATE state;
ParserImpl *Parser = (ParserImpl *)This->pinInfo.pFilter;
......@@ -701,6 +717,8 @@ static HRESULT WINAPI Parser_PullPin_Disconnect(IPin * iface)
{
IPin_Release(This->pConnectedTo);
This->pConnectedTo = NULL;
if (FAILED(hr = IMemAllocator_Decommit(ppin->pAlloc)))
ERR("Allocator decommit failed with error %x. Possible memory leak\n", hr);
hr = Parser_RemoveOutputPins((ParserImpl *)This->pinInfo.pFilter);
}
else
......@@ -738,7 +756,7 @@ static const IPinVtbl Parser_InputPin_Vtbl =
PullPin_QueryInterface,
IPinImpl_AddRef,
PullPin_Release,
OutputPin_Connect,
InputPin_Connect,
Parser_PullPin_ReceiveConnection,
Parser_PullPin_Disconnect,
IPinImpl_ConnectedTo,
......
......@@ -22,7 +22,7 @@ typedef struct ParserImpl ParserImpl;
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_PRE_CONNECT) (IPin * iface, IPin * pConnectPin, ALLOCATOR_PROPERTIES *prop);
typedef HRESULT (*PFN_CLEANUP) (LPVOID iface);
typedef HRESULT (*PFN_DISCONNECT) (LPVOID iface);
......@@ -57,4 +57,4 @@ typedef struct Parser_OutputPin
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, PFN_DISCONNECT, CHANGEPROC stop, CHANGEPROC current, CHANGEPROC rate);
PFN_CLEANUP, PFN_DISCONNECT, REQUESTPROC, CHANGEPROC stop, CHANGEPROC current, CHANGEPROC rate);
......@@ -36,8 +36,10 @@ typedef HRESULT (* QUERYACCEPTPROC)(LPVOID userdata, const AM_MEDIA_TYPE * pmt);
/* This function is called prior to finalizing a connection with
* another pin and can be used to get things from the other pin
* like IMemInput interfaces.
*
* props contains some defaults, but you can safely override them to your liking
*/
typedef HRESULT (* PRECONNECTPROC)(IPin * iface, IPin * pConnectPin);
typedef HRESULT (* PRECONNECTPROC)(IPin * iface, IPin * pConnectPin, ALLOCATOR_PROPERTIES *props);
/* This function is called whenever a cleanup operation has to occur,
* this is usually after a flush, seek, or end of stream notification.
......@@ -57,6 +59,9 @@ typedef HRESULT (* CLEANUPPROC) (LPVOID userdata);
*/
typedef HRESULT (* REQUESTPROC) (LPVOID userdata);
#define ALIGNDOWN(value,boundary) ((value)/(boundary)*(boundary))
#define ALIGNUP(value,boundary) (ALIGNDOWN((value)+(boundary)-1, (boundary)))
typedef struct IPinImpl
{
const struct IPinVtbl * lpVtbl;
......@@ -92,6 +97,9 @@ typedef struct OutputPin
IMemInputPin * pMemInputPin;
HRESULT (* pConnectSpecific)(IPin * iface, IPin * pReceiver, const AM_MEDIA_TYPE * pmt);
BOOL custom_allocator;
IMemAllocator *alloc;
BOOL readonly;
ALLOCATOR_PROPERTIES allocProps;
} OutputPin;
......
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