[PATCH 4/5] quartz/parser: Store the source pins as an array of Parser_OutputPin pointers.
Zebediah Figura
z.figura12 at gmail.com
Tue Jun 25 20:38:14 CDT 2019
Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
dlls/quartz/avisplit.c | 18 +++------
dlls/quartz/mpegsplit.c | 12 ++----
dlls/quartz/parser.c | 82 ++++++++++++++++++----------------------
dlls/quartz/parser.h | 24 ++++++------
dlls/quartz/waveparser.c | 20 ++++------
5 files changed, 66 insertions(+), 90 deletions(-)
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;
-
- 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);
- }
+ strmbase_source_init(&object->pin, &Parser_OutputPin_Vtbl, pin_info,
+ &output_BaseOutputFuncTable, &filter->filter.csFilter);
- 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)
{
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);
--
2.22.0
More information about the wine-devel
mailing list