changeset 22305:3d1b23cf3d08

Moving duplicated (and sometimes wrong) AM_MEDIA_TYPE related code into separate file
author voroshil
date Fri, 23 Feb 2007 09:58:01 +0000
parents 254733f57707
children e95af173a63b
files loader/Makefile loader/com.h loader/dshow/cmediasample.c loader/dshow/inputpin.c loader/dshow/mediatype.c loader/dshow/mediatype.h loader/dshow/outputpin.c
diffstat 7 files changed, 272 insertions(+), 43 deletions(-) [+]
line wrap: on
line diff
--- a/loader/Makefile	Fri Feb 23 08:07:07 2007 +0000
+++ b/loader/Makefile	Fri Feb 23 09:58:01 2007 +0000
@@ -19,6 +19,7 @@
        dshow/DS_Filter.c \
        dshow/DS_VideoDecoder.c \
        dshow/allocator.c \
+       dshow/mediatype.c \
        dshow/cmediasample.c \
        dshow/guids.c \
        dshow/inputpin.c \
--- a/loader/com.h	Fri Feb 23 08:07:07 2007 +0000
+++ b/loader/com.h	Fri Feb 23 09:58:01 2007 +0000
@@ -25,9 +25,6 @@
 extern "C" {
 #endif
 
-void* CoTaskMemAlloc(unsigned long cb);
-void CoTaskMemFree(void* cb);
-
 #ifndef GUID_TYPE
 #define GUID_TYPE
 typedef struct
@@ -77,8 +74,18 @@
     struct IClassFactory_vt* vt;
 };
 
+#if !defined(__MINGW32__) 
+//need proper ifdef to check Co* functions availability 
 long CoCreateInstance(GUID* rclsid, struct IUnknown* pUnkOuter,
+ 		      long dwClsContext, const GUID* riid, void** ppv);
+void* CoTaskMemAlloc(unsigned long cb);
+void CoTaskMemFree(void* cb);
+#else
+long STDCALL CoCreateInstance(GUID* rclsid, struct IUnknown* pUnkOuter,
 		      long dwClsContext, const GUID* riid, void** ppv);
+void* STDCALL  CoTaskMemAlloc(unsigned long);
+void  STDCALL  CoTaskMemFree(void*);
+#endif
 
 #ifdef __cplusplus
 };
--- a/loader/dshow/cmediasample.c	Fri Feb 23 08:07:07 2007 +0000
+++ b/loader/dshow/cmediasample.c	Fri Feb 23 09:58:01 2007 +0000
@@ -5,6 +5,7 @@
  */
 
 #include "cmediasample.h"
+#include "mediatype.h"
 #include "wine/winerror.h"
 #include <stdio.h>
 #include <string.h>
@@ -81,8 +82,7 @@
     Debug printf("CMediaSample_Destroy(%p) called (ref:%d)\n", This, This->refcount);
     free(This->vt);
     free(This->own_block);
-    if (This->media_type.pbFormat)
-	free(This->media_type.pbFormat);
+    FreeMediaType(&(This->media_type));
     free(This);
 }
 
@@ -352,10 +352,7 @@
 
     t = &((CMediaSample*)This)->media_type;
     //    if(t.pbFormat)free(t.pbFormat);
-    (*ppMediaType) = malloc(sizeof(AM_MEDIA_TYPE));
-    **ppMediaType = *t;
-    (*ppMediaType)->pbFormat = malloc(t->cbFormat);
-    memcpy((*ppMediaType)->pbFormat, t->pbFormat, t->cbFormat);
+    *ppMediaType=CreateMediaType(t);
     //    *ppMediaType=0; //media type was not changed
     return 0;
 }
@@ -378,16 +375,8 @@
     if (!pMediaType)
 	return E_INVALIDARG;
     t = &((CMediaSample*)This)->media_type;
-    if (t->pbFormat)
-	free(t->pbFormat);
-    t = pMediaType;
-    if (t->cbFormat)
-    {
-	t->pbFormat = malloc(t->cbFormat);
-	memcpy(t->pbFormat, pMediaType->pbFormat, t->cbFormat);
-    }
-    else
-        t->pbFormat = 0;
+    FreeMediaType(t);
+    CopyMediaType(t,pMediaType);
     ((CMediaSample*) This)->type_valid=1;
 
     return 0;
--- a/loader/dshow/inputpin.c	Fri Feb 23 08:07:07 2007 +0000
+++ b/loader/dshow/inputpin.c	Fri Feb 23 09:58:01 2007 +0000
@@ -5,6 +5,7 @@
  */
 
 #include "inputpin.h"
+#include "mediatype.h"
 #include "wine/winerror.h"
 #include <string.h>
 #include <stdio.h>
@@ -311,12 +312,7 @@
     Debug printf("CInputPin_ConnectionMediaType(%p) called\n", This);
     if (!pmt)
 	return E_INVALIDARG;
-    *pmt=((CInputPin*)This)->type;
-    if (pmt->cbFormat > 0)
-    {
-	pmt->pbFormat=malloc(pmt->cbFormat);
-	memcpy(pmt->pbFormat, ((CInputPin*)This)->type.pbFormat, pmt->cbFormat);
-    }
+    CopyMediaType(pmt,&(((CInputPin*)This)->type));
     return 0;
 }
 
@@ -527,6 +523,7 @@
 static void CInputPin_Destroy(CInputPin* This)
 {
     free(This->vt);
+    FreeMediaType(&(This->type));
     free(This);
 }
 
@@ -550,7 +547,7 @@
 
     This->refcount = 1;
     This->parent = p;
-    This->type = *amt;
+    CopyMediaType(&(This->type),amt);
 
     This->vt= (IPin_vt*) malloc(sizeof(IPin_vt));
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/loader/dshow/mediatype.c	Fri Feb 23 09:58:01 2007 +0000
@@ -0,0 +1,167 @@
+/*
+ *     AM_MEDIA_TYPE service functions implementations
+ *     Code is based on quartz/enummedia.c file from wine project.
+ *     Modified by Vladimir Voroshilov
+ *
+ *     Original code: Copyright 2003 Robert Shearman
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     This program is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ *     You should have received a copy of the GNU General Public License
+ *     along with this program; if not, write to the Free Software
+ *     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#include "mediatype.h"
+#include "mp_msg.h"
+#include "wine/winerror.h"
+#include "com.h"
+
+
+#ifndef NOAVIFILE_HEADERS
+#include "audiodecoder.h"
+#include "except.h"
+#else
+#include "libwin32.h"
+#endif
+
+void DisplayMediaType(const char * label,const AM_MEDIA_TYPE* pmt){
+    WAVEFORMATEX* pWF;
+    VIDEOINFOHEADER* Vhdr;
+    int i;
+    GUID* iid;
+    
+   
+    Debug mp_msg(MSGT_LOADER,MSGL_DBG4,"=======================\n");
+    if(label)
+        Debug mp_msg(MSGT_LOADER,MSGL_DBG4,"AM_MEDIA_TYPE: %s\n",label);
+    else
+        Debug mp_msg(MSGT_LOADER,MSGL_DBG4,"AM_MEDIA_TYPE:\n");
+    Debug mp_msg(MSGT_LOADER,MSGL_DBG4,"-(Ptr:%p)--------\n",pmt);
+    for(i=0;i<sizeof(AM_MEDIA_TYPE);i++){
+        Debug mp_msg(MSGT_LOADER,MSGL_DBG4,"%02x ",(BYTE)((BYTE*)pmt)[i]);
+        if((i+1)%8==0) Debug mp_msg(MSGT_LOADER,MSGL_DBG4,"\n");
+    }
+    if((i)%8!=0) printf("\n");
+    Debug mp_msg(MSGT_LOADER,MSGL_DBG4,"-(Ptr:%p)--(%02d)--\n",pmt->pbFormat,pmt->cbFormat);
+    for(i=0;i<pmt->cbFormat;i++){
+        Debug mp_msg(MSGT_LOADER,MSGL_DBG4,"%02x ",(BYTE)pmt->pbFormat[i]);
+        if((i+1)%8==0) Debug mp_msg(MSGT_LOADER,MSGL_DBG4,"\n");
+    }
+    if((i)%8!=0) Debug mp_msg(MSGT_LOADER,MSGL_DBG4,"\n");
+    Debug mp_msg(MSGT_LOADER,MSGL_DBG4,"-----------------------\n");
+    iid=(GUID*)&(pmt->subtype);
+    Debug mp_msg(MSGT_LOADER,MSGL_DBG4,"Subtype:     %08x-%04x-%04x-%02x%02x-"
+		 "%02x%02x%02x%02x%02x%02x\n",
+		 iid->f1,  iid->f2,  iid->f3,
+		 (unsigned char)iid->f4[1], (unsigned char)iid->f4[0],
+		 (unsigned char)iid->f4[2], (unsigned char)iid->f4[3],
+		 (unsigned char)iid->f4[4], (unsigned char)iid->f4[5],
+		 (unsigned char)iid->f4[6], (unsigned char)iid->f4[7]);
+
+    iid=(GUID*)&(pmt->formattype);
+    Debug mp_msg(MSGT_LOADER,MSGL_DBG4,"Format type: %08x-%04x-%04x-%02x%02x-"
+		 "%02x%02x%02x%02x%02x%02x\n",
+		 iid->f1,  iid->f2,  iid->f3,
+		 (unsigned char)iid->f4[1], (unsigned char)iid->f4[0],
+		 (unsigned char)iid->f4[2], (unsigned char)iid->f4[3],
+		 (unsigned char)iid->f4[4], (unsigned char)iid->f4[5],
+		 (unsigned char)iid->f4[6], (unsigned char)iid->f4[7]);
+    if(pmt && memcmp(&pmt->formattype,&FORMAT_WaveFormatEx,16)==0 && pmt->pbFormat){
+    pWF=(WAVEFORMATEX*)pmt->pbFormat;
+    Debug mp_msg(MSGT_LOADER,MSGL_DBG4,"PMT: nChannels %d\n",pWF->nChannels);
+    Debug mp_msg(MSGT_LOADER,MSGL_DBG4,"PMT: nSamplesPerSec %d\n",pWF->nSamplesPerSec);
+    Debug mp_msg(MSGT_LOADER,MSGL_DBG4,"PMT: wBitsPerSample %d\n",pWF->wBitsPerSample);
+    Debug mp_msg(MSGT_LOADER,MSGL_DBG4,"PMT: nBlockAlign %d\n",pWF->nBlockAlign);
+    Debug mp_msg(MSGT_LOADER,MSGL_DBG4,"PMT: nAvgBytesPerSec %d\n",pWF->nAvgBytesPerSec);
+    Debug mp_msg(MSGT_LOADER,MSGL_DBG4,"PMT: SampleSize %ld\n",pmt->lSampleSize);
+    }
+    if(pmt && memcmp(&pmt->formattype,&FORMAT_VideoInfo,16)==0 && pmt->pbFormat){
+    Vhdr=(VIDEOINFOHEADER*)pmt->pbFormat;
+    Debug mp_msg(MSGT_LOADER,MSGL_DBG4,"Vhdr: dwBitRate %ld\n",Vhdr->dwBitRate);
+    Debug mp_msg(MSGT_LOADER,MSGL_DBG4,"Vhdr: biWidth %ld\n",Vhdr->bmiHeader.biWidth);
+    Debug mp_msg(MSGT_LOADER,MSGL_DBG4,"Vhdr: biHeight %d\n",Vhdr->bmiHeader.biHeight);
+    Debug mp_msg(MSGT_LOADER,MSGL_DBG4,"Vhdr: biSizeImage %d\n",Vhdr->bmiHeader.biSizeImage);
+    Debug mp_msg(MSGT_LOADER,MSGL_DBG4,"Vhdr: biBitCount %d\n",Vhdr->bmiHeader.biBitCount);
+    if(Vhdr->bmiHeader.biCompression){
+        Debug mp_msg(MSGT_LOADER,MSGL_DBG4,"Vhdr: biComression 0x%08x (%s)\n",Vhdr->bmiHeader.biCompression,vo_format_name(Vhdr->bmiHeader.biCompression));
+    }else
+        Debug mp_msg(MSGT_LOADER,MSGL_DBG4,"Vhdr: biComression 0x00000000\n");
+
+    }
+    Debug mp_msg(MSGT_LOADER,MSGL_DBG4,"=======================\n");
+}
+
+HRESULT CopyMediaType(AM_MEDIA_TYPE * pDest, const AM_MEDIA_TYPE *pSrc)
+{
+    Debug mp_msg(MSGT_LOADER,MSGL_DBG4,"%s(%p) called\n", "CopyMediaType",pSrc);
+
+    if(!pSrc || !pDest) return E_POINTER;
+
+    if(pSrc == pDest) return E_INVALIDARG;
+
+    if(!pSrc->pbFormat && pSrc->cbFormat) return E_POINTER;
+    
+    memcpy(pDest, pSrc, sizeof(AM_MEDIA_TYPE));
+    if (!pSrc->pbFormat) return S_OK;
+    if (!(pDest->pbFormat = CoTaskMemAlloc(pSrc->cbFormat)))
+        return E_OUTOFMEMORY;
+    memcpy(pDest->pbFormat, pSrc->pbFormat, pSrc->cbFormat);
+    if (pDest->pUnk)
+        pDest->pUnk->vt->AddRef(pDest->pUnk);
+    return S_OK;
+}
+
+void FreeMediaType(AM_MEDIA_TYPE * pMediaType)
+{
+    if (!pMediaType) return;
+    if (pMediaType->pbFormat)
+    {
+        CoTaskMemFree(pMediaType->pbFormat);
+        pMediaType->pbFormat = NULL;
+    }
+    if (pMediaType->pUnk)
+    {
+        pMediaType->pUnk->vt->Release(pMediaType->pUnk);
+        pMediaType->pUnk = NULL;
+    }
+}
+
+AM_MEDIA_TYPE * CreateMediaType(AM_MEDIA_TYPE const * pSrc)
+{
+    AM_MEDIA_TYPE * pDest;
+    if (!pSrc) return NULL;
+    pDest = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));
+    if (!pDest)
+        return NULL;
+
+    if (FAILED(CopyMediaType(pDest, pSrc)))
+    {
+        CoTaskMemFree(pDest);
+        return NULL;
+    }
+
+    return pDest;
+}
+
+void DeleteMediaType(AM_MEDIA_TYPE * pMediaType)
+{
+    if (!pMediaType) return;
+    FreeMediaType(pMediaType);
+    CoTaskMemFree(pMediaType);
+}
+
+#define IsEqualGUID(a,b) (memcmp(a,b,16)==0)
+int CompareMediaTypes(const AM_MEDIA_TYPE * pmt1, const AM_MEDIA_TYPE * pmt2, int bWildcards)
+{
+    return (((bWildcards && (IsEqualGUID(&pmt1->majortype, &GUID_NULL) || IsEqualGUID(&pmt2->majortype, &GUID_NULL))) || IsEqualGUID(&pmt1->majortype, &pmt2->majortype)) &&
+            ((bWildcards && (IsEqualGUID(&pmt1->subtype, &GUID_NULL)   || IsEqualGUID(&pmt2->subtype, &GUID_NULL)))   || IsEqualGUID(&pmt1->subtype, &pmt2->subtype)));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/loader/dshow/mediatype.h	Fri Feb 23 09:58:01 2007 +0000
@@ -0,0 +1,77 @@
+/*
+-------------------------------------------------------------------
+    AM_MEDIA_TYPE service functions declarations
+-------------------------------------------------------------------
+*/
+#include "guids.h"
+                  
+/**
+ * \brief print info from AM_MEDIA_TYPE structure
+ * =param[in] label short lable for media type
+ * \param[in] pmt pointer to AM_MEDIA_TYPE
+ * 
+ * routine used for debug purposes
+ *
+ */
+void DisplayMediaType(const char * label,const AM_MEDIA_TYPE* pmt);
+/**
+ * \brief frees memory, pointed by pbFormat and pUnk members of AM_MEDIA_TYPE structure
+ *
+ * \param[in] pmt pointer to structure
+ *
+ * \note
+ * routine does not frees memory allocated for AM_MEDIA_TYPE, so given pointer will be
+ * valid after this routine call.
+ *
+ */
+void FreeMediaType(AM_MEDIA_TYPE* pmt);
+/**
+ * \brief frees memory allocated for AM_MEDIA_TYPE structure, including pbFormat and pUnk
+ *        members
+ *
+ * \param[in] pmt pointer to structure
+ *
+ * \note
+ * after call to this routine, pointer to AM_MEDIA_TYPE will not be valid anymore
+ *
+ */
+void DeleteMediaType(AM_MEDIA_TYPE* pmt);
+/**
+ * \brief copyies info from source to destination AM_MEDIA_TYPE structures
+ *
+ * \param[in] pSrc pointer to AM_MEDIA_TYPE structure to copy data from
+ * \param[out] pDst pointer to AM_MEDIA_TYPE structure to copy data to
+ *
+ * \return S_OK - success
+ * \return E_POINTER - pSrc or pDst is NULL or (pSrc->cbFormat && !pSrc->pbFormat)
+ * \return E_INVALIDARG - (pSrc == pDst) 
+ * \return E_OUTOFMEMORY - Insufficient memory
+ *
+ * \note
+ * - pDst must point to existing AM_MEDIA_TYPE structure (all data will be overwritten)
+ * - if pDst->pbFormat!=NULL this will cause memory leak (as described in Directshow SDK)!
+ *
+ */
+HRESULT CopyMediaType(AM_MEDIA_TYPE* pDst,const AM_MEDIA_TYPE* pSrc);
+/**
+ * \brief allocates new AM_MEDIA_TYPE structure and fills it with info from given one
+ *
+ * \param[in] pSrc pointer to AM_MEDIA_TYPE structure to copy data from
+ *
+ * \return result code, returned from CopyMediaType
+ *
+ */
+AM_MEDIA_TYPE* CreateMediaType(const AM_MEDIA_TYPE* pSrc);
+
+/**
+ * \brief compares two AM_MEDIA_TYPE structures for compatibility
+ *
+ * \param[in] pmt1 first  AM_MEDIA_TYPE structure for compare
+ * \param[in] pmt2 second AM_MEDIA_TYPE structure for compare
+ * \param[in] bWildcards 1 means that GUID_NULL of one structure will be compatible with any value of another structure
+ *
+ * \return 1 if structures are compatible
+ * \return 0 if structures are not compatible
+ *
+ */
+int CompareMediaTypes(const AM_MEDIA_TYPE * pmt1, const AM_MEDIA_TYPE * pmt2, int bWildcards);
--- a/loader/dshow/outputpin.c	Fri Feb 23 08:07:07 2007 +0000
+++ b/loader/dshow/outputpin.c	Fri Feb 23 09:58:01 2007 +0000
@@ -7,6 +7,7 @@
 #include "wine/winerror.h"
 #include "wine/windef.h"
 #include "outputpin.h"
+#include "mediatype.h"
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
@@ -73,14 +74,8 @@
 
     if (pcFetched)
 	*pcFetched=1;
-    ppMediaTypes[0] = malloc(sizeof(AM_MEDIA_TYPE));
-    // copy structures - C can handle this...
-    **ppMediaTypes = *type;
-    if (ppMediaTypes[0]->pbFormat)
-    {
-	ppMediaTypes[0]->pbFormat=malloc(ppMediaTypes[0]->cbFormat);
-	memcpy(ppMediaTypes[0]->pbFormat, type->pbFormat, ppMediaTypes[0]->cbFormat);
-    }
+    ppMediaTypes[0] = CreateMediaType(type);
+
     if (cMediaTypes == 1)
 	return 0;
     return 1;
@@ -177,7 +172,7 @@
     }
 
     This->refcount = 1;
-    This->type = *amt;
+    CopyMediaType(&(This->type),amt);
 
     This->vt->QueryInterface = CEnumMediaTypes_QueryInterface;
     This->vt->AddRef = CEnumMediaTypes_AddRef;
@@ -368,12 +363,7 @@
     Debug printf("COutputPin_ConnectionMediaType(%p) called\n",This);
     if (!pmt)
 	return E_INVALIDARG;
-    *pmt = ((COutputPin*)This)->type;
-    if (pmt->cbFormat>0)
-    {
-	pmt->pbFormat=malloc(pmt->cbFormat);
-	memcpy(pmt->pbFormat, ((COutputPin*)This)->type.pbFormat, pmt->cbFormat);
-    }
+    CopyMediaType(pmt,&(((COutputPin*)This)->type));
     return 0;
 }
 
@@ -845,7 +835,7 @@
  */
 static void COutputPin_SetNewFormat(COutputPin* This, const AM_MEDIA_TYPE* amt)
 {
-    This->type = *amt;
+    CopyMediaType(&(This->type),amt);
 }
 
 /**
@@ -862,6 +852,7 @@
 	free(This->mempin);
     if (This->vt)
 	free(This->vt);
+    FreeMediaType(&(This->type));
     free(This);
 }
 
@@ -976,7 +967,7 @@
 
     This->refcount = 1;
     This->remote = 0;
-    This->type = *amt;
+    CopyMediaType(&(This->type),amt);
 
     This->vt->QueryInterface = COutputPin_QueryInterface;
     This->vt->AddRef = COutputPin_AddRef;