diff options
author | arpi <arpi@b3059339-0415-0410-9bf9-f77b7e298cf2> | 2001-12-11 23:29:24 +0000 |
---|---|---|
committer | arpi <arpi@b3059339-0415-0410-9bf9-f77b7e298cf2> | 2001-12-11 23:29:24 +0000 |
commit | 73226c73b01b80b7fe848500ee862caa73775518 (patch) | |
tree | 92536ad555b3e002017a244afa75f58bc279a26d | |
parent | e2f3778cb0ba8aa7df837d66a53833bdd3a63bb2 (diff) | |
download | mpv-73226c73b01b80b7fe848500ee862caa73775518.tar.bz2 mpv-73226c73b01b80b7fe848500ee862caa73775518.tar.xz |
avifile sync
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@3468 b3059339-0415-0410-9bf9-f77b7e298cf2
-rw-r--r-- | loader/dshow/DS_Filter.c | 51 | ||||
-rw-r--r-- | loader/dshow/DS_Filter.h | 1 | ||||
-rw-r--r-- | loader/dshow/allocator.c | 60 | ||||
-rw-r--r-- | loader/dshow/cmediasample.c | 96 | ||||
-rw-r--r-- | loader/dshow/cmediasample.h | 5 | ||||
-rw-r--r-- | loader/dshow/guids.c | 2 | ||||
-rw-r--r-- | loader/dshow/guids.h | 18 | ||||
-rw-r--r-- | loader/dshow/inputpin.c | 80 | ||||
-rw-r--r-- | loader/dshow/inputpin.h | 2 | ||||
-rw-r--r-- | loader/dshow/interfaces.h | 31 | ||||
-rw-r--r-- | loader/dshow/outputpin.c | 105 |
11 files changed, 314 insertions, 137 deletions
diff --git a/loader/dshow/DS_Filter.c b/loader/dshow/DS_Filter.c index 4bef2ffd74..2ecf1d8898 100644 --- a/loader/dshow/DS_Filter.c +++ b/loader/dshow/DS_Filter.c @@ -12,7 +12,7 @@ static void DS_Filter_Start(DS_Filter* This) { HRESULT hr; - if (This->m_iState != 1) + if (This->m_pAll) return; //Debug printf("DS_Filter_Start(%p)\n", This); @@ -30,23 +30,14 @@ static void DS_Filter_Start(DS_Filter* This) return; } This->m_pImp->vt->NotifyAllocator(This->m_pImp, This->m_pAll, 0); - This->m_iState = 2; } static void DS_Filter_Stop(DS_Filter* This) { - if (This->m_iState == 2) + if (This->m_pAll) { - This->m_iState = 1; //Debug printf("DS_Filter_Stop(%p)\n", This); - if (This->m_pFilter) - { - //printf("vt: %p\n", m_pFilter->vt); - //printf("vtstop %p\n", m_pFilter->vt->Stop); - This->m_pFilter->vt->Stop(This->m_pFilter); // causes weird crash ??? FIXME - } - else - printf("WARNING: DS_Filter::Stop() m_pFilter is NULL!\n"); + This->m_pFilter->vt->Stop(This->m_pFilter); // causes weird crash ??? FIXME This->m_pAll->vt->Release((IUnknown*)This->m_pAll); This->m_pAll = 0; } @@ -56,8 +47,6 @@ void DS_Filter_Destroy(DS_Filter* This) { This->Stop(This); - This->m_iState = 0; - if (This->m_pOurInput) This->m_pOurInput->vt->Release((IUnknown*)This->m_pOurInput); if (This->m_pInputPin) @@ -93,6 +82,9 @@ DS_Filter* DS_FilterCreate(const char* dllname, const GUID* id, AM_MEDIA_TYPE* in_fmt, AM_MEDIA_TYPE* out_fmt) { + int init = 0; + char eb[250]; + const char* em = NULL; DS_Filter* This = (DS_Filter*) malloc(sizeof(DS_Filter)); if (!This) return NULL; @@ -108,7 +100,6 @@ DS_Filter* DS_FilterCreate(const char* dllname, const GUID* id, This->m_pOurOutput = NULL; This->m_pAll = NULL; This->m_pImp = NULL; - This->m_iState = 0; This->Start = DS_Filter_Start; This->Stop = DS_Filter_Stop; @@ -127,40 +118,40 @@ DS_Filter* DS_FilterCreate(const char* dllname, const GUID* id, This->m_iHandle = LoadLibraryA(dllname); if (!This->m_iHandle) { - printf("Could not open DirectShow DLL: %.200s\n", dllname); + em = "could not open DirectShow DLL"; break; } func = (GETCLASS)GetProcAddress(This->m_iHandle, "DllGetClassObject"); if (!func) { - printf("Illegal or corrupt DirectShow DLL: %.200s\n", dllname); + em = "illegal or corrupt DirectShow DLL"; break; } result = func(id, &IID_IClassFactory, (void**)&factory); if (result || !factory) { - printf("No such class object\n"); + em = "no such class object"; break; } result = factory->vt->CreateInstance(factory, 0, &IID_IUnknown, (void**)&object); factory->vt->Release((IUnknown*)factory); if (result || !object) { - printf("Class factory failure\n"); + em = "class factory failure"; break; } result = object->vt->QueryInterface(object, &IID_IBaseFilter, (void**)&This->m_pFilter); object->vt->Release((IUnknown*)object); if (result || !This->m_pFilter) { - printf("Object does not have IBaseFilter interface\n"); + em = "object does not have IBaseFilter interface"; break; } // enumerate pins result = This->m_pFilter->vt->EnumPins(This->m_pFilter, &enum_pins); if (result || !enum_pins) { - printf("Could not enumerate pins\n"); + em = "could not enumerate pins"; break; } @@ -186,12 +177,12 @@ DS_Filter* DS_FilterCreate(const char* dllname, const GUID* id, } if (!This->m_pInputPin) { - printf("Input pin not found\n"); + em = "could not find input pin"; break; } if (!This->m_pOutputPin) { - printf("Output pin not found\n"); + em = "could not find output pin"; break; } result = This->m_pInputPin->vt->QueryInterface((IUnknown*)This->m_pInputPin, @@ -199,7 +190,7 @@ DS_Filter* DS_FilterCreate(const char* dllname, const GUID* id, (void**)&This->m_pImp); if (result) { - printf("Error getting IMemInputPin interface\n"); + em = "could not get IMemInputPin interface"; break; } @@ -208,7 +199,7 @@ DS_Filter* DS_FilterCreate(const char* dllname, const GUID* id, result = This->m_pInputPin->vt->QueryAccept(This->m_pInputPin, This->m_pOurType); if (result) { - printf("Source format is not accepted\n"); + em = "source format is not accepted"; break; } This->m_pParentFilter = CBaseFilter2Create(); @@ -221,7 +212,7 @@ DS_Filter* DS_FilterCreate(const char* dllname, const GUID* id, This->m_pOurType); if (result) { - printf("Error connecting to input pin\n"); + em = "could not connect to input pin"; break; } @@ -232,19 +223,19 @@ DS_Filter* DS_FilterCreate(const char* dllname, const GUID* id, This->m_pDestType); if (result) { - //printf("Tracking ACELP %d 0%x\n", result); - printf("Error connecting to output pin\n"); + em = "could not connect to output pin"; break; } printf("Using DirectShow codec: %s\n", dllname); - This->m_iState = 1; + init++; break; } - if (This->m_iState != 1) + if (!init) { DS_Filter_Destroy(This); + printf("Warning: DS_Filter() %s. (DLL=%.200s)\n", em, dllname); This = 0; } return This; diff --git a/loader/dshow/DS_Filter.h b/loader/dshow/DS_Filter.h index fd8166b11c..909217602b 100644 --- a/loader/dshow/DS_Filter.h +++ b/loader/dshow/DS_Filter.h @@ -29,7 +29,6 @@ struct _DS_Filter AM_MEDIA_TYPE *m_pOurType, *m_pDestType; IMemAllocator* m_pAll; IMemInputPin* m_pImp; - int m_iState; void ( *Start )(DS_Filter*); void ( *Stop )(DS_Filter*); diff --git a/loader/dshow/allocator.c b/loader/dshow/allocator.c index 6b960c570e..bc129dc422 100644 --- a/loader/dshow/allocator.c +++ b/loader/dshow/allocator.c @@ -69,6 +69,7 @@ static inline avm_list_t* avm_list_add_tail(avm_list_t* head, void* member) static inline avm_list_t* avm_list_del_head(avm_list_t* head) { avm_list_t* n = 0; + if (head) { if (head->next != head) @@ -77,10 +78,8 @@ static inline avm_list_t* avm_list_del_head(avm_list_t* head) head->prev->next = head->next; head->next->prev = head->prev; } - free(head); } - return n; } @@ -130,8 +129,12 @@ static HRESULT STDCALL MemAllocator_SetProperties(IMemAllocator * This, return E_FAIL; if (me->used_list != 0 || me->free_list != 0) return E_FAIL; - me->props = *pRequest; + *pActual = *pRequest; + //if (pActual->cbBuffer == 2) + // pActual->cbBuffer = 576; + + me->props = *pActual; return 0; } @@ -162,8 +165,9 @@ static HRESULT STDCALL MemAllocator_Commit(IMemAllocator * This) { CMediaSample* sample = CMediaSampleCreate((IMemAllocator*)me, me->props.cbBuffer); + if (!sample) + return E_OUTOFMEMORY; //printf("FREEEEEEEEEEEE ADDED %p\n", sample); - me->free_list = avm_list_add_tail(me->free_list, sample); //avm_list_print(me->free_list); } @@ -179,10 +183,8 @@ static HRESULT STDCALL MemAllocator_Decommit(IMemAllocator * This) //printf("Deleted mem %p: %d %d\n", me, me->free_list.size(), me->used_list.size()); while (me->used_list) { - CMediaSample* sample = (CMediaSample*) me->used_list->member; - //printf("****************** Decommiting USED %p\n", sample); - //sample->vt->Release((IUnknown*)sample); - CMediaSample_Destroy((CMediaSample*)sample); + me->free_list = avm_list_add_tail(me->free_list, + (CMediaSample*) me->used_list->member); me->used_list = avm_list_del_head(me->used_list); } @@ -192,7 +194,7 @@ static HRESULT STDCALL MemAllocator_Decommit(IMemAllocator * This) //printf("****************** Decommiting FREE %p\n", sample); //sample->vt->Release((IUnknown*)sample); CMediaSample_Destroy((CMediaSample*)sample); - me->free_list = avm_list_del_head(me->free_list); + me->free_list = avm_list_del_head(me->free_list); } return 0; @@ -206,8 +208,9 @@ static HRESULT STDCALL MemAllocator_GetBuffer(IMemAllocator * This, { MemAllocator* me = (MemAllocator*)This; CMediaSample* sample; - Debug printf("MemAllocator_GetBuffer(%p) called %d %d\n", This, + Debug printf("MemAllocator_ReleaseBuffer(%p) called %d %d\n", This, avm_list_size(me->used_list), avm_list_size(me->free_list)); + if (!me->free_list) { Debug printf("No samples available\n"); @@ -218,8 +221,6 @@ static HRESULT STDCALL MemAllocator_GetBuffer(IMemAllocator * This, me->free_list = avm_list_del_head(me->free_list); me->used_list = avm_list_add_tail(me->used_list, sample); - //printf("MemAllocator getbuffer: %p %d %d\n", sample, avm_list_size(me->used_list), avm_list_size(me->free_list)); - *ppBuffer = (IMediaSample*) sample; sample->vt->AddRef((IUnknown*) sample); if (me->new_pointer) @@ -236,24 +237,24 @@ static HRESULT STDCALL MemAllocator_GetBuffer(IMemAllocator * This, static HRESULT STDCALL MemAllocator_ReleaseBuffer(IMemAllocator* This, /* [in] */ IMediaSample* pBuffer) { + avm_list_t* l; MemAllocator* me = (MemAllocator*)This; Debug printf("MemAllocator_ReleaseBuffer(%p) called %d %d\n", This, avm_list_size(me->used_list), avm_list_size(me->free_list)); - for (;;) + l = avm_list_find(me->used_list, pBuffer); + if (l) { - avm_list_t* l = avm_list_find(me->used_list, pBuffer); - if (l) + CMediaSample* sample = (CMediaSample*) l->member; + if (me->modified_sample == sample) { - CMediaSample* sample = (CMediaSample*) l->member; - me->used_list = avm_list_del_head(me->used_list); - me->free_list = avm_list_add_head(me->free_list, sample); - //printf("****************** RELEASED OK %p %p\n", me->used_list, me->free_list); - - return 0; + me->modified_sample->ResetPointer(me->modified_sample); + me->modified_sample = 0; } - else - break; + me->used_list = avm_list_del_head(me->used_list); + me->free_list = avm_list_add_head(me->free_list, sample); + //printf("****************** RELEASED OK %p %p\n", me->used_list, me->free_list); + return 0; } Debug printf("MemAllocator_ReleaseBuffer(%p) releasing unknown buffer!!!! %p\n", This, pBuffer); return E_FAIL; @@ -288,6 +289,10 @@ IMPLEMENT_IUNKNOWN(MemAllocator) MemAllocator* MemAllocatorCreate() { MemAllocator* This = (MemAllocator*) malloc(sizeof(MemAllocator)); + + if (!This) + return NULL; + Debug printf("MemAllocatorCreate() called -> %p\n", This); This->refcount = 1; @@ -296,6 +301,13 @@ MemAllocator* MemAllocatorCreate() This->props.cbAlign = This->props.cbPrefix = 0; This->vt = (IMemAllocator_vt*) malloc(sizeof(IMemAllocator_vt)); + + if (!This->vt) + { + free(This); + return NULL; + } + This->vt->QueryInterface = MemAllocator_QueryInterface; This->vt->AddRef = MemAllocator_AddRef; This->vt->Release = MemAllocator_Release; @@ -309,8 +321,8 @@ MemAllocator* MemAllocatorCreate() This->SetPointer = MemAllocator_SetPointer; This->ResetPointer = MemAllocator_ResetPointer; - This->new_pointer = 0; This->modified_sample = 0; + This->new_pointer = 0; This->used_list = 0; This->free_list = 0; diff --git a/loader/dshow/cmediasample.c b/loader/dshow/cmediasample.c index d927bb2264..eba60dd4a0 100644 --- a/loader/dshow/cmediasample.c +++ b/loader/dshow/cmediasample.c @@ -45,10 +45,11 @@ void CMediaSample_Destroy(CMediaSample* This) static long STDCALL CMediaSample_Release(IUnknown* This) { - CMediaSample* parent=(CMediaSample*)This; + CMediaSample* parent = (CMediaSample*)This; Debug printf("CMediaSample_Release(%p) called (new ref:%d)\n", This, ((CMediaSample*)This)->refcount-1); - if (--((CMediaSample*)This)->refcount == 0) + + if (--((CMediaSample*) This)->refcount == 0) { parent->all->vt->ReleaseBuffer((IMemAllocator*)(parent->all), (IMediaSample*)This); @@ -56,28 +57,27 @@ static long STDCALL CMediaSample_Release(IUnknown* This) return 0; } -static HRESULT STDCALL CMediaSample_GetPointer(IMediaSample * This, - /* [out] */ BYTE **ppBuffer) +static HRESULT STDCALL CMediaSample_GetPointer(IMediaSample* This, + /* [out] */ BYTE** ppBuffer) { - Debug printf("CMediaSample_GetPointer(%p) called\n", This); + Debug printf("CMediaSample_GetPointer(%p) called -> %p, size: %d %d\n", This, ((CMediaSample*) This)->block, ((CMediaSample*)This)->actual_size, ((CMediaSample*)This)->size); if (!ppBuffer) return E_INVALIDARG; - *ppBuffer=(BYTE *)((CMediaSample*)This)->block; + *ppBuffer = (BYTE*) ((CMediaSample*) This)->block; return 0; } static long STDCALL CMediaSample_GetSize(IMediaSample * This) { - Debug printf("CMediaSample_GetSize(%p) called -> %d\n", - This, ((CMediaSample*)This)->size); - return ((CMediaSample*)This)->size; + Debug printf("CMediaSample_GetSize(%p) called -> %d\n", This, ((CMediaSample*) This)->size); + return ((CMediaSample*) This)->size; } static HRESULT STDCALL CMediaSample_GetTime(IMediaSample * This, /* [out] */ REFERENCE_TIME *pTimeStart, /* [out] */ REFERENCE_TIME *pTimeEnd) { - Debug printf("CMediaSample_GetTime(%p) called\n", This); + Debug printf("CMediaSample_GetTime(%p) called (UNIMPLIMENTED)\n", This); return E_NOTIMPL; } @@ -85,7 +85,7 @@ static HRESULT STDCALL CMediaSample_SetTime(IMediaSample * This, /* [in] */ REFERENCE_TIME *pTimeStart, /* [in] */ REFERENCE_TIME *pTimeEnd) { - Debug printf("CMediaSample_SetTime(%p) called\n", This); + Debug printf("CMediaSample_SetTime(%p) called (UNIMPLIMENTED)\n", This); return E_NOTIMPL; } @@ -101,7 +101,7 @@ static HRESULT STDCALL CMediaSample_SetSyncPoint(IMediaSample * This, long bIsSyncPoint) { Debug printf("CMediaSample_SetSyncPoint(%p) called\n", This); - ((CMediaSample*)This)->isSyncPoint=bIsSyncPoint; + ((CMediaSample*)This)->isSyncPoint = bIsSyncPoint; return 0; } @@ -132,12 +132,19 @@ static long STDCALL CMediaSample_GetActualDataLength(IMediaSample* This) static HRESULT STDCALL CMediaSample_SetActualDataLength(IMediaSample* This, long __MIDL_0010) { + CMediaSample* cms = (CMediaSample*)This; Debug printf("CMediaSample_SetActualDataLength(%p, %ld) called\n", This, __MIDL_0010); - if (__MIDL_0010 > ((CMediaSample*)This)->size) + if (__MIDL_0010 > cms->size) { - printf("%p: ERROR: CMediaSample buffer overflow\n", This); + char* c = cms->own_block; + Debug printf(" CMediaSample - buffer overflow %ld %d %p %p\n", + __MIDL_0010, ((CMediaSample*)This)->size, cms->own_block, cms->block); + cms->own_block = realloc(cms->own_block, __MIDL_0010); + if (c == cms->block) + cms->block = cms->own_block; + cms->size = __MIDL_0010; } - ((CMediaSample*)This)->actual_size = __MIDL_0010; + cms->actual_size = __MIDL_0010; return 0; } @@ -175,9 +182,14 @@ static HRESULT STDCALL CMediaSample_SetMediaType(IMediaSample * This, if (t->pbFormat) CoTaskMemFree(t->pbFormat); t = pMediaType; - t->pbFormat = (char*)CoTaskMemAlloc(t->cbFormat); - memcpy(t->pbFormat, pMediaType->pbFormat, t->cbFormat); - ((CMediaSample*)This)->type_valid=1; + if (t->cbFormat) + { + t->pbFormat = (char*)CoTaskMemAlloc(t->cbFormat); + memcpy(t->pbFormat, pMediaType->pbFormat, t->cbFormat); + } + else + t->pbFormat = 0; + ((CMediaSample*) This)->type_valid=1; return 0; } @@ -185,14 +197,15 @@ static HRESULT STDCALL CMediaSample_SetMediaType(IMediaSample * This, static HRESULT STDCALL CMediaSample_IsDiscontinuity(IMediaSample * This) { Debug printf("CMediaSample_IsDiscontinuity(%p) called\n", This); - return 1; + return ((CMediaSample*) This)->isDiscontinuity; } static HRESULT STDCALL CMediaSample_SetDiscontinuity(IMediaSample * This, long bDiscontinuity) { - Debug printf("CMediaSample_SetDiscontinuity(%p) called\n", This); - return E_NOTIMPL; + Debug printf("CMediaSample_SetDiscontinuity(%p) called (%ld)\n", This, bDiscontinuity); + ((CMediaSample*) This)->isDiscontinuity = bDiscontinuity; + return 0; } static HRESULT STDCALL CMediaSample_GetMediaTime(IMediaSample * This, @@ -200,7 +213,11 @@ static HRESULT STDCALL CMediaSample_GetMediaTime(IMediaSample * This, /* [out] */ LONGLONG *pTimeEnd) { Debug printf("CMediaSample_GetMediaTime(%p) called\n", This); - return E_NOTIMPL; + if (pTimeStart) + *pTimeStart = ((CMediaSample*) This)->time_start; + if (pTimeEnd) + *pTimeEnd = ((CMediaSample*) This)->time_end; + return 0; } static HRESULT STDCALL CMediaSample_SetMediaTime(IMediaSample * This, @@ -208,9 +225,14 @@ static HRESULT STDCALL CMediaSample_SetMediaTime(IMediaSample * This, /* [in] */ LONGLONG *pTimeEnd) { Debug printf("CMediaSample_SetMediaTime(%p) called\n", This); - return E_NOTIMPL; + if (pTimeStart) + ((CMediaSample*) This)->time_start = *pTimeStart; + if (pTimeEnd) + ((CMediaSample*) This)->time_end = *pTimeEnd; + return 0; } +// extension for direct memory write or decompressed data static void CMediaSample_SetPointer(CMediaSample* This, char* pointer) { Debug printf("CMediaSample_SetPointer(%p) called -> %p\n", This, pointer); @@ -228,8 +250,29 @@ static void CMediaSample_ResetPointer(CMediaSample* This) CMediaSample* CMediaSampleCreate(IMemAllocator* allocator, int _size) { - CMediaSample* This = (CMediaSample*) malloc(sizeof( CMediaSample )); + CMediaSample* This = (CMediaSample*) malloc(sizeof(CMediaSample)); + if (!This) + return NULL; + + // some hack here! + // it looks like Acelp decoder is actually accessing + // the allocated memory before it sets the new size for it ??? + // -- maybe it's being initialized with wrong parameters + // anyway this is fixes the problem somehow with some reserves + // + // using different trick for now - in DS_Audio modify sample size + //if (_size < 0x1000) + // _size = (_size + 0xfff) & ~0xfff; + This->vt = (IMediaSample_vt*) malloc(sizeof(IMediaSample_vt)); + This->own_block = (char*) malloc(_size); + This->media_type.pbFormat = 0; + + if (!This->vt || !This->own_block) + { + CMediaSample_Destroy(This); + return NULL; + } This->vt->QueryInterface = CMediaSample_QueryInterface; This->vt->AddRef = CMediaSample_AddRef; @@ -255,10 +298,11 @@ CMediaSample* CMediaSampleCreate(IMemAllocator* allocator, int _size) This->size = _size; This->refcount = 0; // increased by MemAllocator This->actual_size = 0; - This->media_type.pbFormat = 0; This->isPreroll = 0; + This->isDiscontinuity = 1; + This->time_start = 0; + This->time_end = 0; This->type_valid = 0; - This->own_block = (char*) malloc(This->size); This->block = This->own_block; This->SetPointer = CMediaSample_SetPointer; diff --git a/loader/dshow/cmediasample.h b/loader/dshow/cmediasample.h index 0b6b5b7881..3d6e1218ca 100644 --- a/loader/dshow/cmediasample.h +++ b/loader/dshow/cmediasample.h @@ -16,9 +16,12 @@ struct _CMediaSample char* own_block; int isPreroll; int isSyncPoint; + int isDiscontinuity; + LONGLONG time_start; + LONGLONG time_end; AM_MEDIA_TYPE media_type; int type_valid; - void ( *SetPointer) (CMediaSample* This,char* pointer); + void ( *SetPointer) (CMediaSample* This, char* pointer); void ( *ResetPointer) (CMediaSample* This); // FIXME replace with Set & 0 }; diff --git a/loader/dshow/guids.c b/loader/dshow/guids.c index 3a8096373e..393b5f90c5 100644 --- a/loader/dshow/guids.c +++ b/loader/dshow/guids.c @@ -1,5 +1,5 @@ #include "guids.h" -int DSHOW_DEBUG=0; +int DSHOW_DEBUG = 0; GUID CLSID_DivxDecompressorCF={0x82CCd3E0, 0xF71A, 0x11D0, { 0x9f, 0xe5, 0x00, 0x60, 0x97, 0x78, 0xaa, 0xaa}}; diff --git a/loader/dshow/guids.h b/loader/dshow/guids.h index 2d38d51f95..1c6355b389 100644 --- a/loader/dshow/guids.h +++ b/loader/dshow/guids.h @@ -2,13 +2,14 @@ #define GUIDS_H #include "com.h" -#include "wine/winbase.h" +#include "wine/module.h" +#include "wine/windef.h" #include "wine/vfw.h" extern int DSHOW_DEBUG; #define Debug if(DSHOW_DEBUG) -typedef struct _MediaType +typedef struct __attribute__((__packed__)) _MediaType { GUID majortype; //0x0 GUID subtype; //0x10 @@ -18,30 +19,31 @@ typedef struct _MediaType GUID formattype; //0x2c IUnknown* pUnk; //0x3c unsigned long cbFormat; //0x40 - char *pbFormat; //0x44 + char* pbFormat; //0x44 } AM_MEDIA_TYPE; typedef enum { - PINDIR_INPUT = 0, - PINDIR_OUTPUT = PINDIR_INPUT + 1 + PINDIR_INPUT = 0, + PINDIR_OUTPUT } PIN_DIRECTION; typedef long long REFERENCE_TIME; -typedef struct RECT32 +typedef struct __attribute__((__packed__)) RECT32 { int left, top, right, bottom; } RECT32; -typedef struct tagVIDEOINFOHEADER { +typedef struct __attribute__((__packed__)) tagVIDEOINFOHEADER { RECT32 rcSource; // The bit we really want to use RECT32 rcTarget; // Where the video should go unsigned long dwBitRate; // Approximate bit data rate unsigned long dwBitErrorRate; // Bit error rate for this stream REFERENCE_TIME AvgTimePerFrame; // Average time per frame (100ns units) - BITMAPINFOHEADER bmiHeader; + BITMAPINFOHEADER bmiHeader; + //int reserved[3]; } VIDEOINFOHEADER; typedef struct _AllocatorProperties diff --git a/loader/dshow/inputpin.c b/loader/dshow/inputpin.c index 2a4718e33f..89264ec086 100644 --- a/loader/dshow/inputpin.c +++ b/loader/dshow/inputpin.c @@ -17,11 +17,11 @@ static int unimplemented(const char* s, void* p) typedef struct { IEnumPins_vt* vt; + DECLARE_IUNKNOWN(); IPin* pin1; IPin* pin2; int counter; GUID interfaces[2]; - DECLARE_IUNKNOWN(); } CEnumPins; static long STDCALL CEnumPins_Next(IEnumPins* This, @@ -101,12 +101,20 @@ static CEnumPins* CEnumPinsCreate(IPin* p, IPin* pp) { CEnumPins* This = (CEnumPins*) malloc(sizeof(CEnumPins)); + if (!This) + return NULL; + + This->refcount = 1; This->pin1 = p; This->pin2 = pp; This->counter = 0; - This->refcount = 1; This->vt = (IEnumPins_vt*) malloc(sizeof(IEnumPins_vt)); + if (!This->vt) + { + free(This); + return NULL; + } This->vt->QueryInterface = CEnumPins_QueryInterface; This->vt->AddRef = CEnumPins_AddRef; This->vt->Release = CEnumPins_Release; @@ -261,11 +269,21 @@ CInputPin* CInputPinCreate(CBaseFilter* p, const AM_MEDIA_TYPE* amt) { CInputPin* This = (CInputPin*) malloc(sizeof(CInputPin)); - This->parent = p; + if (!This) + return NULL; + This->refcount = 1; + This->parent = p; This->type = *amt; This->vt= (IPin_vt*) malloc(sizeof(IPin_vt)); + + if (!This->vt) + { + free(This); + return NULL; + } + This->vt->QueryInterface = CInputPin_QueryInterface; This->vt->AddRef = CInputPin_AddRef; This->vt->Release = CInputPin_Release; @@ -395,9 +413,12 @@ static IPin* CBaseFilter_GetUnusedPin(CBaseFilter* This) static void CBaseFilter_Destroy(CBaseFilter* This) { - free(This->vt); - This->pin->vt->Release((IUnknown*)This->pin); - This->unused_pin->vt->Release((IUnknown*)This->unused_pin); + if (This->vt) + free(This->vt); + if (This->pin) + This->pin->vt->Release((IUnknown*)This->pin); + if (This->unused_pin) + This->unused_pin->vt->Release((IUnknown*)This->unused_pin); free(This); } @@ -406,12 +427,21 @@ IMPLEMENT_IUNKNOWN(CBaseFilter) CBaseFilter* CBaseFilterCreate(const AM_MEDIA_TYPE* type, CBaseFilter2* parent) { CBaseFilter* This = (CBaseFilter*) malloc(sizeof(CBaseFilter)); + if (!This) + return NULL; + This->refcount = 1; This->pin = (IPin*) CInputPinCreate(This, type); This->unused_pin = (IPin*) CRemotePinCreate(This, parent->GetPin(parent)); This->vt = (IBaseFilter_vt*) malloc(sizeof(IBaseFilter_vt)); + if (!This->vt || !This->pin || !This->unused_pin) + { + CBaseFilter_Destroy(This); + return NULL; + } + This->vt->QueryInterface = CBaseFilter_QueryInterface; This->vt->AddRef = CBaseFilter_AddRef; This->vt->Release = CBaseFilter_Release; @@ -541,8 +571,10 @@ static IPin* CBaseFilter2_GetPin(CBaseFilter2* This) static void CBaseFilter2_Destroy(CBaseFilter2* This) { Debug printf("CBaseFilter2_Destroy(%p) called\n", This); - This->pin->vt->Release((IUnknown*) This->pin); - free(This->vt); + if (This->pin) + This->pin->vt->Release((IUnknown*) This->pin); + if (This->vt) + free(This->vt); free(This); } @@ -559,10 +591,20 @@ CBaseFilter2* CBaseFilter2Create() { CBaseFilter2* This = (CBaseFilter2*) malloc(sizeof(CBaseFilter2)); + if (!This) + return NULL; + This->refcount = 1; This->pin = (IPin*) CRemotePin2Create(This); This->vt = (IBaseFilter_vt*) malloc(sizeof(IBaseFilter_vt)); + + if (!This->pin || !This->vt) + { + CBaseFilter2_Destroy(This); + return NULL; + } + memset(This->vt, 0, sizeof(IBaseFilter_vt)); This->vt->QueryInterface = CBaseFilter2_QueryInterface; This->vt->AddRef = CBaseFilter2_AddRef; @@ -646,6 +688,10 @@ IMPLEMENT_IUNKNOWN(CRemotePin) CRemotePin* CRemotePinCreate(CBaseFilter* pt, IPin* rpin) { CRemotePin* This = (CRemotePin*) malloc(sizeof(CRemotePin)); + + if (!This) + return NULL; + Debug printf("CRemotePinCreate() called -> %p\n", This); This->parent = pt; @@ -653,6 +699,13 @@ CRemotePin* CRemotePinCreate(CBaseFilter* pt, IPin* rpin) This->refcount = 1; This->vt = (IPin_vt*) malloc(sizeof(IPin_vt)); + + if (!This->vt) + { + free(This); + return NULL; + } + memset(This->vt, 0, sizeof(IPin_vt)); This->vt->QueryInterface = CRemotePin_QueryInterface; This->vt->AddRef = CRemotePin_AddRef; @@ -698,12 +751,23 @@ IMPLEMENT_IUNKNOWN(CRemotePin2) CRemotePin2* CRemotePin2Create(CBaseFilter2* p) { CRemotePin2* This = (CRemotePin2*) malloc(sizeof(CRemotePin2)); + + if (!This) + return NULL; + Debug printf("CRemotePin2Create() called -> %p\n", This); This->parent = p; This->refcount = 1; This->vt = (IPin_vt*) malloc(sizeof(IPin_vt)); + + if (!This->vt) + { + free(This); + return NULL; + } + memset(This->vt, 0, sizeof(IPin_vt)); This->vt->QueryInterface = CRemotePin2_QueryInterface; This->vt->AddRef = CRemotePin2_AddRef; diff --git a/loader/dshow/inputpin.h b/loader/dshow/inputpin.h index 7c96624f51..1ad9a2d608 100644 --- a/loader/dshow/inputpin.h +++ b/loader/dshow/inputpin.h @@ -38,8 +38,8 @@ struct _CInputPin { IPin_vt* vt; DECLARE_IUNKNOWN(); - AM_MEDIA_TYPE type; CBaseFilter* parent; + AM_MEDIA_TYPE type; GUID interfaces[1]; }; diff --git a/loader/dshow/interfaces.h b/loader/dshow/interfaces.h index ab5069d854..23b02a5090 100644 --- a/loader/dshow/interfaces.h +++ b/loader/dshow/interfaces.h @@ -84,13 +84,17 @@ typedef struct IEnumPins_vt { INHERIT_IUNKNOWN(); + // retrieves a specified number of pins in the enumeration sequence.. HRESULT STDCALL ( *Next )(IEnumPins* This, /* [in] */ unsigned long cPins, /* [size_is][out] */ IPin** ppPins, /* [out] */ unsigned long* pcFetched); + // skips over a specified number of pins. HRESULT STDCALL ( *Skip )(IEnumPins* This, /* [in] */ unsigned long cPins); + // resets the enumeration sequence to the beginning. HRESULT STDCALL ( *Reset )(IEnumPins* This); + // makes a copy of the enumerator with the same enumeration state. HRESULT STDCALL ( *Clone )(IEnumPins* This, /* [out] */ IEnumPins** ppEnum); } IEnumPins_vt; @@ -111,25 +115,46 @@ typedef struct IMediaSample_vt HRESULT STDCALL ( *SetTime )(IMediaSample* This, /* [in] */ REFERENCE_TIME* pTimeStart, /* [in] */ REFERENCE_TIME* pTimeEnd); + + // sync-point property. If true, then the beginning of this + // sample is a sync-point. (note that if AM_MEDIA_TYPE.bTemporalCompression + // is false then all samples are sync points). A filter can start + // a stream at any sync point. S_FALSE if not sync-point, S_OK if true. HRESULT STDCALL ( *IsSyncPoint )(IMediaSample* This); HRESULT STDCALL ( *SetSyncPoint )(IMediaSample* This, long bIsSyncPoint); + + // preroll property. If true, this sample is for preroll only and + // shouldn't be displayed. HRESULT STDCALL ( *IsPreroll )(IMediaSample* This); HRESULT STDCALL ( *SetPreroll )(IMediaSample* This, long bIsPreroll); + LONG STDCALL ( *GetActualDataLength )(IMediaSample* This); HRESULT STDCALL ( *SetActualDataLength )(IMediaSample* This, long __MIDL_0010); + + // these allow for limited format changes in band - if no format change + // has been made when you receive a sample GetMediaType will return S_FALSE HRESULT STDCALL ( *GetMediaType )(IMediaSample* This, AM_MEDIA_TYPE** ppMediaType); HRESULT STDCALL ( *SetMediaType )(IMediaSample* This, AM_MEDIA_TYPE* pMediaType); + + // returns S_OK if there is a discontinuity in the data (this frame is + // not a continuation of the previous stream of data + // - there has been a seek or some dropped samples). HRESULT STDCALL ( *IsDiscontinuity )(IMediaSample* This); HRESULT STDCALL ( *SetDiscontinuity )(IMediaSample* This, long bDiscontinuity); + + // get the media times for this sample HRESULT STDCALL ( *GetMediaTime )(IMediaSample* This, /* [out] */ long long* pTimeStart, /* [out] */ long long* pTimeEnd); + // Set the media times for this sample + // pTimeStart==pTimeEnd==NULL will invalidate the media time stamps in |