[QUARTZ] Some stuff to start the graph

Robert Shearman rob at codeweavers.com
Wed Dec 29 04:27:42 CST 2004


Christian Costa wrote:

> Hi,
>
> Changelog:
> Implemented IMediaControl_Run that explores the graph, counts 
> renderers and starts filters.
> Better implementation of IBaseFilter_Run for AVI SPlitter and AVI 
> Decompressor.
> Use the standard memory allocator when an output pin does not provide 
> any allocator.
> Set allocator properties for AVI Decompressor output pin and update 
> the buffers size at connection time.
>
> Christian Costa   titan.costa at wanadoo.fr
>
>------------------------------------------------------------------------
>
>Index: dlls/quartz/avidec.c
>===================================================================
>RCS file: /home/wine/wine/dlls/quartz/avidec.c,v
>retrieving revision 1.12
>diff -u -r1.12 avidec.c
>--- dlls/quartz/avidec.c	27 Dec 2004 17:15:58 -0000	1.12
>+++ dlls/quartz/avidec.c	29 Dec 2004 09:06:24 -0000
>@@ -235,6 +235,9 @@
>             pAVIDec->pBihOut->biCompression = 0;
>             pAVIDec->pBihOut->biSizeImage = pAVIDec->pBihOut->biWidth * pAVIDec->pBihOut->biHeight * pAVIDec->pBihOut->biBitCount / 8;
> 
>+            /* Update buffer size of media samples in output */
>+            ((OutputPin*)pAVIDec->ppPins[1])->allocProps.cbBuffer = pAVIDec->pBihOut->biSizeImage;
>+	    
>             pAVIDec->init = 1;
>             TRACE("Connection accepted\n");
>             return S_OK;
>@@ -354,7 +357,13 @@
> 
>     if (SUCCEEDED(hr))
>     {
>-        hr = AVIDec_OutputPin_Construct(&piOutput, NULL, NULL, AVIDec_Output_QueryAccept, &pAVIDec->csFilter, &pAVIDec->ppPins[1]);
>+        ALLOCATOR_PROPERTIES props;
>+        props.cbAlign = 1;
>+        props.cbPrefix = 0;
>+        props.cbBuffer = 0; /* Will be updated at connection time */
>+        props.cBuffers = 2;
>+	
>+        hr = AVIDec_OutputPin_Construct(&piOutput, &props, NULL, AVIDec_Output_QueryAccept, &pAVIDec->csFilter, &pAVIDec->ppPins[1]);
> 
> 	if (FAILED(hr))
> 	    ERR("Cannot create output pin (%lx)\n", hr);
>@@ -502,6 +511,8 @@
>         This->state = State_Running;
>     }
>     LeaveCriticalSection(&This->csFilter);
>+
>+    OutputPin_CommitAllocator((OutputPin *)This->ppPins[1]);
>  
>

This needs to be inside the critical section.

> 
>     return hr;
> }
>Index: dlls/quartz/avisplit.c
>===================================================================
>RCS file: /home/wine/wine/dlls/quartz/avisplit.c,v
>retrieving revision 1.10
>diff -u -r1.10 avisplit.c
>--- dlls/quartz/avisplit.c	27 Dec 2004 17:15:58 -0000	1.10
>+++ dlls/quartz/avisplit.c	29 Dec 2004 09:06:26 -0000
>@@ -327,6 +327,7 @@
> {
>     HRESULT hr = S_OK;
>     AVISplitter *This = (AVISplitter *)iface;
>+    int i;
> 
>     TRACE("(%s)\n", wine_dbgstr_longlong(tStart));
> 
>@@ -337,6 +338,17 @@
>     }
>     LeaveCriticalSection(&This->csFilter);
> 
>+    hr = PullPin_InitProcessing(This->pInputPin);
>+
>+    if (SUCCEEDED(hr))
>+    { 
>+        for (i = 1; i < This->cStreams + 1; i++)
>+        {
>+            OutputPin_CommitAllocator((OutputPin *)This->ppPins[i]);
>+        }
>+        hr = PullPin_StartProcessing(This->pInputPin);
>+    }
>+
>     return hr;
> }
>  
>

And so does this.

...

> /*** IMediaControl methods ***/
> static HRESULT WINAPI Mediacontrol_Run(IMediaControl *iface) {
>     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
>+    int i;
>+    IBaseFilter* pfilter;
>+    IEnumPins* pEnum;
>+    HRESULT hr;
>+    IPin* pPin;
>+    LONG dummy;
>+    PIN_DIRECTION dir;
> 
>-    TRACE("(%p/%p)->(): stub !!!\n", This, iface);
>+    TRACE("(%p/%p)->()\n", This, iface);
> 
>+    if (This->state == State_Running)
>+        return S_OK;
>+
>+    /* Explorer the graph from source filters to renderers, determine renderers number and
>+     * run filters from renderers to source filters */
>+    This->nRenderers = 0;  
>     ResetEvent(This->hEventCompletion);
> 
>+    for(i = 0; i < This->nFilters; i++)
>+    {
>+        BOOL source = TRUE;
>+        pfilter = This->ppFiltersInGraph[i];
>+        hr = IBaseFilter_EnumPins(pfilter, &pEnum);
>+        if (hr != S_OK)
>+        {
>+            ERR("Enum pins failed %lx\n", hr);
>+            continue;
>+        }
>+        /* Check if it is a source filter */
>+        while(IEnumPins_Next(pEnum, 1, &pPin, &dummy) == S_OK)
>+        {
>+            IPin_QueryDirection(pPin, &dir);
>+            if (dir == PINDIR_INPUT)
>+            {
>+                source = FALSE;
>+                break;
>+            }
>+        }
>+        if (source == TRUE)
>+        {
>+            TRACE("Found a source filter\n");
>+            IEnumPins_Reset(pEnum);
>+            while(IEnumPins_Next(pEnum, 1, &pPin, &dummy) == S_OK)
>+            {
>+                /* Explore the graph downstream from this pin */
>+                ExploreGraph(This, pPin, 0);
>+            }
>+            IBaseFilter_Run(pfilter, 0);
>+        }
>+        IEnumPins_Release(pEnum);
>+    }
>+
>+    This->state = State_Running;
>+
>     return S_FALSE;
> }
>  
>

And this all needs to be protected by a critical section too.

> 
>@@ -1191,7 +1287,9 @@
> 					    OAFilterState *pfs) {
>     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
> 
>-    TRACE("(%p/%p)->(%ld, %p): stub !!!\n", This, iface, msTimeout, pfs);
>+    TRACE("(%p/%p)->(%ld, %p): semi-stub !!!\n", This, iface, msTimeout, pfs);
>+
>+    *pfs = This->state;
> 
>  
>

This probably needs protection too.


Rob



More information about the wine-devel mailing list