diff --git a/dlls/quartz/avisplit.c b/dlls/quartz/avisplit.c index aa43e0131e8..dcaefc528b9 100644 --- a/dlls/quartz/avisplit.c +++ b/dlls/quartz/avisplit.c @@ -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; diff --git a/dlls/quartz/mpegsplit.c b/dlls/quartz/mpegsplit.c index f80ab1cb210..3bfff9f7b44 100644 --- a/dlls/quartz/mpegsplit.c +++ b/dlls/quartz/mpegsplit.c @@ -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); } diff --git a/dlls/quartz/parser.c b/dlls/quartz/parser.c index 6c8ddf80f47..ca3a94f1740 100644 --- a/dlls/quartz/parser.c +++ b/dlls/quartz/parser.c @@ -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; } diff --git a/dlls/quartz/parser.h b/dlls/quartz/parser.h index 8909c4da798..95b98d1f74d 100644 --- a/dlls/quartz/parser.h +++ b/dlls/quartz/parser.h @@ -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, diff --git a/dlls/quartz/waveparser.c b/dlls/quartz/waveparser.c index 5b2608ac88e..0ab2388da45 100644 --- a/dlls/quartz/waveparser.c +++ b/dlls/quartz/waveparser.c @@ -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);