Commit 8f4194f3 authored by Zebediah Figura's avatar Zebediah Figura Committed by Alexandre Julliard

quartz/parser: Store the source pins as an array of Parser_OutputPin pointers.

parent e8510660
...@@ -130,20 +130,14 @@ static inline AVISplitterImpl *impl_from_IBaseFilter(IBaseFilter *iface) ...@@ -130,20 +130,14 @@ static inline AVISplitterImpl *impl_from_IBaseFilter(IBaseFilter *iface)
* != S_OK occurs. This means that any error is fatal to processing. * != S_OK occurs. This means that any error is fatal to processing.
*/ */
static HRESULT AVISplitter_SendEndOfFile(AVISplitterImpl *This, DWORD streamnumber) static HRESULT AVISplitter_SendEndOfFile(AVISplitterImpl *filter, DWORD index)
{ {
IPin* ppin = NULL; IPin *peer;
HRESULT hr;
TRACE("End of file reached\n"); TRACE("End of file reached\n");
hr = IPin_ConnectedTo(This->Parser.ppPins[streamnumber], &ppin); if ((peer = filter->Parser.sources[index]->pin.pin.pConnectedTo))
if (SUCCEEDED(hr)) IPin_EndOfStream(peer);
{
hr = IPin_EndOfStream(ppin);
IPin_Release(ppin);
}
TRACE("--> %x\n", hr);
/* Force the pullpin thread to stop */ /* Force the pullpin thread to stop */
return S_FALSE; return S_FALSE;
...@@ -297,7 +291,7 @@ static HRESULT AVISplitter_next_request(AVISplitterImpl *This, DWORD streamnumbe ...@@ -297,7 +291,7 @@ static HRESULT AVISplitter_next_request(AVISplitterImpl *This, DWORD streamnumbe
static HRESULT AVISplitter_Receive(AVISplitterImpl *This, IMediaSample *sample, DWORD streamnumber) static HRESULT AVISplitter_Receive(AVISplitterImpl *This, IMediaSample *sample, DWORD streamnumber)
{ {
Parser_OutputPin *pin = unsafe_impl_Parser_OutputPin_from_IPin(This->Parser.ppPins[streamnumber]); Parser_OutputPin *pin = This->Parser.sources[streamnumber];
HRESULT hr; HRESULT hr;
LONGLONG start, stop, rtstart, rtstop; LONGLONG start, stop, rtstart, rtstop;
StreamData *stream = &This->streams[streamnumber]; StreamData *stream = &This->streams[streamnumber];
...@@ -1292,7 +1286,7 @@ static HRESULT WINAPI AVISplitter_seek(IMediaSeeking *iface) ...@@ -1292,7 +1286,7 @@ static HRESULT WINAPI AVISplitter_seek(IMediaSeeking *iface)
EnterCriticalSection(&This->Parser.filter.csFilter); EnterCriticalSection(&This->Parser.filter.csFilter);
for (x = 0; x < This->Parser.cStreams; ++x) for (x = 0; x < This->Parser.cStreams; ++x)
{ {
Parser_OutputPin *pin = unsafe_impl_Parser_OutputPin_from_IPin(This->Parser.ppPins[x]); Parser_OutputPin *pin = This->Parser.sources[x];
StreamData *stream = This->streams + x; StreamData *stream = This->streams + x;
LONGLONG wanted_frames; LONGLONG wanted_frames;
DWORD last_keyframe = 0, last_keyframeidx = 0, preroll = 0; DWORD last_keyframe = 0, last_keyframeidx = 0, preroll = 0;
......
...@@ -168,7 +168,7 @@ static HRESULT parse_header(BYTE *header, LONGLONG *plen, LONGLONG *pduration) ...@@ -168,7 +168,7 @@ static HRESULT parse_header(BYTE *header, LONGLONG *plen, LONGLONG *pduration)
static HRESULT FillBuffer(MPEGSplitterImpl *This, IMediaSample *pCurrentSample) static HRESULT FillBuffer(MPEGSplitterImpl *This, IMediaSample *pCurrentSample)
{ {
Parser_OutputPin * pOutputPin = unsafe_impl_Parser_OutputPin_from_IPin(This->Parser.ppPins[0]); Parser_OutputPin *pOutputPin = This->Parser.sources[0];
LONGLONG length = 0; LONGLONG length = 0;
LONGLONG pos = BYTES_FROM_MEDIATIME(This->Parser.pInputPin->rtNext); LONGLONG pos = BYTES_FROM_MEDIATIME(This->Parser.pInputPin->rtNext);
LONGLONG time = This->position, rtstop, rtstart; LONGLONG time = This->position, rtstop, rtstart;
...@@ -320,14 +320,10 @@ static HRESULT MPEGSplitter_process_sample(LPVOID iface, IMediaSample * pSample, ...@@ -320,14 +320,10 @@ static HRESULT MPEGSplitter_process_sample(LPVOID iface, IMediaSample * pSample,
for (i = 0; i < This->Parser.cStreams; i++) for (i = 0; i < This->Parser.cStreams; i++)
{ {
IPin* ppin; IPin *peer;
hr = IPin_ConnectedTo(This->Parser.ppPins[i], &ppin); if ((peer = This->Parser.sources[i]->pin.pin.pConnectedTo))
if (SUCCEEDED(hr)) hr = IPin_EndOfStream(peer);
{
hr = IPin_EndOfStream(ppin);
IPin_Release(ppin);
}
if (FAILED(hr)) if (FAILED(hr))
WARN("Error sending EndOfStream to pin %u (%x)\n", i, hr); WARN("Error sending EndOfStream to pin %u (%x)\n", i, hr);
} }
......
...@@ -69,7 +69,7 @@ IPin *parser_get_pin(BaseFilter *iface, unsigned int index) ...@@ -69,7 +69,7 @@ IPin *parser_get_pin(BaseFilter *iface, unsigned int index)
if (!index) if (!index)
return &filter->pInputPin->pin.IPin_iface; return &filter->pInputPin->pin.IPin_iface;
else if (index <= filter->cStreams) else if (index <= filter->cStreams)
return filter->ppPins[index - 1]; return &filter->sources[index - 1]->pin.pin.IPin_iface;
return NULL; return NULL;
} }
...@@ -89,7 +89,7 @@ HRESULT Parser_Create(ParserImpl *pParser, const IBaseFilterVtbl *vtbl, IUnknown ...@@ -89,7 +89,7 @@ HRESULT Parser_Create(ParserImpl *pParser, const IBaseFilterVtbl *vtbl, IUnknown
pParser->fnDisconnect = fnDisconnect; pParser->fnDisconnect = fnDisconnect;
pParser->cStreams = 0; pParser->cStreams = 0;
pParser->ppPins = CoTaskMemAlloc(0 * sizeof(IPin *)); pParser->sources = CoTaskMemAlloc(0 * sizeof(IPin *));
/* construct input pin */ /* construct input pin */
piInput.dir = PINDIR_INPUT; piInput.dir = PINDIR_INPUT;
...@@ -115,7 +115,7 @@ HRESULT Parser_Create(ParserImpl *pParser, const IBaseFilterVtbl *vtbl, IUnknown ...@@ -115,7 +115,7 @@ HRESULT Parser_Create(ParserImpl *pParser, const IBaseFilterVtbl *vtbl, IUnknown
} }
else else
{ {
CoTaskMemFree(pParser->ppPins); CoTaskMemFree(pParser->sources);
strmbase_filter_cleanup(&pParser->filter); strmbase_filter_cleanup(&pParser->filter);
CoTaskMemFree(pParser); CoTaskMemFree(pParser);
} }
...@@ -173,7 +173,7 @@ void Parser_Destroy(ParserImpl *This) ...@@ -173,7 +173,7 @@ void Parser_Destroy(ParserImpl *This)
PullPin_destroy(This->pInputPin); PullPin_destroy(This->pInputPin);
CoTaskMemFree(This->ppPins); CoTaskMemFree(This->sources);
strmbase_filter_cleanup(&This->filter); strmbase_filter_cleanup(&This->filter);
TRACE("Destroying parser\n"); TRACE("Destroying parser\n");
...@@ -207,7 +207,7 @@ HRESULT WINAPI Parser_Stop(IBaseFilter * iface) ...@@ -207,7 +207,7 @@ HRESULT WINAPI Parser_Stop(IBaseFilter * iface)
for (i = 0; i < This->cStreams; ++i) for (i = 0; i < This->cStreams; ++i)
{ {
BaseOutputPinImpl_Inactive((BaseOutputPin *)This->ppPins[i]); BaseOutputPinImpl_Inactive(&This->sources[i]->pin);
} }
LeaveCriticalSection(&This->filter.csFilter); LeaveCriticalSection(&This->filter.csFilter);
...@@ -280,7 +280,7 @@ HRESULT WINAPI Parser_Run(IBaseFilter * iface, REFERENCE_TIME tStart) ...@@ -280,7 +280,7 @@ HRESULT WINAPI Parser_Run(IBaseFilter * iface, REFERENCE_TIME tStart)
for (i = 0; i < This->cStreams; ++i) for (i = 0; i < This->cStreams; ++i)
{ {
hr = BaseOutputPinImpl_Active((BaseOutputPin *)This->ppPins[i]); hr = BaseOutputPinImpl_Active(&This->sources[i]->pin);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
hr_any = hr; hr_any = hr;
} }
...@@ -348,58 +348,48 @@ static const BaseOutputPinFuncTable output_BaseOutputFuncTable = { ...@@ -348,58 +348,48 @@ static const BaseOutputPinFuncTable output_BaseOutputFuncTable = {
Parser_OutputPin_DecideAllocator, Parser_OutputPin_DecideAllocator,
}; };
HRESULT Parser_AddPin(ParserImpl * This, const PIN_INFO * piOutput, ALLOCATOR_PROPERTIES * props, const AM_MEDIA_TYPE * amt) HRESULT Parser_AddPin(ParserImpl *filter, const PIN_INFO *pin_info,
ALLOCATOR_PROPERTIES *props, const AM_MEDIA_TYPE *mt)
{ {
IPin ** ppOldPins; Parser_OutputPin **old_sources;
HRESULT hr; Parser_OutputPin *object;
ppOldPins = This->ppPins; if (!(object = CoTaskMemAlloc(sizeof(*object))))
return E_OUTOFMEMORY;
This->ppPins = CoTaskMemAlloc((This->cStreams + 1) * sizeof(IPin *)); old_sources = filter->sources;
memcpy(This->ppPins, ppOldPins, This->cStreams * sizeof(IPin *));
hr = BaseOutputPin_Construct(&Parser_OutputPin_Vtbl, sizeof(Parser_OutputPin), piOutput, filter->sources = CoTaskMemAlloc((filter->cStreams + 1) * sizeof(filter->sources[0]));
&output_BaseOutputFuncTable, &This->filter.csFilter, &This->ppPins[This->cStreams]); memcpy(filter->sources, old_sources, filter->cStreams * sizeof(filter->sources[0]));
filter->sources[filter->cStreams] = object;
if (SUCCEEDED(hr)) strmbase_source_init(&object->pin, &Parser_OutputPin_Vtbl, pin_info,
{ &output_BaseOutputFuncTable, &filter->filter.csFilter);
IPin *pPin = This->ppPins[This->cStreams];
Parser_OutputPin *pin = unsafe_impl_Parser_OutputPin_from_IPin(pPin);
pin->pmt = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));
CopyMediaType(pin->pmt, amt);
pin->dwSamplesProcessed = 0;
pin->pin.pin.pinInfo.pFilter = &This->filter.IBaseFilter_iface;
pin->allocProps = *props;
This->cStreams++;
BaseFilterImpl_IncrementPinVersion(&This->filter);
CoTaskMemFree(ppOldPins);
}
else
{
CoTaskMemFree(This->ppPins);
This->ppPins = ppOldPins;
ERR("Failed with error %x\n", hr);
}
return hr; object->pmt = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));
CopyMediaType(object->pmt, mt);
object->dwSamplesProcessed = 0;
object->pin.pin.pinInfo.pFilter = &filter->filter.IBaseFilter_iface;
object->allocProps = *props;
filter->cStreams++;
BaseFilterImpl_IncrementPinVersion(&filter->filter);
CoTaskMemFree(old_sources);
return S_OK;
} }
static void free_source_pin(IPin *iface) static void free_source_pin(Parser_OutputPin *pin)
{ {
Parser_OutputPin *pin = unsafe_impl_Parser_OutputPin_from_IPin(iface);
if (pin->pin.pin.pConnectedTo) if (pin->pin.pin.pConnectedTo)
{ {
IPin_Disconnect(pin->pin.pin.pConnectedTo); IPin_Disconnect(pin->pin.pin.pConnectedTo);
IPin_Disconnect(iface); IPin_Disconnect(&pin->pin.pin.IPin_iface);
} }
FreeMediaType(pin->pmt); FreeMediaType(pin->pmt);
CoTaskMemFree(pin->pmt); CoTaskMemFree(pin->pmt);
FreeMediaType(&pin->pin.pin.mtCurrent); strmbase_source_cleanup(&pin->pin);
if (pin->pin.pAllocator)
IMemAllocator_Release(pin->pin.pAllocator);
CoTaskMemFree(pin); CoTaskMemFree(pin);
} }
...@@ -407,18 +397,18 @@ static HRESULT Parser_RemoveOutputPins(ParserImpl * This) ...@@ -407,18 +397,18 @@ static HRESULT Parser_RemoveOutputPins(ParserImpl * This)
{ {
/* NOTE: should be in critical section when calling this function */ /* NOTE: should be in critical section when calling this function */
ULONG i; ULONG i;
IPin ** ppOldPins = This->ppPins; Parser_OutputPin **old_sources = This->sources;
TRACE("(%p)\n", This); TRACE("(%p)\n", This);
This->ppPins = CoTaskMemAlloc(0); This->sources = CoTaskMemAlloc(0);
for (i = 0; i < This->cStreams; i++) for (i = 0; i < This->cStreams; i++)
free_source_pin(ppOldPins[i]); free_source_pin(old_sources[i]);
BaseFilterImpl_IncrementPinVersion(&This->filter); BaseFilterImpl_IncrementPinVersion(&This->filter);
This->cStreams = 0; This->cStreams = 0;
CoTaskMemFree(ppOldPins); CoTaskMemFree(old_sources);
return S_OK; return S_OK;
} }
......
...@@ -26,18 +26,6 @@ typedef HRESULT (*PFN_PRE_CONNECT) (IPin * iface, IPin * pConnectPin, ALLOCATOR_ ...@@ -26,18 +26,6 @@ typedef HRESULT (*PFN_PRE_CONNECT) (IPin * iface, IPin * pConnectPin, ALLOCATOR_
typedef HRESULT (*PFN_CLEANUP) (LPVOID iface); typedef HRESULT (*PFN_CLEANUP) (LPVOID iface);
typedef HRESULT (*PFN_DISCONNECT) (LPVOID iface); typedef HRESULT (*PFN_DISCONNECT) (LPVOID iface);
struct ParserImpl
{
BaseFilter filter;
PFN_DISCONNECT fnDisconnect;
PullPin * pInputPin;
IPin ** ppPins;
ULONG cStreams;
SourceSeeking sourceSeeking;
};
typedef struct Parser_OutputPin typedef struct Parser_OutputPin
{ {
BaseOutputPin pin; BaseOutputPin pin;
...@@ -50,6 +38,18 @@ typedef struct Parser_OutputPin ...@@ -50,6 +38,18 @@ typedef struct Parser_OutputPin
BOOL readonly; BOOL readonly;
} Parser_OutputPin; } Parser_OutputPin;
struct ParserImpl
{
BaseFilter filter;
PFN_DISCONNECT fnDisconnect;
PullPin *pInputPin;
Parser_OutputPin **sources;
ULONG cStreams;
SourceSeeking sourceSeeking;
};
extern HRESULT Parser_AddPin(ParserImpl * This, const PIN_INFO * piOutput, ALLOCATOR_PROPERTIES * props, const AM_MEDIA_TYPE * amt); extern HRESULT Parser_AddPin(ParserImpl * This, const PIN_INFO * piOutput, ALLOCATOR_PROPERTIES * props, const AM_MEDIA_TYPE * amt);
HRESULT Parser_Create(ParserImpl *parser, const IBaseFilterVtbl *vtbl, IUnknown *outer, HRESULT Parser_Create(ParserImpl *parser, const IBaseFilterVtbl *vtbl, IUnknown *outer,
......
...@@ -102,7 +102,7 @@ static HRESULT WAVEParser_Sample(LPVOID iface, IMediaSample * pSample, DWORD_PTR ...@@ -102,7 +102,7 @@ static HRESULT WAVEParser_Sample(LPVOID iface, IMediaSample * pSample, DWORD_PTR
return S_OK; return S_OK;
} }
pOutputPin = unsafe_impl_Parser_OutputPin_from_IPin(This->Parser.ppPins[0]); pOutputPin = This->Parser.sources[0];
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
hr = IMemAllocator_GetBuffer(pin->pAlloc, &newsample, NULL, NULL, 0); hr = IMemAllocator_GetBuffer(pin->pAlloc, &newsample, NULL, NULL, 0);
...@@ -161,7 +161,7 @@ static HRESULT WAVEParser_Sample(LPVOID iface, IMediaSample * pSample, DWORD_PTR ...@@ -161,7 +161,7 @@ static HRESULT WAVEParser_Sample(LPVOID iface, IMediaSample * pSample, DWORD_PTR
TRACE("Send End Of Stream to output pin %u\n", i); TRACE("Send End Of Stream to output pin %u\n", i);
hr = IPin_ConnectedTo(This->Parser.ppPins[i], &ppin); hr = IPin_ConnectedTo(&This->Parser.sources[i]->pin.pin.IPin_iface, &ppin);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = IPin_EndOfStream(ppin); hr = IPin_EndOfStream(ppin);
...@@ -196,8 +196,8 @@ static HRESULT WINAPI WAVEParserImpl_seek(IMediaSeeking *iface) ...@@ -196,8 +196,8 @@ static HRESULT WINAPI WAVEParserImpl_seek(IMediaSeeking *iface)
{ {
WAVEParserImpl *This = impl_from_IMediaSeeking(iface); WAVEParserImpl *This = impl_from_IMediaSeeking(iface);
PullPin *pPin = This->Parser.pInputPin; PullPin *pPin = This->Parser.pInputPin;
IPin *victim = NULL;
LONGLONG newpos, curpos, endpos, bytepos; LONGLONG newpos, curpos, endpos, bytepos;
IPin *peer;
newpos = This->Parser.sourceSeeking.llCurrent; newpos = This->Parser.sourceSeeking.llCurrent;
curpos = bytepos_to_duration(This, pPin->rtCurrent); curpos = bytepos_to_duration(This, pPin->rtCurrent);
...@@ -225,15 +225,12 @@ static HRESULT WINAPI WAVEParserImpl_seek(IMediaSeeking *iface) ...@@ -225,15 +225,12 @@ static HRESULT WINAPI WAVEParserImpl_seek(IMediaSeeking *iface)
/* Make sure this is done while stopped, BeginFlush takes care of this */ /* Make sure this is done while stopped, BeginFlush takes care of this */
EnterCriticalSection(&This->Parser.filter.csFilter); EnterCriticalSection(&This->Parser.filter.csFilter);
IPin_ConnectedTo(This->Parser.ppPins[0], &victim);
if (victim) if ((peer = This->Parser.sources[0]->pin.pin.pConnectedTo))
{ IPin_NewSegment(peer, newpos, endpos, pPin->dRate);
IPin_NewSegment(victim, newpos, endpos, pPin->dRate);
IPin_Release(victim);
}
pPin->rtStart = pPin->rtCurrent = bytepos; pPin->rtStart = pPin->rtCurrent = bytepos;
unsafe_impl_Parser_OutputPin_from_IPin(This->Parser.ppPins[0])->dwSamplesProcessed = 0; This->Parser.sources[0]->dwSamplesProcessed = 0;
LeaveCriticalSection(&This->Parser.filter.csFilter); LeaveCriticalSection(&This->Parser.filter.csFilter);
TRACE("Done flushing\n"); TRACE("Done flushing\n");
...@@ -364,7 +361,6 @@ static HRESULT WAVEParser_first_request(LPVOID iface) ...@@ -364,7 +361,6 @@ static HRESULT WAVEParser_first_request(LPVOID iface)
LONGLONG rtSampleStart = pin->rtNext; LONGLONG rtSampleStart = pin->rtNext;
/* Add 4 for the next header, which should hopefully work */ /* Add 4 for the next header, which should hopefully work */
LONGLONG rtSampleStop = rtSampleStart + MEDIATIME_FROM_BYTES(IMediaSample_GetSize(sample)); LONGLONG rtSampleStop = rtSampleStart + MEDIATIME_FROM_BYTES(IMediaSample_GetSize(sample));
Parser_OutputPin *outpin = unsafe_impl_Parser_OutputPin_from_IPin(This->Parser.ppPins[0]);
if (rtSampleStop > pin->rtStop) if (rtSampleStop > pin->rtStop)
rtSampleStop = MEDIATIME_FROM_BYTES(ALIGNUP(BYTES_FROM_MEDIATIME(pin->rtStop), pin->cbAlign)); rtSampleStop = MEDIATIME_FROM_BYTES(ALIGNUP(BYTES_FROM_MEDIATIME(pin->rtStop), pin->cbAlign));
...@@ -375,7 +371,7 @@ static HRESULT WAVEParser_first_request(LPVOID iface) ...@@ -375,7 +371,7 @@ static HRESULT WAVEParser_first_request(LPVOID iface)
pin->rtNext = rtSampleStop; pin->rtNext = rtSampleStop;
IMediaSample_SetPreroll(sample, FALSE); IMediaSample_SetPreroll(sample, FALSE);
if (!outpin->dwSamplesProcessed++) if (!This->Parser.sources[0]->dwSamplesProcessed++)
IMediaSample_SetDiscontinuity(sample, TRUE); IMediaSample_SetDiscontinuity(sample, TRUE);
else else
IMediaSample_SetDiscontinuity(sample, FALSE); IMediaSample_SetDiscontinuity(sample, FALSE);
......
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