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

Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
stable
Zebediah Figura 2019-06-25 20:38:14 -05:00 committed by Alexandre Julliard
parent e8510660e6
commit 8f4194f311
5 changed files with 65 additions and 89 deletions

View File

@ -130,20 +130,14 @@ static inline AVISplitterImpl *impl_from_IBaseFilter(IBaseFilter *iface)
* != 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;
HRESULT hr;
IPin *peer;
TRACE("End of file reached\n");
hr = IPin_ConnectedTo(This->Parser.ppPins[streamnumber], &ppin);
if (SUCCEEDED(hr))
{
hr = IPin_EndOfStream(ppin);
IPin_Release(ppin);
}
TRACE("--> %x\n", hr);
if ((peer = filter->Parser.sources[index]->pin.pin.pConnectedTo))
IPin_EndOfStream(peer);
/* Force the pullpin thread to stop */
return S_FALSE;
@ -297,7 +291,7 @@ static HRESULT AVISplitter_next_request(AVISplitterImpl *This, DWORD streamnumbe
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;
LONGLONG start, stop, rtstart, rtstop;
StreamData *stream = &This->streams[streamnumber];
@ -1292,7 +1286,7 @@ static HRESULT WINAPI AVISplitter_seek(IMediaSeeking *iface)
EnterCriticalSection(&This->Parser.filter.csFilter);
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;
LONGLONG wanted_frames;
DWORD last_keyframe = 0, last_keyframeidx = 0, preroll = 0;

View File

@ -168,7 +168,7 @@ static HRESULT parse_header(BYTE *header, LONGLONG *plen, LONGLONG *pduration)
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 pos = BYTES_FROM_MEDIATIME(This->Parser.pInputPin->rtNext);
LONGLONG time = This->position, rtstop, rtstart;
@ -320,14 +320,10 @@ static HRESULT MPEGSplitter_process_sample(LPVOID iface, IMediaSample * pSample,
for (i = 0; i < This->Parser.cStreams; i++)
{
IPin* ppin;
IPin *peer;
hr = IPin_ConnectedTo(This->Parser.ppPins[i], &ppin);
if (SUCCEEDED(hr))
{
hr = IPin_EndOfStream(ppin);
IPin_Release(ppin);
}
if ((peer = This->Parser.sources[i]->pin.pin.pConnectedTo))
hr = IPin_EndOfStream(peer);
if (FAILED(hr))
WARN("Error sending EndOfStream to pin %u (%x)\n", i, hr);
}

View File

@ -69,7 +69,7 @@ IPin *parser_get_pin(BaseFilter *iface, unsigned int index)
if (!index)
return &filter->pInputPin->pin.IPin_iface;
else if (index <= filter->cStreams)
return filter->ppPins[index - 1];
return &filter->sources[index - 1]->pin.pin.IPin_iface;
return NULL;
}
@ -89,7 +89,7 @@ HRESULT Parser_Create(ParserImpl *pParser, const IBaseFilterVtbl *vtbl, IUnknown
pParser->fnDisconnect = fnDisconnect;
pParser->cStreams = 0;
pParser->ppPins = CoTaskMemAlloc(0 * sizeof(IPin *));
pParser->sources = CoTaskMemAlloc(0 * sizeof(IPin *));
/* construct input pin */
piInput.dir = PINDIR_INPUT;
@ -115,7 +115,7 @@ HRESULT Parser_Create(ParserImpl *pParser, const IBaseFilterVtbl *vtbl, IUnknown
}
else
{
CoTaskMemFree(pParser->ppPins);
CoTaskMemFree(pParser->sources);
strmbase_filter_cleanup(&pParser->filter);
CoTaskMemFree(pParser);
}
@ -173,7 +173,7 @@ void Parser_Destroy(ParserImpl *This)
PullPin_destroy(This->pInputPin);
CoTaskMemFree(This->ppPins);
CoTaskMemFree(This->sources);
strmbase_filter_cleanup(&This->filter);
TRACE("Destroying parser\n");
@ -207,7 +207,7 @@ HRESULT WINAPI Parser_Stop(IBaseFilter * iface)
for (i = 0; i < This->cStreams; ++i)
{
BaseOutputPinImpl_Inactive((BaseOutputPin *)This->ppPins[i]);
BaseOutputPinImpl_Inactive(&This->sources[i]->pin);
}
LeaveCriticalSection(&This->filter.csFilter);
@ -280,7 +280,7 @@ HRESULT WINAPI Parser_Run(IBaseFilter * iface, REFERENCE_TIME tStart)
for (i = 0; i < This->cStreams; ++i)
{
hr = BaseOutputPinImpl_Active((BaseOutputPin *)This->ppPins[i]);
hr = BaseOutputPinImpl_Active(&This->sources[i]->pin);
if (SUCCEEDED(hr))
hr_any = hr;
}
@ -348,58 +348,48 @@ static const BaseOutputPinFuncTable output_BaseOutputFuncTable = {
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;
HRESULT hr;
Parser_OutputPin **old_sources;
Parser_OutputPin *object;
ppOldPins = This->ppPins;
if (!(object = CoTaskMemAlloc(sizeof(*object))))
return E_OUTOFMEMORY;
This->ppPins = CoTaskMemAlloc((This->cStreams + 1) * sizeof(IPin *));
memcpy(This->ppPins, ppOldPins, This->cStreams * sizeof(IPin *));
old_sources = filter->sources;
hr = BaseOutputPin_Construct(&Parser_OutputPin_Vtbl, sizeof(Parser_OutputPin), piOutput,
&output_BaseOutputFuncTable, &This->filter.csFilter, &This->ppPins[This->cStreams]);
filter->sources = CoTaskMemAlloc((filter->cStreams + 1) * sizeof(filter->sources[0]));
memcpy(filter->sources, old_sources, filter->cStreams * sizeof(filter->sources[0]));
filter->sources[filter->cStreams] = object;
if (SUCCEEDED(hr))
{
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;
strmbase_source_init(&object->pin, &Parser_OutputPin_Vtbl, pin_info,
&output_BaseOutputFuncTable, &filter->filter.csFilter);
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);
}
object->pmt = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));
CopyMediaType(object->pmt, mt);
object->dwSamplesProcessed = 0;
return hr;
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)
{
IPin_Disconnect(pin->pin.pin.pConnectedTo);
IPin_Disconnect(iface);
IPin_Disconnect(&pin->pin.pin.IPin_iface);
}
FreeMediaType(pin->pmt);
CoTaskMemFree(pin->pmt);
FreeMediaType(&pin->pin.pin.mtCurrent);
if (pin->pin.pAllocator)
IMemAllocator_Release(pin->pin.pAllocator);
strmbase_source_cleanup(&pin->pin);
CoTaskMemFree(pin);
}
@ -407,18 +397,18 @@ static HRESULT Parser_RemoveOutputPins(ParserImpl * This)
{
/* NOTE: should be in critical section when calling this function */
ULONG i;
IPin ** ppOldPins = This->ppPins;
Parser_OutputPin **old_sources = This->sources;
TRACE("(%p)\n", This);
This->ppPins = CoTaskMemAlloc(0);
This->sources = CoTaskMemAlloc(0);
for (i = 0; i < This->cStreams; i++)
free_source_pin(ppOldPins[i]);
free_source_pin(old_sources[i]);
BaseFilterImpl_IncrementPinVersion(&This->filter);
This->cStreams = 0;
CoTaskMemFree(ppOldPins);
CoTaskMemFree(old_sources);
return S_OK;
}

View File

@ -26,18 +26,6 @@ typedef HRESULT (*PFN_PRE_CONNECT) (IPin * iface, IPin * pConnectPin, ALLOCATOR_
typedef HRESULT (*PFN_CLEANUP) (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
{
BaseOutputPin pin;
@ -50,6 +38,18 @@ typedef struct Parser_OutputPin
BOOL readonly;
} 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);
HRESULT Parser_Create(ParserImpl *parser, const IBaseFilterVtbl *vtbl, IUnknown *outer,

View File

@ -102,7 +102,7 @@ static HRESULT WAVEParser_Sample(LPVOID iface, IMediaSample * pSample, DWORD_PTR
return S_OK;
}
pOutputPin = unsafe_impl_Parser_OutputPin_from_IPin(This->Parser.ppPins[0]);
pOutputPin = This->Parser.sources[0];
if (SUCCEEDED(hr))
hr = IMemAllocator_GetBuffer(pin->pAlloc, &newsample, NULL, NULL, 0);
@ -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);
hr = IPin_ConnectedTo(This->Parser.ppPins[i], &ppin);
hr = IPin_ConnectedTo(&This->Parser.sources[i]->pin.pin.IPin_iface, &ppin);
if (SUCCEEDED(hr))
{
hr = IPin_EndOfStream(ppin);
@ -196,8 +196,8 @@ static HRESULT WINAPI WAVEParserImpl_seek(IMediaSeeking *iface)
{
WAVEParserImpl *This = impl_from_IMediaSeeking(iface);
PullPin *pPin = This->Parser.pInputPin;
IPin *victim = NULL;
LONGLONG newpos, curpos, endpos, bytepos;
IPin *peer;
newpos = This->Parser.sourceSeeking.llCurrent;
curpos = bytepos_to_duration(This, pPin->rtCurrent);
@ -225,15 +225,12 @@ static HRESULT WINAPI WAVEParserImpl_seek(IMediaSeeking *iface)
/* Make sure this is done while stopped, BeginFlush takes care of this */
EnterCriticalSection(&This->Parser.filter.csFilter);
IPin_ConnectedTo(This->Parser.ppPins[0], &victim);
if (victim)
{
IPin_NewSegment(victim, newpos, endpos, pPin->dRate);
IPin_Release(victim);
}
if ((peer = This->Parser.sources[0]->pin.pin.pConnectedTo))
IPin_NewSegment(peer, newpos, endpos, pPin->dRate);
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);
TRACE("Done flushing\n");
@ -364,7 +361,6 @@ static HRESULT WAVEParser_first_request(LPVOID iface)
LONGLONG rtSampleStart = pin->rtNext;
/* Add 4 for the next header, which should hopefully work */
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)
rtSampleStop = MEDIATIME_FROM_BYTES(ALIGNUP(BYTES_FROM_MEDIATIME(pin->rtStop), pin->cbAlign));
@ -375,7 +371,7 @@ static HRESULT WAVEParser_first_request(LPVOID iface)
pin->rtNext = rtSampleStop;
IMediaSample_SetPreroll(sample, FALSE);
if (!outpin->dwSamplesProcessed++)
if (!This->Parser.sources[0]->dwSamplesProcessed++)
IMediaSample_SetDiscontinuity(sample, TRUE);
else
IMediaSample_SetDiscontinuity(sample, FALSE);