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>
This commit is contained in:
parent
e8510660e6
commit
8f4194f311
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue