[QUARTZ] Improved AVIDec filter & transform template

Christian Costa titan.costa at wanadoo.fr
Sat Feb 19 08:50:33 CST 2005


Hi,

Changelog:
Improved AVIDec.
Added 2 new callback functions to the transform template and moved all 
of them into a funcs table.

Christian Costa   titan.costa at wanadoo.fr

-------------- next part --------------
Index: dlls/quartz/avidec.c
===================================================================
RCS file: /home/wine/wine/dlls/quartz/avidec.c,v
retrieving revision 1.16
diff -u -r1.16 avidec.c
--- dlls/quartz/avidec.c	1 Feb 2005 14:22:00 -0000	1.16
+++ dlls/quartz/avidec.c	19 Feb 2005 13:32:21 -0000
@@ -46,6 +46,8 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(quartz);
 
+static HRESULT AVIDec_Cleanup(TransformFilterImpl* pTransformFilter);
+
 typedef struct AVIDecImpl
 {
     TransformFilterImpl tf;
@@ -54,7 +56,23 @@
     BITMAPINFOHEADER* pBihOut;
 } AVIDecImpl;
 
-static DWORD AVIDec_SendSampleData(TransformFilterImpl* pTransformFilter, LPBYTE data, DWORD size)
+static HRESULT AVIDec_ProcessBegin(TransformFilterImpl* pTransformFilter)
+{
+    AVIDecImpl* This = (AVIDecImpl*)pTransformFilter;
+    DWORD result;
+
+    TRACE("(%p)->()\n", This);
+
+    result = ICDecompressBegin(This->hvid, This->pBihIn, This->pBihOut);
+    if (result != ICERR_OK)
+    {
+        ERR("Cannot start processing (%ld)\n", result);
+	return E_FAIL;
+    }
+    return S_OK;
+}
+
+static HRESULT AVIDec_ProcessSampleData(TransformFilterImpl* pTransformFilter, LPBYTE data, DWORD size)
 {
     AVIDecImpl* This = (AVIDecImpl*)pTransformFilter;
     VIDEOINFOHEADER* format;
@@ -115,25 +133,45 @@
     return hr;
 }
 
+static HRESULT AVIDec_ProcessEnd(TransformFilterImpl* pTransformFilter)
+{
+    AVIDecImpl* This = (AVIDecImpl*)pTransformFilter;
+    DWORD result;
+
+    TRACE("(%p)->()\n", This);
+
+    result = ICDecompressEnd(This->hvid);
+    if (result != ICERR_OK)
+    {
+        ERR("Cannot stop processing (%ld)\n", result);
+	return E_FAIL;
+    }
+    return S_OK;
+}
+
 static HRESULT AVIDec_ConnectInput(TransformFilterImpl* pTransformFilter, const AM_MEDIA_TYPE * pmt)
 {
     AVIDecImpl* This = (AVIDecImpl*)pTransformFilter;
+    HRESULT hr = S_FALSE;
 
     TRACE("(%p)->(%p)\n", This, pmt);
 
+    AVIDec_Cleanup(pTransformFilter);
+   
     if ((IsEqualIID(&pmt->majortype, &MEDIATYPE_Video)) &&
         (!memcmp(((char*)&pmt->subtype)+4, ((char*)&MEDIATYPE_Video)+4, sizeof(GUID)-4)) && /* Check root (GUID w/o FOURCC) */
         (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo)))
     {
-        HIC drv;
         VIDEOINFOHEADER* format = (VIDEOINFOHEADER*)pmt->pbFormat;
 
-        drv = ICLocate(pmt->majortype.Data1, pmt->subtype.Data1, &format->bmiHeader, NULL, ICMODE_DECOMPRESS);
-        if (drv)
+        This->hvid = ICLocate(pmt->majortype.Data1, pmt->subtype.Data1, &format->bmiHeader, NULL, ICMODE_DECOMPRESS);
+        if (This->hvid)
         {
             AM_MEDIA_TYPE* outpmt = &((OutputPin*)This->tf.ppPins[1])->pin.mtCurrent;
             const CLSID* outsubtype;
             DWORD bih_size;
+            DWORD output_depth = format->bmiHeader.biBitCount;
+            DWORD result;
 
             switch(format->bmiHeader.biBitCount)
             {
@@ -142,41 +180,46 @@
                 case 16: outsubtype = &MEDIASUBTYPE_RGB565; break;
                 case 8:  outsubtype = &MEDIASUBTYPE_RGB8; break;
                 default:
-                    FIXME("Depth %d not supported\n", format->bmiHeader.biBitCount);
-                    ICClose(drv);
-                    return S_FALSE;
+                    TRACE("Non standard input depth %d, forced ouptut depth to 32\n", format->bmiHeader.biBitCount);
+                    outsubtype = &MEDIASUBTYPE_RGB32;
+                    output_depth = 32;
+                    break;
             }
-            CopyMediaType(outpmt, pmt);
-            outpmt->subtype = *outsubtype;
-            This->hvid = drv;
 
             /* Copy bitmap header from media type to 1 for input and 1 for output */
-            if (This->pBihIn) {
-                CoTaskMemFree(This->pBihIn);
-                CoTaskMemFree(This->pBihOut);
-            }
             bih_size = format->bmiHeader.biSize + format->bmiHeader.biClrUsed * 4;
             This->pBihIn = (BITMAPINFOHEADER*)CoTaskMemAlloc(bih_size);
             if (!This->pBihIn)
             {
-                ICClose(drv);
-                return E_OUTOFMEMORY;
+                hr = E_OUTOFMEMORY;
+                goto failed;
             }
             This->pBihOut = (BITMAPINFOHEADER*)CoTaskMemAlloc(bih_size);
             if (!This->pBihOut)
             {
-                CoTaskMemFree(This->pBihIn);
-                This->pBihIn = NULL;
-                ICClose(drv);
-                return E_OUTOFMEMORY;
+                hr = E_OUTOFMEMORY;
+                goto failed;
             }
             memcpy(This->pBihIn, &format->bmiHeader, bih_size);
             memcpy(This->pBihOut, &format->bmiHeader, bih_size);
 
             /* Update output format as non compressed bitmap */
             This->pBihOut->biCompression = 0;
+            This->pBihOut->biBitCount = output_depth;
             This->pBihOut->biSizeImage = This->pBihOut->biWidth * This->pBihOut->biHeight * This->pBihOut->biBitCount / 8;
 
+            result = ICDecompressQuery(This->hvid, This->pBihIn, This->pBihOut);
+            if (result != ICERR_OK)
+            {
+                TRACE("Unable to found a suitable output format (%ld)\n", result);
+                goto failed;
+            }
+
+            /* Update output media type */
+            CopyMediaType(outpmt, pmt);
+            outpmt->subtype = *outsubtype;
+            memcpy(&(((VIDEOINFOHEADER*)outpmt->pbFormat)->bmiHeader), This->pBihOut, This->pBihOut->biSize); 
+
             /* Update buffer size of media samples in output */
             ((OutputPin*)This->tf.ppPins[1])->allocProps.cbBuffer = This->pBihOut->biSizeImage;
 
@@ -186,8 +229,11 @@
         TRACE("Unable to find a suitable VFW decompressor\n");
     }
 
+failed:
+    AVIDec_Cleanup(pTransformFilter);
+    
     TRACE("Connection refused\n");
-    return S_FALSE;
+    return hr;
 }
 
 static HRESULT AVIDec_Cleanup(TransformFilterImpl* pTransformFilter)
@@ -198,18 +244,26 @@
     
     if (This->hvid)
         ICClose(This->hvid);
-
-    if (This->pBihIn) {
+    if (This->pBihIn)
         CoTaskMemFree(This->pBihIn);
+    if (This->pBihOut)
         CoTaskMemFree(This->pBihOut);
-    }
 
     This->hvid = NULL;
     This->pBihIn = NULL;
+    This->pBihOut = NULL;
 
     return S_OK;
 }
 
+TransformFuncsTable AVIDec_FuncsTable = {
+    AVIDec_ProcessBegin,
+    AVIDec_ProcessSampleData,
+    AVIDec_ProcessEnd,
+    AVIDec_ConnectInput,
+    AVIDec_Cleanup
+};
+
 HRESULT AVIDec_create(IUnknown * pUnkOuter, LPVOID * ppv)
 {
     HRESULT hr;
@@ -227,8 +281,9 @@
 
     This->hvid = NULL;
     This->pBihIn = NULL;
+    This->pBihOut = NULL;
 
-    hr = TransformFilter_Create(&(This->tf), &CLSID_AVIDec, AVIDec_SendSampleData, AVIDec_ConnectInput, AVIDec_Cleanup);
+    hr = TransformFilter_Create(&(This->tf), &CLSID_AVIDec, &AVIDec_FuncsTable);
 
     if (FAILED(hr))
         return hr;
Index: dlls/quartz/acmwrapper.c
===================================================================
RCS file: /home/wine/wine/dlls/quartz/acmwrapper.c,v
retrieving revision 1.2
diff -u -r1.2 acmwrapper.c
--- dlls/quartz/acmwrapper.c	10 Feb 2005 19:19:35 -0000	1.2
+++ dlls/quartz/acmwrapper.c	19 Feb 2005 13:32:23 -0000
@@ -59,7 +59,7 @@
     BOOL reinit_codec; /* FIXME: Should use sync points instead */
 } ACMWrapperImpl;
 
-static DWORD ACMWrapper_SendSampleData(TransformFilterImpl* pTransformFilter, LPBYTE data, DWORD size)
+static HRESULT ACMWrapper_ProcessSampleData(TransformFilterImpl* pTransformFilter, LPBYTE data, DWORD size)
 {
     ACMWrapperImpl* This = (ACMWrapperImpl*)pTransformFilter;
     AM_MEDIA_TYPE amt;
@@ -230,6 +230,14 @@
     return S_OK;
 }
 
+TransformFuncsTable ACMWrapper_FuncsTable = {
+    NULL,
+    ACMWrapper_ProcessSampleData,
+    NULL,
+    ACMWrapper_ConnectInput,
+    ACMWrapper_Cleanup
+};
+
 HRESULT ACMWrapper_create(IUnknown * pUnkOuter, LPVOID * ppv)
 {
     HRESULT hr;
@@ -248,7 +256,7 @@
     This->has = 0;
     This->reinit_codec = TRUE;
 
-    hr = TransformFilter_Create(&(This->tf), &CLSID_ACMWrapper, ACMWrapper_SendSampleData, ACMWrapper_ConnectInput, ACMWrapper_Cleanup);
+    hr = TransformFilter_Create(&(This->tf), &CLSID_ACMWrapper, &ACMWrapper_FuncsTable);
 
     if (FAILED(hr))
         return hr;
Index: dlls/quartz/transform.h
===================================================================
RCS file: /home/wine/wine/dlls/quartz/transform.h,v
retrieving revision 1.1
diff -u -r1.1 transform.h
--- dlls/quartz/transform.h	31 Jan 2005 16:24:00 -0000	1.1
+++ dlls/quartz/transform.h	19 Feb 2005 13:32:25 -0000
@@ -20,9 +20,13 @@
 
 typedef struct TransformFilterImpl TransformFilterImpl;
 
-typedef DWORD (*PFN_PROCESS_SAMPLE) (TransformFilterImpl* This, LPBYTE data, DWORD size);
-typedef HRESULT (*PFN_CONNECT_INPUT) (TransformFilterImpl* This, const AM_MEDIA_TYPE * pmt);
-typedef HRESULT (*PFN_CLEANUP) (TransformFilterImpl* This);
+typedef struct TransformFuncsTable {
+    HRESULT (*pfnProcessBegin) (TransformFilterImpl* This);
+    HRESULT (*pfnProcessSampleData) (TransformFilterImpl* This, LPBYTE data, DWORD size);
+    HRESULT (*pfnProcessEnd) (TransformFilterImpl* This);
+    HRESULT (*pfnConnectInput) (TransformFilterImpl* This, const AM_MEDIA_TYPE * pmt);
+    HRESULT (*pfnCleanup) (TransformFilterImpl* This);
+} TransformFuncsTable;
 
 struct TransformFilterImpl
 {
@@ -38,9 +42,7 @@
 
     IPin ** ppPins;
 
-    PFN_PROCESS_SAMPLE pfnProcessSample;
-    PFN_CONNECT_INPUT pfnConnectInput;
-    PFN_CLEANUP pfnCleanup;
+    TransformFuncsTable * pFuncsTable;
 };
 
-HRESULT TransformFilter_Create(TransformFilterImpl*, const CLSID*, PFN_PROCESS_SAMPLE, PFN_CONNECT_INPUT, PFN_CLEANUP);
+HRESULT TransformFilter_Create(TransformFilterImpl*, const CLSID*, TransformFuncsTable* pFuncsTable);
Index: dlls/quartz/transform.c
===================================================================
RCS file: /home/wine/wine/dlls/quartz/transform.c,v
retrieving revision 1.1
diff -u -r1.1 transform.c
--- dlls/quartz/transform.c	31 Jan 2005 16:24:00 -0000	1.1
+++ dlls/quartz/transform.c	19 Feb 2005 13:32:27 -0000
@@ -92,7 +92,7 @@
     }
 #endif
 
-    This->pfnProcessSample(This, pbSrcStream, cbSrcStream);
+    This->pFuncsTable->pfnProcessSampleData(This, pbSrcStream, cbSrcStream);
 
     return S_OK;
 }
@@ -103,7 +103,7 @@
     TRACE("%p\n", iface);
     dump_AM_MEDIA_TYPE(pmt);
 
-    return This->pfnConnectInput(This, pmt);
+    return This->pFuncsTable->pfnConnectInput(This, pmt);
 }
 
 
@@ -173,7 +173,7 @@
     return E_FAIL;
 }
 
-HRESULT TransformFilter_Create(TransformFilterImpl* pTransformFilter, const CLSID* pClsid, PFN_PROCESS_SAMPLE pps, PFN_CONNECT_INPUT pci, PFN_CLEANUP pcu)
+HRESULT TransformFilter_Create(TransformFilterImpl* pTransformFilter, const CLSID* pClsid, TransformFuncsTable* pFuncsTable)
 {
     HRESULT hr;
     PIN_INFO piInput;
@@ -181,9 +181,7 @@
 
     /* pTransformFilter is already allocated */
     pTransformFilter->clsid = *pClsid;
-    pTransformFilter->pfnProcessSample = pps;
-    pTransformFilter->pfnConnectInput = pci;
-    pTransformFilter->pfnCleanup = pcu;
+    pTransformFilter->pFuncsTable = pFuncsTable;
 
     pTransformFilter->lpVtbl = &TransformFilter_Vtbl;
 
@@ -285,7 +283,7 @@
         HeapFree(GetProcessHeap(), 0, This->ppPins);
         This->lpVtbl = NULL;
 
-	This->pfnCleanup(This);
+	This->pFuncsTable->pfnCleanup(This);
 
         TRACE("Destroying transform filter\n");
         CoTaskMemFree(This);
@@ -320,6 +318,8 @@
     EnterCriticalSection(&This->csFilter);
     {
         This->state = State_Stopped;
+        if (This->pFuncsTable->pfnProcessEnd)
+            This->pFuncsTable->pfnProcessEnd(This);
     }
     LeaveCriticalSection(&This->csFilter);
 
@@ -353,6 +353,8 @@
         This->rtStreamStart = tStart;
         This->state = State_Running;
         OutputPin_CommitAllocator((OutputPin *)This->ppPins[1]);
+        if (This->pFuncsTable->pfnProcessBegin)
+            This->pFuncsTable->pfnProcessBegin(This);
     }
     LeaveCriticalSection(&This->csFilter);
 
@@ -540,7 +542,7 @@
 
     if (hr == S_OK)
     {
-	pTransformFilter->pfnCleanup(pTransformFilter);
+	pTransformFilter->pFuncsTable->pfnCleanup(pTransformFilter);
     }
 
     return hr;


More information about the wine-patches mailing list