[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