summaryrefslogtreecommitdiffstats
path: root/loader
diff options
context:
space:
mode:
authorvoroshil <voroshil@b3059339-0415-0410-9bf9-f77b7e298cf2>2007-02-23 09:58:01 +0000
committervoroshil <voroshil@b3059339-0415-0410-9bf9-f77b7e298cf2>2007-02-23 09:58:01 +0000
commita98fcdb7b3b147c15bd089b5a36fe3db0b0fd55a (patch)
tree62c860a2d965c9eb17c8c4d14f4fda9b36d2ff44 /loader
parente33a1695bab717d2dd3a7e5c289ed822437b187f (diff)
downloadmpv-a98fcdb7b3b147c15bd089b5a36fe3db0b0fd55a.tar.bz2
mpv-a98fcdb7b3b147c15bd089b5a36fe3db0b0fd55a.tar.xz
Moving duplicated (and sometimes wrong) AM_MEDIA_TYPE related code into separate file
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@22323 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'loader')
-rw-r--r--loader/Makefile1
-rw-r--r--loader/com.h13
-rw-r--r--loader/dshow/cmediasample.c21
-rw-r--r--loader/dshow/inputpin.c11
-rw-r--r--loader/dshow/mediatype.c167
-rw-r--r--loader/dshow/mediatype.h77
-rw-r--r--loader/dshow/outputpin.c25
7 files changed, 272 insertions, 43 deletions
diff --git a/loader/Makefile b/loader/Makefile
index 26693cada4..33f5d3bbf5 100644
--- a/loader/Makefile
+++ b/loader/Makefile
@@ -19,6 +19,7 @@ SRCS+= dshow/DS_AudioDecoder.c \
dshow/DS_Filter.c \
dshow/DS_VideoDecoder.c \
dshow/allocator.c \
+ dshow/mediatype.c \
dshow/cmediasample.c \
dshow/guids.c \
dshow/inputpin.c \
diff --git a/loader/com.h b/loader/com.h
index 172ce915b5..5f8e43925d 100644
--- a/loader/com.h
+++ b/loader/com.h
@@ -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
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
};
diff --git a/loader/dshow/cmediasample.c b/loader/dshow/cmediasample.c
index 4444c65204..b2f0f6f77d 100644
--- a/loader/dshow/cmediasample.c
+++ b/loader/dshow/cmediasample.c
@@ -5,6 +5,7 @@
*/
#include "cmediasample.h"
+#include "mediatype.h"
#include "wine/winerror.h"
#include <stdio.h>
#include <string.h>
@@ -81,8 +82,7 @@ void CMediaSample_Destroy(CMediaSample* This)
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 @@ static HRESULT STDCALL CMediaSample_GetMediaType(IMediaSample* This,
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 @@ static HRESULT STDCALL CMediaSample_SetMediaType(IMediaSample * This,
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;
diff --git a/loader/dshow/inputpin.c b/loader/dshow/inputpin.c
index 7ad56669ac..be455f7a6b 100644
--- a/loader/dshow/inputpin.c
+++ b/loader/dshow/inputpin.c
@@ -5,6 +5,7 @@
*/
#include "inputpin.h"
+#include "mediatype.h"
#include "wine/winerror.h"
#include <string.h>
#include <stdio.h>
@@ -311,12 +312,7 @@ static long STDCALL CInputPin_ConnectionMediaType(IPin* This,
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 long STDCALL CInputPin_NewSegment(IPin* This,
static void CInputPin_Destroy(CInputPin* This)
{
free(This->vt);
+ FreeMediaType(&(This->type));
free(This);
}
@@ -550,7 +547,7 @@ CInputPin* CInputPinCreate(CBaseFilter* p, const AM_MEDIA_TYPE* amt)
This->refcount = 1;
This->parent = p;
- This->type = *amt;
+ CopyMediaType(&(This->type),amt);
This->vt= (IPin_vt*) malloc(sizeof(IPin_vt));
diff --git a/loader/dshow/mediatype.c b/loader/dshow/mediatype.c
new file mode 100644
index 0000000000..9288f3808f
--- /dev/null
+++ b/loader/dshow/mediatype.c
@@ -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)));
+}
diff --git a/loader/dshow/mediatype.h b/loader/dshow/mediatype.h
new file mode 100644
index 0000000000..cc77e1e3b9
--- /dev/null
+++ b/loader/dshow/mediatype.h
@@ -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);
diff --git a/loader/dshow/outputpin.c b/loader/dshow/outputpin.c
index 72574c2fa6..a92c689bc7 100644
--- a/loader/dshow/outputpin.c
+++ b/loader/dshow/outputpin.c
@@ -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 @@ static HRESULT STDCALL CEnumMediaTypes_Next(IEnumMediaTypes * This,
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 @@ static CEnumMediaTypes* CEnumMediaTypesCreate(const AM_MEDIA_TYPE* amt)
}
This->refcount = 1;
- This->type = *amt;
+ CopyMediaType(&(This->type),amt);
This->vt->QueryInterface = CEnumMediaTypes_QueryInterface;
This->vt->AddRef = CEnumMediaTypes_AddRef;
@@ -368,12 +363,7 @@ static HRESULT STDCALL COutputPin_ConnectionMediaType(IPin * This,
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_SetFrameSizePointer(COutputPin* This, long* z)
*/
static void COutputPin_SetNewFormat(COutputPin* This, const AM_MEDIA_TYPE* amt)
{
- This->type = *amt;
+ CopyMediaType(&(This->type),amt);
}
/**
@@ -862,6 +852,7 @@ static void COutputPin_Destroy(COutputPin* This)
free(This->mempin);
if (This->vt)
free(This->vt);
+ FreeMediaType(&(This->type));
free(This);
}
@@ -976,7 +967,7 @@ COutputPin* COutputPinCreate(const AM_MEDIA_TYPE* amt)
This->refcount = 1;
This->remote = 0;
- This->type = *amt;
+ CopyMediaType(&(This->type),amt);
This->vt->QueryInterface = COutputPin_QueryInterface;
This->vt->AddRef = COutputPin_AddRef;