diff options
Diffstat (limited to 'src')
24 files changed, 1671 insertions, 164 deletions
diff --git a/src/libw32dll/DirectShow/DS_AudioDecoder.c b/src/libw32dll/DirectShow/DS_AudioDecoder.c index 6f2cedbf3..79118efb9 100644 --- a/src/libw32dll/DirectShow/DS_AudioDecoder.c +++ b/src/libw32dll/DirectShow/DS_AudioDecoder.c @@ -30,18 +30,6 @@ struct _DS_AudioDecoder #include <stdlib.h> #define __MODULE__ "DirectShow audio decoder" -const GUID FORMAT_WaveFormatEx = { - 0x05589f81, 0xc356, 0x11CE, - { 0xBF, 0x01, 0x00, 0xAA, 0x00, 0x55, 0x59, 0x5A } -}; -const GUID MEDIATYPE_Audio = { - 0x73647561, 0x0000, 0x0010, - { 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71 } -}; -const GUID MEDIASUBTYPE_PCM = { - 0x00000001, 0x0000, 0x0010, - { 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71 } -}; typedef long STDCALL (*GETCLASS) (GUID*, GUID*, void**); diff --git a/src/libw32dll/DirectShow/DS_Filter.c b/src/libw32dll/DirectShow/DS_Filter.c index 09b49532b..cfa583535 100644 --- a/src/libw32dll/DirectShow/DS_Filter.c +++ b/src/libw32dll/DirectShow/DS_Filter.c @@ -3,10 +3,12 @@ #include "com.h" #include <stdio.h> #include <string.h> +#include <stdlib.h> +#include "win32.h" // printf macro typedef long STDCALL (*GETCLASS) (const GUID*, const GUID*, void**); -//extern "C" STDCALL void* GetProcAddress(int, const char*); // STDCALL has to be first NetBSD +//void trapbug(); static void DS_Filter_Start(DS_Filter* This) { @@ -16,7 +18,7 @@ static void DS_Filter_Start(DS_Filter* This) return; //Debug printf("DS_Filter_Start(%p)\n", This); - hr = This->m_pFilter->vt->Run(This->m_pFilter, 0); + hr = This->m_pFilter->vt->Run(This->m_pFilter, (REFERENCE_TIME)0); if (hr != 0) { Debug printf("WARNING: m_Filter->Run() failed, error code %x\n", (int)hr); @@ -71,7 +73,7 @@ void DS_Filter_Destroy(DS_Filter* This) // FIXME - we are still leaving few things allocated! if (This->m_iHandle) - FreeLibrary(This->m_iHandle); + FreeLibrary((unsigned)This->m_iHandle); free(This); @@ -82,6 +84,7 @@ DS_Filter* DS_FilterCreate(const char* dllname, const GUID* id, AM_MEDIA_TYPE* in_fmt, AM_MEDIA_TYPE* out_fmt) { + HRESULT result = 0; int init = 0; /* char eb[250]; -- unused */ const char* em = NULL; @@ -106,7 +109,6 @@ DS_Filter* DS_FilterCreate(const char* dllname, const GUID* id, for (;;) { - HRESULT result; GETCLASS func; struct IClassFactory* factory = NULL; struct IUnknown* object = NULL; @@ -121,7 +123,7 @@ DS_Filter* DS_FilterCreate(const char* dllname, const GUID* id, em = "could not open DirectShow DLL"; break; } - func = (GETCLASS)GetProcAddress(This->m_iHandle, "DllGetClassObject"); + func = (GETCLASS)GetProcAddress((unsigned)This->m_iHandle, "DllGetClassObject"); if (!func) { em = "illegal or corrupt DirectShow DLL"; @@ -144,7 +146,7 @@ DS_Filter* DS_FilterCreate(const char* dllname, const GUID* id, object->vt->Release((IUnknown*)object); if (result || !This->m_pFilter) { - em = "object does not have IBaseFilter interface"; + em = "object does not provide IBaseFilter interface"; break; } // enumerate pins @@ -217,7 +219,6 @@ DS_Filter* DS_FilterCreate(const char* dllname, const GUID* id, } This->m_pOurOutput = COutputPinCreate(This->m_pDestType); - result = This->m_pOutputPin->vt->ReceiveConnection(This->m_pOutputPin, (IPin*) This->m_pOurOutput, This->m_pDestType); @@ -235,7 +236,7 @@ DS_Filter* DS_FilterCreate(const char* dllname, const GUID* id, if (!init) { DS_Filter_Destroy(This); - printf("Warning: DS_Filter() %s. (DLL=%.200s)\n", em, dllname); + printf("Warning: DS_Filter() %s. (DLL=%.200s, r=0x%x)\n", em, dllname, result); This = 0; } return This; diff --git a/src/libw32dll/DirectShow/allocator.c b/src/libw32dll/DirectShow/allocator.c index 0f7bf6838..cf4848da5 100644 --- a/src/libw32dll/DirectShow/allocator.c +++ b/src/libw32dll/DirectShow/allocator.c @@ -2,9 +2,17 @@ #include "com.h" #include "../wine/winerror.h" #include <stdio.h> +#include <stdlib.h> static int AllocatorKeeper = 0; +struct _avm_list_t +{ + struct _avm_list_t* next; + struct _avm_list_t* prev; + void* member; +}; + static inline int avm_list_size(avm_list_t* head) { avm_list_t* it = head; @@ -100,7 +108,7 @@ static inline avm_list_t* avm_list_find(avm_list_t* head, void* member) return NULL; } -static long MemAllocator_CreateAllocator(GUID* clsid, GUID* iid, void** ppv) +static long MemAllocator_CreateAllocator(GUID* clsid, const GUID* iid, void** ppv) { IMemAllocator* p; int result; @@ -275,7 +283,7 @@ static void MemAllocator_ResetPointer(MemAllocator* This) } } -void MemAllocator_Destroy(MemAllocator* This) +static void MemAllocator_Destroy(MemAllocator* This) { Debug printf("MemAllocator_Destroy(%p) called (%d, %d)\n", This, This->refcount, AllocatorKeeper); if (--AllocatorKeeper == 0) diff --git a/src/libw32dll/DirectShow/allocator.h b/src/libw32dll/DirectShow/allocator.h index 855637063..ef1efd737 100644 --- a/src/libw32dll/DirectShow/allocator.h +++ b/src/libw32dll/DirectShow/allocator.h @@ -4,14 +4,9 @@ #include "interfaces.h" #include "cmediasample.h" -typedef struct avm_list_t -{ - struct avm_list_t* next; - struct avm_list_t* prev; - void* member; -} avm_list_t; - +typedef struct _avm_list_t avm_list_t; typedef struct _MemAllocator MemAllocator; + struct _MemAllocator { IMemAllocator_vt* vt; @@ -27,6 +22,6 @@ struct _MemAllocator void ( *ResetPointer )(MemAllocator* This); }; -MemAllocator* MemAllocatorCreate(); +MemAllocator* MemAllocatorCreate(void); #endif /* DS_ALLOCATOR_H */ diff --git a/src/libw32dll/DirectShow/cmediasample.c b/src/libw32dll/DirectShow/cmediasample.c index 56a10c09a..0d997d103 100644 --- a/src/libw32dll/DirectShow/cmediasample.c +++ b/src/libw32dll/DirectShow/cmediasample.c @@ -2,9 +2,17 @@ #include "../wine/winerror.h" #include <stdio.h> #include <string.h> +#include <stdlib.h> + +/* + * currently hack to make some extra room for DS Acel codec which + * seems to overwrite allocated memory - FIXME better later + * check the buffer allocation + */ +static const int SAFETY_ACEL = 1024; static long STDCALL CMediaSample_QueryInterface(IUnknown* This, - /* [in] */ IID* iid, + /* [in] */ const GUID* iid, /* [iid_is][out] */ void **ppv) { Debug printf("CMediaSample_QueryInterface(%p) called\n", This); @@ -77,7 +85,7 @@ static HRESULT STDCALL CMediaSample_GetTime(IMediaSample * This, /* [out] */ REFERENCE_TIME *pTimeStart, /* [out] */ REFERENCE_TIME *pTimeEnd) { - Debug printf("CMediaSample_GetTime(%p) called (UNIMPLIMENTED)\n", This); + Debug printf("CMediaSample_GetTime(%p) called (UNIMPLEMENTED)\n", This); return E_NOTIMPL; } @@ -85,7 +93,7 @@ static HRESULT STDCALL CMediaSample_SetTime(IMediaSample * This, /* [in] */ REFERENCE_TIME *pTimeStart, /* [in] */ REFERENCE_TIME *pTimeEnd) { - Debug printf("CMediaSample_SetTime(%p) called (UNIMPLIMENTED)\n", This); + Debug printf("CMediaSample_SetTime(%p) called (UNIMPLEMENTED)\n", This); return E_NOTIMPL; } @@ -134,12 +142,13 @@ static HRESULT STDCALL CMediaSample_SetActualDataLength(IMediaSample* This, { CMediaSample* cms = (CMediaSample*)This; Debug printf("CMediaSample_SetActualDataLength(%p, %ld) called\n", This, __MIDL_0010); + if (__MIDL_0010 > cms->size) { char* c = cms->own_block; - Debug printf(" CMediaSample - buffer overflow %ld %d %p %p\n", + 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); + cms->own_block = (char*) realloc(cms->own_block, (size_t) __MIDL_0010 + SAFETY_ACEL); if (c == cms->block) cms->block = cms->own_block; cms->size = __MIDL_0010; @@ -265,7 +274,7 @@ CMediaSample* CMediaSampleCreate(IMemAllocator* allocator, int _size) // _size = (_size + 0xfff) & ~0xfff; This->vt = (IMediaSample_vt*) malloc(sizeof(IMediaSample_vt)); - This->own_block = (char*) malloc(_size); + This->own_block = (char*) malloc((size_t)_size + SAFETY_ACEL); This->media_type.pbFormat = 0; if (!This->vt || !This->own_block) diff --git a/src/libw32dll/DirectShow/guids.c b/src/libw32dll/DirectShow/guids.c index f1ee0aaa3..73cf7f545 100644 --- a/src/libw32dll/DirectShow/guids.c +++ b/src/libw32dll/DirectShow/guids.c @@ -1,68 +1,79 @@ #include "guids.h" -int DSHOW_DEBUG = 0; -GUID CLSID_DivxDecompressorCF={0x82CCd3E0, 0xF71A, 0x11D0, +const GUID CLSID_DivxDecompressorCF={0x82CCd3E0, 0xF71A, 0x11D0, { 0x9f, 0xe5, 0x00, 0x60, 0x97, 0x78, 0xaa, 0xaa}}; -GUID IID_IDivxFilterInterface={0xd132ee97, 0x3e38, 0x4030, +const GUID IID_IDivxFilterInterface={0xd132ee97, 0x3e38, 0x4030, {0x8b, 0x17, 0x59, 0x16, 0x3b, 0x30, 0xa1, 0xf5}}; -GUID CLSID_IV50_Decoder={0x30355649, 0x0000, 0x0010, +const GUID CLSID_IV50_Decoder={0x30355649, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; -GUID IID_IBaseFilter={0x56a86895, 0x0ad4, 0x11ce, +const GUID IID_IBaseFilter={0x56a86895, 0x0ad4, 0x11ce, {0xb0, 0x3a, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}}; -GUID IID_IEnumPins={0x56a86892, 0x0ad4, 0x11ce, +const GUID IID_IEnumPins={0x56a86892, 0x0ad4, 0x11ce, {0xb0, 0x3a, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}}; -GUID IID_IEnumMediaTypes={0x89c31040, 0x846b, 0x11ce, +const GUID IID_IEnumMediaTypes={0x89c31040, 0x846b, 0x11ce, {0x97, 0xd3, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}}; -GUID IID_IMemInputPin={0x56a8689d, 0x0ad4, 0x11ce, +const GUID IID_IMemInputPin={0x56a8689d, 0x0ad4, 0x11ce, {0xb0, 0x3a, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}}; -GUID IID_IMemAllocator={0x56a8689c, 0x0ad4, 0x11ce, +const GUID IID_IMemAllocator={0x56a8689c, 0x0ad4, 0x11ce, {0xb0, 0x3a, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}}; -GUID IID_IMediaSample={0x56a8689a, 0x0ad4, 0x11ce, +const GUID IID_IMediaSample={0x56a8689a, 0x0ad4, 0x11ce, {0xb0, 0x3a, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}}; -GUID MEDIATYPE_Video={0x73646976, 0x0000, 0x0010, +const GUID MEDIATYPE_Video={0x73646976, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; -GUID GUID_NULL={0x0, 0x0, 0x0, +const GUID GUID_NULL={0x0, 0x0, 0x0, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}; -GUID FORMAT_VideoInfo={0x05589f80, 0xc356, 0x11ce, +const GUID FORMAT_VideoInfo={0x05589f80, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}}; -GUID MEDIASUBTYPE_RGB565={0xe436eb7b, 0x524f, 0x11ce, +const GUID MEDIASUBTYPE_RGB1={0xe436eb78, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}}; -GUID MEDIASUBTYPE_RGB555={0xe436eb7c, 0x524f, 0x11ce, +const GUID MEDIASUBTYPE_RGB4={0xe436eb79, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}}; -GUID MEDIASUBTYPE_RGB24={0xe436eb7d, 0x524f, 0x11ce, +const GUID MEDIASUBTYPE_RGB8={0xe436eb7a, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}}; -GUID MEDIASUBTYPE_RGB32={0xe436eb7e, 0x524f, 0x11ce, +const GUID MEDIASUBTYPE_RGB565={0xe436eb7b, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}}; -GUID MEDIASUBTYPE_YUYV={0x56595559, 0x0000, 0x0010, +const GUID MEDIASUBTYPE_RGB555={0xe436eb7c, 0x524f, 0x11ce, + {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}}; +const GUID MEDIASUBTYPE_RGB24={0xe436eb7d, 0x524f, 0x11ce, + {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}}; +const GUID MEDIASUBTYPE_RGB32={0xe436eb7e, 0x524f, 0x11ce, + {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}}; +const GUID MEDIASUBTYPE_YUYV={0x56595559, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; -GUID MEDIASUBTYPE_IYUV={0x56555949, 0x0000, 0x0010, +const GUID MEDIASUBTYPE_IYUV={0x56555949, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; -GUID MEDIASUBTYPE_YVU9={0x39555659, 0x0000, 0x0010, +const GUID MEDIASUBTYPE_YVU9={0x39555659, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; -GUID MEDIASUBTYPE_Y411={0x31313459, 0x0000, 0x0010, +const GUID MEDIASUBTYPE_Y411={0x31313459, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; -GUID MEDIASUBTYPE_Y41P={0x50313459, 0x0000, 0x0010, +const GUID MEDIASUBTYPE_Y41P={0x50313459, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; -GUID MEDIASUBTYPE_YUY2={0x32595559, 0x0000, 0x0010, +const GUID MEDIASUBTYPE_YUY2={0x32595559, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; -GUID MEDIASUBTYPE_YVYU={0x55595659, 0x0000, 0x0010, +const GUID MEDIASUBTYPE_YVYU={0x55595659, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; -GUID MEDIASUBTYPE_UYVY={0x59565955, 0x0000, 0x0010, +const GUID MEDIASUBTYPE_UYVY={0x59565955, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; -GUID MEDIASUBTYPE_Y211={0x31313259, 0x0000, 0x0010, +const GUID MEDIASUBTYPE_Y211={0x31313259, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; -GUID MEDIASUBTYPE_YV12={0x32315659, 0x0000, 0x0010, +const GUID MEDIASUBTYPE_YV12={0x32315659, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; -GUID MEDIASUBTYPE_I420={0x30323449, 0x0000, 0x0010, +const GUID MEDIASUBTYPE_I420={0x30323449, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; -GUID MEDIASUBTYPE_IF09={0x39304649, 0x0000, 0x0010, +const GUID MEDIASUBTYPE_IF09={0x39304649, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; -GUID CLSID_MemoryAllocator={0x1e651cc0, 0xb199, 0x11d0, +const GUID CLSID_MemoryAllocator={0x1e651cc0, 0xb199, 0x11d0, {0x82, 0x12, 0x00, 0xc0, 0x4f, 0xc3, 0x2c, 0x45}}; -GUID IID_DivxHidden={0x598eba01, 0xb49a, 0x11d2, +const GUID IID_DivxHidden={0x598eba01, 0xb49a, 0x11d2, {0xa1, 0xc1, 0x00, 0x60, 0x97, 0x78, 0xaa, 0xaa}}; -GUID IID_Iv50Hidden={0x665a4442, 0xd905, 0x11d0, +const GUID IID_Iv50Hidden={0x665a4442, 0xd905, 0x11d0, {0xa3, 0x0e, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}; +const GUID FORMAT_WaveFormatEx = {0x05589f81, 0xc356, 0x11CE, + {0xBF, 0x01, 0x00, 0xAA, 0x00, 0x55, 0x59, 0x5A}}; +const GUID MEDIATYPE_Audio = {0x73647561, 0x0000, 0x0010, + {0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71}}; +const GUID MEDIASUBTYPE_PCM = {0x00000001, 0x0000, 0x0010, + {0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71}}; diff --git a/src/libw32dll/DirectShow/guids.h b/src/libw32dll/DirectShow/guids.h index b17c80662..aea96801c 100644 --- a/src/libw32dll/DirectShow/guids.h +++ b/src/libw32dll/DirectShow/guids.h @@ -1,13 +1,13 @@ -#ifndef GUIDS_H -#define GUIDS_H +#ifndef DS_GUIDS_H +#define DS_GUIDS_H #include "com.h" #include "../wine/module.h" #include "../wine/windef.h" #include "../wine/vfw.h" -extern int DSHOW_DEBUG; -#define Debug if(DSHOW_DEBUG) +//#define Debug if(1) +#define Debug if(0) typedef struct __attribute__((__packed__)) _MediaType { @@ -22,12 +22,6 @@ typedef struct __attribute__((__packed__)) _MediaType char* pbFormat; //0x44 } AM_MEDIA_TYPE; -typedef enum -{ - PINDIR_INPUT = 0, - PINDIR_OUTPUT -} PIN_DIRECTION; - typedef long long REFERENCE_TIME; typedef struct __attribute__((__packed__)) RECT32 @@ -35,8 +29,8 @@ typedef struct __attribute__((__packed__)) RECT32 int left, top, right, bottom; } RECT32; -typedef struct __attribute__((__packed__)) 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 @@ -46,52 +40,46 @@ typedef struct __attribute__((__packed__)) tagVIDEOINFOHEADER { //int reserved[3]; } VIDEOINFOHEADER; -typedef struct _AllocatorProperties -{ - long cBuffers; - long cbBuffer; - long cbAlign; - long cbPrefix; -} ALLOCATOR_PROPERTIES; - -typedef struct _IBaseFilter IBaseFilter; -typedef struct _PinInfo -{ - IBaseFilter* pFilter; - PIN_DIRECTION dir; - unsigned short achName[128]; -} PIN_INFO; +typedef GUID CLSID; +typedef GUID IID; +extern const GUID IID_IBaseFilter; +extern const GUID IID_IEnumPins; +extern const GUID IID_IEnumMediaTypes; +extern const GUID IID_IMemInputPin; +extern const GUID IID_IMemAllocator; +extern const GUID IID_IMediaSample; +extern const GUID IID_DivxHidden; +extern const GUID IID_Iv50Hidden; +extern const GUID CLSID_DivxDecompressorCF; +extern const GUID IID_IDivxFilterInterface; +extern const GUID CLSID_IV50_Decoder; +extern const GUID CLSID_MemoryAllocator; +extern const GUID MEDIATYPE_Video; +extern const GUID GUID_NULL; +extern const GUID FORMAT_VideoInfo; +extern const GUID MEDIASUBTYPE_RGB1; +extern const GUID MEDIASUBTYPE_RGB4; +extern const GUID MEDIASUBTYPE_RGB8; +extern const GUID MEDIASUBTYPE_RGB565; +extern const GUID MEDIASUBTYPE_RGB555; +extern const GUID MEDIASUBTYPE_RGB24; +extern const GUID MEDIASUBTYPE_RGB32; +extern const GUID MEDIASUBTYPE_YUYV; +extern const GUID MEDIASUBTYPE_IYUV; +extern const GUID MEDIASUBTYPE_YVU9; +extern const GUID MEDIASUBTYPE_Y411; +extern const GUID MEDIASUBTYPE_Y41P; +extern const GUID MEDIASUBTYPE_YUY2; +extern const GUID MEDIASUBTYPE_YVYU; +extern const GUID MEDIASUBTYPE_UYVY; +extern const GUID MEDIASUBTYPE_Y211; +extern const GUID MEDIASUBTYPE_YV12; +extern const GUID MEDIASUBTYPE_I420; +extern const GUID MEDIASUBTYPE_IF09; -extern GUID IID_IBaseFilter; -extern GUID IID_IEnumPins; -extern GUID IID_IEnumMediaTypes; -extern GUID IID_IMemInputPin; -extern GUID IID_IMemAllocator; -extern GUID IID_IMediaSample; -extern GUID IID_DivxHidden; -extern GUID IID_Iv50Hidden; -extern GUID CLSID_DivxDecompressorCF; -extern GUID IID_IDivxFilterInterface; -extern GUID CLSID_IV50_Decoder; -extern GUID CLSID_MemoryAllocator; -extern GUID MEDIATYPE_Video; -extern GUID GUID_NULL; -extern GUID FORMAT_VideoInfo; -extern GUID MEDIASUBTYPE_RGB565; -extern GUID MEDIASUBTYPE_RGB555; -extern GUID MEDIASUBTYPE_RGB24; -extern GUID MEDIASUBTYPE_RGB32; -extern GUID MEDIASUBTYPE_YUYV; -extern GUID MEDIASUBTYPE_IYUV; -extern GUID MEDIASUBTYPE_YVU9; -extern GUID MEDIASUBTYPE_Y411; -extern GUID MEDIASUBTYPE_Y41P; -extern GUID MEDIASUBTYPE_YUY2; -extern GUID MEDIASUBTYPE_YVYU; -extern GUID MEDIASUBTYPE_UYVY; -extern GUID MEDIASUBTYPE_Y211; -extern GUID MEDIASUBTYPE_YV12; -extern GUID MEDIASUBTYPE_I420; +extern const GUID FORMAT_WaveFormatEx; +extern const GUID MEDIATYPE_Audio; +extern const GUID MEDIASUBTYPE_PCM; -#endif +#endif /* DS_GUIDS_H */ diff --git a/src/libw32dll/DirectShow/inputpin.h b/src/libw32dll/DirectShow/inputpin.h index 1ad9a2d60..a8ccdcccf 100644 --- a/src/libw32dll/DirectShow/inputpin.h +++ b/src/libw32dll/DirectShow/inputpin.h @@ -14,7 +14,7 @@ struct _CBaseFilter2 IPin* ( *GetPin )(CBaseFilter2* This); }; -CBaseFilter2* CBaseFilter2Create(); +CBaseFilter2* CBaseFilter2Create(void); typedef struct _CBaseFilter CBaseFilter; @@ -33,20 +33,19 @@ struct _CBaseFilter CBaseFilter* CBaseFilterCreate(const AM_MEDIA_TYPE* vhdr, CBaseFilter2* parent); -typedef struct _CInputPin CInputPin; -struct _CInputPin +typedef struct { IPin_vt* vt; DECLARE_IUNKNOWN(); CBaseFilter* parent; AM_MEDIA_TYPE type; GUID interfaces[1]; -}; +} CInputPin; CInputPin* CInputPinCreate(CBaseFilter* parent, const AM_MEDIA_TYPE* vhdr); -typedef struct CRemotePin +typedef struct { IPin_vt* vt; DECLARE_IUNKNOWN(); @@ -58,7 +57,7 @@ typedef struct CRemotePin CRemotePin* CRemotePinCreate(CBaseFilter* pt, IPin* rpin); -typedef struct CRemotePin2 +typedef struct { IPin_vt* vt; DECLARE_IUNKNOWN(); diff --git a/src/libw32dll/DirectShow/interfaces.h b/src/libw32dll/DirectShow/interfaces.h index 23b02a509..92a7718cd 100644 --- a/src/libw32dll/DirectShow/interfaces.h +++ b/src/libw32dll/DirectShow/interfaces.h @@ -2,26 +2,41 @@ #define DS_INTERFACES_H /* - -Definition of important DirectShow interfaces. -Created using freely-available DirectX 8.0 SDK -( http://msdn.microsoft.com ) - -*/ + * Definition of important DirectShow interfaces. + * Created using freely-available DirectX 8.0 SDK + * ( http://msdn.microsoft.com ) + */ #include "iunk.h" #include "com.h" -//typedef GUID& REFIID; -typedef GUID CLSID; -typedef GUID IID; - /* Sh*t. MSVC++ and g++ use different methods of storing vtables. */ typedef struct _IReferenceClock IReferenceClock; typedef struct _IFilterGraph IFilterGraph; -enum PIN_DIRECTION; +typedef struct _IBaseFilter IBaseFilter; + +typedef enum +{ + PINDIR_INPUT = 0, + PINDIR_OUTPUT +} PIN_DIRECTION; + +typedef struct _PinInfo +{ + IBaseFilter* pFilter; + PIN_DIRECTION dir; + unsigned short achName[128]; +} PIN_INFO; + +typedef struct _AllocatorProperties +{ + long cBuffers; + long cbBuffer; + long cbAlign; + long cbPrefix; +} ALLOCATOR_PROPERTIES; typedef struct _IEnumMediaTypes IEnumMediaTypes; typedef struct IEnumMediaTypes_vt diff --git a/src/libw32dll/DirectShow/iunk.h b/src/libw32dll/DirectShow/iunk.h index 6dbf00ffa..7998011cd 100644 --- a/src/libw32dll/DirectShow/iunk.h +++ b/src/libw32dll/DirectShow/iunk.h @@ -2,10 +2,9 @@ #define DS_IUNK_H #include "guids.h" -#include <stdlib.h> #define INHERIT_IUNKNOWN() \ - long STDCALL ( *QueryInterface )(IUnknown * This, GUID* riid, void **ppvObject); \ + long STDCALL ( *QueryInterface )(IUnknown * This, const GUID* riid, void **ppvObject); \ long STDCALL ( *AddRef )(IUnknown * This); \ long STDCALL ( *Release )(IUnknown * This); @@ -14,12 +13,12 @@ #define IMPLEMENT_IUNKNOWN(CLASSNAME) \ static long STDCALL CLASSNAME ## _QueryInterface(IUnknown * This, \ - GUID* riid, void **ppvObject) \ + const GUID* riid, void **ppvObject) \ { \ CLASSNAME * me = (CLASSNAME *)This; \ - GUID* r; unsigned int i = 0; \ + const GUID* r; unsigned int i = 0; \ Debug printf(#CLASSNAME "_QueryInterface(%p) called\n", This);\ - if (!ppvObject) return 0x80004003; \ + if (!ppvObject) return E_POINTER; \ for(r=me->interfaces; i<sizeof(me->interfaces)/sizeof(me->interfaces[0]); r++, i++) \ if(!memcmp(r, riid, sizeof(*r))) \ { \ @@ -27,7 +26,7 @@ static long STDCALL CLASSNAME ## _QueryInterface(IUnknown * This, \ *ppvObject=This; \ return 0; \ } \ - Debug printf("Query failed!\n"); \ + Debug printf("Query failed! (GUID: 0x%x)\n", *(const unsigned int*)riid); \ return E_NOINTERFACE; \ } \ \ diff --git a/src/libw32dll/DirectShow/outputpin.c b/src/libw32dll/DirectShow/outputpin.c index 8ca12d792..e6317a985 100644 --- a/src/libw32dll/DirectShow/outputpin.c +++ b/src/libw32dll/DirectShow/outputpin.c @@ -4,6 +4,7 @@ #include "outputpin.h" #include <stdio.h> #include <string.h> +#include <stdlib.h> /* An object beyond interface IEnumMediaTypes. @@ -24,6 +25,15 @@ typedef struct CEnumMediaTypes GUID interfaces[2]; } CEnumMediaTypes; +struct _COutputMemPin +{ + IMemInputPin_vt* vt; + DECLARE_IUNKNOWN(); + char** frame_pointer; + long* frame_size_pointer; + MemAllocator* pAllocator; + COutputPin* parent; +}; static HRESULT STDCALL CEnumMediaTypes_Next(IEnumMediaTypes * This, /* [in] */ ULONG cMediaTypes, @@ -74,7 +84,7 @@ static HRESULT STDCALL CEnumMediaTypes_Clone(IEnumMediaTypes * This, return E_NOTIMPL; } -void CEnumMediaTypes_Destroy(CEnumMediaTypes* This) +static void CEnumMediaTypes_Destroy(CEnumMediaTypes* This) { free(This->vt); free(This); @@ -83,7 +93,7 @@ void CEnumMediaTypes_Destroy(CEnumMediaTypes* This) // IPin->IUnknown methods IMPLEMENT_IUNKNOWN(CEnumMediaTypes) -CEnumMediaTypes* CEnumMediaTypesCreate(const AM_MEDIA_TYPE* amt) +static CEnumMediaTypes* CEnumMediaTypesCreate(const AM_MEDIA_TYPE* amt) { CEnumMediaTypes *This = (CEnumMediaTypes*) malloc(sizeof(CEnumMediaTypes)) ; @@ -120,7 +130,7 @@ CEnumMediaTypes* CEnumMediaTypesCreate(const AM_MEDIA_TYPE* amt) *************/ -static HRESULT STDCALL COutputPin_QueryInterface(IUnknown* This, GUID* iid, void** ppv) +static HRESULT STDCALL COutputPin_QueryInterface(IUnknown* This, const GUID* iid, void** ppv) { COutputPin* p = (COutputPin*) This; @@ -284,7 +294,7 @@ static HRESULT STDCALL COutputPin_NewSegment(IPin * This, // IMemInputPin->IUnknown methods -static HRESULT STDCALL COutputPin_M_QueryInterface(IUnknown* This, GUID* iid, void** ppv) +static HRESULT STDCALL COutputPin_M_QueryInterface(IUnknown* This, const GUID* iid, void** ppv) { COutputPin* p = (COutputPin*)This; diff --git a/src/libw32dll/DirectShow/outputpin.h b/src/libw32dll/DirectShow/outputpin.h index 016b36787..1e802f6e0 100644 --- a/src/libw32dll/DirectShow/outputpin.h +++ b/src/libw32dll/DirectShow/outputpin.h @@ -5,18 +5,8 @@ #include "allocator.h" -typedef struct _COutputPin COutputPin; - typedef struct _COutputMemPin COutputMemPin; -struct _COutputMemPin -{ - IMemInputPin_vt* vt; - DECLARE_IUNKNOWN(); - char** frame_pointer; - long* frame_size_pointer; - MemAllocator* pAllocator; - COutputPin* parent; -}; +typedef struct _COutputPin COutputPin; struct _COutputPin { diff --git a/src/libw32dll/dmo/DMO_AudioDecoder.c b/src/libw32dll/dmo/DMO_AudioDecoder.c new file mode 100644 index 000000000..10ddfc367 --- /dev/null +++ b/src/libw32dll/dmo/DMO_AudioDecoder.c @@ -0,0 +1,178 @@ +/******************************************************** + + DirectShow audio decoder + Copyright 2001 Eugene Kuznetsov (divx@euro.ru) + +*********************************************************/ + +#ifndef NOAVIFILE_HEADERS +#include "audiodecoder.h" +#include "except.h" +#else +#include "libwin32.h" +#ifdef LDT_paranoia +#include "ldt_keeper.h" +#endif +#endif + +#include "DMO_Filter.h" +#include "DMO_AudioDecoder.h" + +struct _DMO_AudioDecoder +{ + DMO_MEDIA_TYPE m_sOurType, m_sDestType; + DMO_Filter* m_pDMO_Filter; + char* m_sVhdr; + char* m_sVhdr2; + int m_iFlushed; +}; + +#include "DMO_AudioDecoder.h" + +#include <string.h> +#include <stdio.h> +#include <stdlib.h> + +#define __MODULE__ "DirectShow audio decoder" + +typedef long STDCALL (*GETCLASS) (GUID*, GUID*, void**); +extern void print_wave_header(WAVEFORMATEX *h); + +DMO_AudioDecoder * DMO_AudioDecoder_Open(char* dllname, GUID* guid, WAVEFORMATEX* wf,int out_channels) +//DMO_AudioDecoder * DMO_AudioDecoder_Create(const CodecInfo * info, const WAVEFORMATEX* wf) +{ + DMO_AudioDecoder *this; + int sz; + WAVEFORMATEX* pWF; + +#ifdef LDT_paranoia + Setup_LDT_Keeper(); + Setup_FS_Segment(); +#endif + + this = malloc(sizeof(DMO_AudioDecoder)); + + this->m_iFlushed=1; + + sz = 18 + wf->cbSize; + this->m_sVhdr = malloc(sz); + memcpy(this->m_sVhdr, wf, sz); + this->m_sVhdr2 = malloc(18); + memcpy(this->m_sVhdr2, this->m_sVhdr, 18); + + pWF = (WAVEFORMATEX*)this->m_sVhdr2; + pWF->wFormatTag = 1; + pWF->wBitsPerSample = 16; + pWF->nChannels = out_channels; + pWF->nBlockAlign = 2*pWF->nChannels; //pWF->nChannels * (pWF->wBitsPerSample + 7) / 8; + pWF->nAvgBytesPerSec = pWF->nBlockAlign * pWF->nSamplesPerSec; + pWF->cbSize = 0; + + memset(&this->m_sOurType, 0, sizeof(this->m_sOurType)); + this->m_sOurType.majortype=MEDIATYPE_Audio; + this->m_sOurType.subtype=MEDIASUBTYPE_PCM; + this->m_sOurType.subtype.f1=wf->wFormatTag; + this->m_sOurType.formattype=FORMAT_WaveFormatEx; + this->m_sOurType.lSampleSize=wf->nBlockAlign; + this->m_sOurType.bFixedSizeSamples=1; + this->m_sOurType.bTemporalCompression=0; + this->m_sOurType.cbFormat=sz; + this->m_sOurType.pbFormat=this->m_sVhdr; + + memset(&this->m_sDestType, 0, sizeof(this->m_sDestType)); + this->m_sDestType.majortype=MEDIATYPE_Audio; + this->m_sDestType.subtype=MEDIASUBTYPE_PCM; + this->m_sDestType.formattype=FORMAT_WaveFormatEx; + this->m_sDestType.bFixedSizeSamples=1; + this->m_sDestType.bTemporalCompression=0; + this->m_sDestType.lSampleSize=pWF->nBlockAlign; + this->m_sDestType.cbFormat=18; //pWF->cbSize; + this->m_sDestType.pbFormat=this->m_sVhdr2; + +#if 0 +print_wave_header((WAVEFORMATEX *)this->m_sVhdr); +print_wave_header((WAVEFORMATEX *)this->m_sVhdr2); +#endif + + this->m_pDMO_Filter = DMO_FilterCreate(dllname, guid, &this->m_sOurType, &this->m_sDestType); + if( !this->m_pDMO_Filter ) { + free(this); + return NULL; + } + + return this; +} + +void DMO_AudioDecoder_Destroy(DMO_AudioDecoder *this) +{ + free(this->m_sVhdr); + free(this->m_sVhdr2); + DMO_Filter_Destroy(this->m_pDMO_Filter); + free(this); +} + +int DMO_AudioDecoder_Convert(DMO_AudioDecoder *this, const void* in_data, unsigned int in_size, + void* out_data, unsigned int out_size, + unsigned int* size_read, unsigned int* size_written) +{ + DMO_OUTPUT_DATA_BUFFER db; + CMediaBuffer* bufferin; + unsigned long written = 0; + unsigned long read = 0; + int r = 0; + + if (!in_data || !out_data) + return -1; + +#ifdef LDT_paranoia + Setup_FS_Segment(); +#endif + + //m_pDMO_Filter->m_pMedia->vt->Lock(m_pDMO_Filter->m_pMedia, 1); + bufferin = CMediaBufferCreate(in_size, (void*)in_data, in_size, 1); + r = this->m_pDMO_Filter->m_pMedia->vt->ProcessInput(this->m_pDMO_Filter->m_pMedia, 0, + (IMediaBuffer*)bufferin, + (this->m_iFlushed) ? DMO_INPUT_DATA_BUFFERF_SYNCPOINT : 0, + 0, 0); + if (r == 0){ + ((IMediaBuffer*)bufferin)->vt->GetBufferAndLength((IMediaBuffer*)bufferin, 0, &read); + this->m_iFlushed = 0; + } + + ((IMediaBuffer*)bufferin)->vt->Release((IUnknown*)bufferin); + + //printf("RESULTA: %d 0x%x %ld %d %d\n", r, r, read, m_iFlushed, out_size); + if (r == 0 || (unsigned)r == DMO_E_NOTACCEPTING){ + unsigned long status = 0; + /* something for process */ + db.rtTimestamp = 0; + db.rtTimelength = 0; + db.dwStatus = 0; + db.pBuffer = (IMediaBuffer*) CMediaBufferCreate(out_size, out_data, 0, 0); + //printf("OUTSIZE %d\n", out_size); + r = this->m_pDMO_Filter->m_pMedia->vt->ProcessOutput(this->m_pDMO_Filter->m_pMedia, + 0, 1, &db, &status); + + ((IMediaBuffer*)db.pBuffer)->vt->GetBufferAndLength((IMediaBuffer*)db.pBuffer, 0, &written); + ((IMediaBuffer*)db.pBuffer)->vt->Release((IUnknown*)db.pBuffer); + + //printf("RESULTB: %d 0x%x %ld\n", r, r, written); + //printf("Converted %d -> %d\n", in_size, out_size); + } + else if (in_size > 0) + printf("ProcessInputError r:0x%x=%d\n", r, r); + + if (size_read) + *size_read = read; + if (size_written) + *size_written = written; + return r; +} + +int DMO_AudioDecoder_GetSrcSize(DMO_AudioDecoder *this, int dest_size) +{ +// unsigned long inputs, outputs; +// Setup_FS_Segment(); +// this->m_pDMO_Filter->m_pMedia->vt->GetOutputSizeInfo(this->m_pDMO_Filter->m_pMedia, 0, &inputs, &outputs); + return ((WAVEFORMATEX*)this->m_sVhdr)->nBlockAlign*4; +} diff --git a/src/libw32dll/dmo/DMO_AudioDecoder.h b/src/libw32dll/dmo/DMO_AudioDecoder.h new file mode 100644 index 000000000..ed571f465 --- /dev/null +++ b/src/libw32dll/dmo/DMO_AudioDecoder.h @@ -0,0 +1,17 @@ +#ifndef AVIFILE_DMO_AUDIODECODER_H +#define AVIFILE_DMO_AUDIODECODER_H + +typedef struct _DMO_AudioDecoder DMO_AudioDecoder; + +//DMO_AudioDecoder * DMO_AudioDecoder_Create(const CodecInfo * info, const WAVEFORMATEX* wf); +DMO_AudioDecoder * DMO_AudioDecoder_Open(char* dllname, GUID* guid, WAVEFORMATEX* wf,int out_channels); + +void DMO_AudioDecoder_Destroy(DMO_AudioDecoder *this); + +int DMO_AudioDecoder_Convert(DMO_AudioDecoder *this, const void* in_data, unsigned int in_size, + void* out_data, unsigned int out_size, + unsigned int* size_read, unsigned int* size_written); + +int DMO_AudioDecoder_GetSrcSize(DMO_AudioDecoder *this, int dest_size); + +#endif // AVIFILE_DMO_AUDIODECODER_H diff --git a/src/libw32dll/dmo/DMO_Filter.h b/src/libw32dll/dmo/DMO_Filter.h new file mode 100644 index 000000000..ee7a38b1c --- /dev/null +++ b/src/libw32dll/dmo/DMO_Filter.h @@ -0,0 +1,47 @@ +#ifndef DMO_FILTER_H +#define DMO_FILTER_H + +#include "dmo_guids.h" +#include "dmo_interfaces.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +typedef struct _DMO_Filter +{ + int m_iHandle; + IDMOVideoOutputOptimizations* m_pOptim; + IMediaObject* m_pMedia; + IMediaObjectInPlace* m_pInPlace; + AM_MEDIA_TYPE *m_pOurType, *m_pDestType; +} DMO_Filter; + +typedef struct _CMediaBuffer CMediaBuffer; + +/** + * Create DMO_Filter object - similar syntax as for DS_Filter + */ +DMO_Filter* DMO_FilterCreate(const char* dllname, const GUID* id, + AM_MEDIA_TYPE* in_fmt, AM_MEDIA_TYPE* out_fmt); +/** + * Destroy DMO_Filter object - release all allocated resources + */ +void DMO_Filter_Destroy(DMO_Filter* This); + + +/** + * Create IMediaBuffer object - to pass/receive data from DMO_Filter + * + * maxlen - maximum size for this buffer + * mem - initial memory 0 - creates memory + * len - initial size of used portion of the buffer + * copy - make a local copy of data + */ +CMediaBuffer* CMediaBufferCreate(unsigned long maxlen, void* mem, unsigned long len, int copy); + +#if defined(__cplusplus) +} +#endif + +#endif /* DS_FILTER_H */ diff --git a/src/libw32dll/dmo/DMO_VideoDecoder.c b/src/libw32dll/dmo/DMO_VideoDecoder.c new file mode 100644 index 000000000..c7a1af6c0 --- /dev/null +++ b/src/libw32dll/dmo/DMO_VideoDecoder.c @@ -0,0 +1,557 @@ +/******************************************************** + + DirectShow Video decoder implementation + Copyright 2000 Eugene Kuznetsov (divx@euro.ru) + +*********************************************************/ + +#include "DirectShow/guids.h" +#include "DirectShow/interfaces.h" +#include "registry.h" +#ifdef LDT_paranoia +#include "../ldt_keeper.h" +#endif + +#ifndef NOAVIFILE_HEADERS +#include "videodecoder.h" +#else +#include "libwin32.h" +#endif +#include "DMO_Filter.h" + +#include "DMO_VideoDecoder.h" + +struct _DMO_VideoDecoder +{ + IVideoDecoder iv; + + DMO_Filter* m_pDMO_Filter; + AM_MEDIA_TYPE m_sOurType, m_sDestType; + VIDEOINFOHEADER* m_sVhdr; + VIDEOINFOHEADER* m_sVhdr2; + int m_Caps;//CAPS m_Caps; // capabilities of DirectShow decoder + int m_iLastQuality; // remember last quality as integer + int m_iMinBuffers; + int m_iMaxAuto; +}; + +//#include "DMO_VideoDecoder.h" + +#include "../wine/winerror.h" + +#ifndef NOAVIFILE_HEADERS +#define VFW_E_NOT_RUNNING 0x80040226 +#include "fourcc.h" +#include "except.h" +#endif + +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/mman.h> +#include <stdio.h> +#include <stdlib.h> // labs + +// strcmp((const char*)info.dll,...) is used instead of (... == ...) +// so Arpi could use char* pointer in his simplified DMO_VideoDecoder class + +#define __MODULE__ "DirectShow_VideoDecoder" + +#define false 0 +#define true 1 + + +//int DMO_VideoDecoder_GetCapabilities(DMO_VideoDecoder *this){return this->m_Caps;} + +typedef struct _ct ct; + +struct _ct { + fourcc_t fcc; + unsigned int bits; + const GUID* subtype; + int cap; + }; + +static ct check[] = { + { fccI420, 12, &MEDIASUBTYPE_I420, CAP_I420 }, + { fccYV12, 12, &MEDIASUBTYPE_YV12, CAP_YV12 }, + { fccYUY2, 16, &MEDIASUBTYPE_YUY2, CAP_YUY2 }, + { fccUYVY, 16, &MEDIASUBTYPE_UYVY, CAP_UYVY }, + { fccYVYU, 16, &MEDIASUBTYPE_YVYU, CAP_YVYU }, + { fccIYUV, 24, &MEDIASUBTYPE_IYUV, CAP_IYUV }, + + { 8, 8, &MEDIASUBTYPE_RGB8, CAP_NONE }, + { 15, 16, &MEDIASUBTYPE_RGB555, CAP_NONE }, + { 16, 16, &MEDIASUBTYPE_RGB565, CAP_NONE }, + { 24, 24, &MEDIASUBTYPE_RGB24, CAP_NONE }, + { 32, 32, &MEDIASUBTYPE_RGB32, CAP_NONE }, + + {0}, +}; + +DMO_VideoDecoder * DMO_VideoDecoder_Open(char* dllname, GUID* guid, BITMAPINFOHEADER * format, int flip, int maxauto) +{ + DMO_VideoDecoder *this; + HRESULT result; + ct* c; + + this = malloc(sizeof(DMO_VideoDecoder)); + memset( this, 0, sizeof(DMO_VideoDecoder)); + + this->m_sVhdr2 = 0; + this->m_iLastQuality = -1; + this->m_iMaxAuto = maxauto; + +#ifdef LDT_paranoia + Setup_LDT_Keeper(); +#endif + + //memset(&m_obh, 0, sizeof(m_obh)); + //m_obh.biSize = sizeof(m_obh); + /*try*/ + { + unsigned int bihs; + + bihs = (format->biSize < (int) sizeof(BITMAPINFOHEADER)) ? + sizeof(BITMAPINFOHEADER) : format->biSize; + + this->iv.m_bh = (BITMAPINFOHEADER*)malloc(bihs); + memcpy(this->iv.m_bh, format, bihs); + + this->iv.m_State = STOP; + //this->iv.m_pFrame = 0; + this->iv.m_Mode = DIRECT; + this->iv.m_iDecpos = 0; + this->iv.m_iPlaypos = -1; + this->iv.m_fQuality = 0.0f; + this->iv.m_bCapable16b = true; + + bihs += sizeof(VIDEOINFOHEADER) - sizeof(BITMAPINFOHEADER); + this->m_sVhdr = (VIDEOINFOHEADER*)malloc(bihs); + memset(this->m_sVhdr, 0, bihs); + memcpy(&this->m_sVhdr->bmiHeader, this->iv.m_bh, this->iv.m_bh->biSize); + this->m_sVhdr->rcSource.left = this->m_sVhdr->rcSource.top = 0; + this->m_sVhdr->rcSource.right = this->m_sVhdr->bmiHeader.biWidth; + this->m_sVhdr->rcSource.bottom = this->m_sVhdr->bmiHeader.biHeight; + //this->m_sVhdr->rcSource.right = 0; + //this->m_sVhdr->rcSource.bottom = 0; + this->m_sVhdr->rcTarget = this->m_sVhdr->rcSource; + + this->m_sOurType.majortype = MEDIATYPE_Video; + this->m_sOurType.subtype = MEDIATYPE_Video; + this->m_sOurType.subtype.f1 = this->m_sVhdr->bmiHeader.biCompression; + this->m_sOurType.formattype = FORMAT_VideoInfo; + this->m_sOurType.bFixedSizeSamples = false; + this->m_sOurType.bTemporalCompression = true; + this->m_sOurType.pUnk = 0; + this->m_sOurType.cbFormat = bihs; + this->m_sOurType.pbFormat = (char*)this->m_sVhdr; + + this->m_sVhdr2 = (VIDEOINFOHEADER*)(malloc(sizeof(VIDEOINFOHEADER)+12)); + memcpy(this->m_sVhdr2, this->m_sVhdr, sizeof(VIDEOINFOHEADER)); + memset((char*)this->m_sVhdr2 + sizeof(VIDEOINFOHEADER), 0, 12); + this->m_sVhdr2->bmiHeader.biCompression = 0; + this->m_sVhdr2->bmiHeader.biBitCount = 24; + +// memset((char*)this->m_sVhdr2, 0, sizeof(VIDEOINFOHEADER)+12); + this->m_sVhdr2->rcTarget = this->m_sVhdr->rcTarget; +// this->m_sVhdr2->rcSource = this->m_sVhdr->rcSource; + + memset(&this->m_sDestType, 0, sizeof(this->m_sDestType)); + this->m_sDestType.majortype = MEDIATYPE_Video; + this->m_sDestType.subtype = MEDIASUBTYPE_RGB24; + this->m_sDestType.formattype = FORMAT_VideoInfo; + this->m_sDestType.bFixedSizeSamples = true; + this->m_sDestType.bTemporalCompression = false; + this->m_sDestType.lSampleSize = labs(this->m_sVhdr2->bmiHeader.biWidth*this->m_sVhdr2->bmiHeader.biHeight + * ((this->m_sVhdr2->bmiHeader.biBitCount + 7) / 8)); + this->m_sVhdr2->bmiHeader.biSizeImage = this->m_sDestType.lSampleSize; + this->m_sDestType.pUnk = 0; + this->m_sDestType.cbFormat = sizeof(VIDEOINFOHEADER); + this->m_sDestType.pbFormat = (char*)this->m_sVhdr2; + + memset(&this->iv.m_obh, 0, sizeof(this->iv.m_obh)); + memcpy(&this->iv.m_obh, this->iv.m_bh, sizeof(this->iv.m_obh) < (unsigned) this->iv.m_bh->biSize + ? sizeof(this->iv.m_obh) : (unsigned) this->iv.m_bh->biSize); + this->iv.m_obh.biBitCount=24; + this->iv.m_obh.biSize = sizeof(BITMAPINFOHEADER); + this->iv.m_obh.biCompression = 0; //BI_RGB + //this->iv.m_obh.biHeight = labs(this->iv.m_obh.biHeight); + this->iv.m_obh.biSizeImage = labs(this->iv.m_obh.biWidth * this->iv.m_obh.biHeight) + * ((this->iv.m_obh.biBitCount + 7) / 8); + + + this->m_pDMO_Filter = DMO_FilterCreate(dllname, guid, &this->m_sOurType, &this->m_sDestType); + + if (!this->m_pDMO_Filter) + { + printf("Failed to create DMO filter\n"); + return 0; + } + + if (!flip) + { + this->iv.m_obh.biHeight *= -1; + this->m_sVhdr2->bmiHeader.biHeight = this->iv.m_obh.biHeight; +// result = this->m_pDMO_Filter->m_pOutputPin->vt->QueryAccept(this->m_pDMO_Filter->m_pOutputPin, &this->m_sDestType); + result = this->m_pDMO_Filter->m_pMedia->vt->SetOutputType(this->m_pDMO_Filter->m_pMedia, 0, &this->m_sDestType, DMO_SET_TYPEF_TEST_ONLY); + if (result) + { + printf("Decoder does not support upside-down RGB frames\n"); + this->iv.m_obh.biHeight *= -1; + this->m_sVhdr2->bmiHeader.biHeight = this->iv.m_obh.biHeight; + } + } + + memcpy( &this->iv.m_decoder, &this->iv.m_obh, sizeof(this->iv.m_obh) ); + + switch (this->iv.m_bh->biCompression) + { +#if 0 + case fccDIV3: + case fccDIV4: + case fccDIV5: + case fccDIV6: + case fccMP42: + case fccWMV2: + //YV12 seems to be broken for DivX :-) codec +// case fccIV50: + //produces incorrect picture + //m_Caps = (CAPS) (m_Caps & ~CAP_YV12); + //m_Caps = CAP_UYVY;//CAP_YUY2; // | CAP_I420; + //m_Caps = CAP_I420; + this->m_Caps = (CAP_YUY2 | CAP_UYVY); + break; +#endif + default: + + this->m_Caps = CAP_NONE; + + printf("Decoder supports the following YUV formats: "); + for (c = check; c->bits; c++) + { + this->m_sVhdr2->bmiHeader.biBitCount = c->bits; + this->m_sVhdr2->bmiHeader.biCompression = c->fcc; + this->m_sDestType.subtype = *c->subtype; + //result = this->m_pDMO_Filter->m_pOutputPin->vt->QueryAccept(this->m_pDMO_Filter->m_pOutputPin, &this->m_sDestType); + result = this->m_pDMO_Filter->m_pMedia->vt->SetOutputType(this->m_pDMO_Filter->m_pMedia, 0, &this->m_sDestType, DMO_SET_TYPEF_TEST_ONLY); + if (!result) + { + this->m_Caps = (this->m_Caps | c->cap); + printf("%.4s ", (char*) &c->fcc); + } + } + printf("\n"); + } + + if (this->m_Caps != CAP_NONE) + printf("Decoder is capable of YUV output (flags 0x%x)\n", (int)this->m_Caps); + + this->m_sVhdr2->bmiHeader.biBitCount = 24; + this->m_sVhdr2->bmiHeader.biCompression = 0; + this->m_sDestType.subtype = MEDIASUBTYPE_RGB24; + + this->m_iMinBuffers = this->iv.VBUFSIZE; + } + /*catch (FatalError& error) + { + delete[] m_sVhdr; + delete[] m_sVhdr2; + delete m_pDMO_Filter; + throw; + }*/ + return this; +} + +void DMO_VideoDecoder_Destroy(DMO_VideoDecoder *this) +{ + DMO_VideoDecoder_StopInternal(this); + this->iv.m_State = STOP; + free(this->m_sVhdr); + free(this->m_sVhdr2); + DMO_Filter_Destroy(this->m_pDMO_Filter); +} + +void DMO_VideoDecoder_StartInternal(DMO_VideoDecoder *this) +{ +#if 0 + ALLOCATOR_PROPERTIES props, props1; + Debug printf("DMO_VideoDecoder_StartInternal\n"); + //cout << "DSSTART" << endl; + this->m_pDMO_Filter->Start(this->m_pDMO_Filter); + + props.cBuffers = 1; + props.cbBuffer = this->m_sDestType.lSampleSize; + + //don't know how to do this correctly + props.cbAlign = props.cbPrefix = 0; + this->m_pDMO_Filter->m_pAll->vt->SetProperties(this->m_pDMO_Filter->m_pAll, &props, &props1); + this->m_pDMO_Filter->m_pAll->vt->Commit(this->m_pDMO_Filter->m_pAll); +#endif + this->iv.m_State = START; +} + +void DMO_VideoDecoder_StopInternal(DMO_VideoDecoder *this) +{ + // this->m_pDMO_Filter->Stop(this->m_pDMO_Filter); + //??? why was this here ??? m_pOurOutput->SetFramePointer(0); +} + +int DMO_VideoDecoder_DecodeInternal(DMO_VideoDecoder *this, const void* src, int size, int is_keyframe, char* imdata) +{ +// IMediaSample* sample = 0; + char* ptr; + int result; + unsigned long status; // to be ignored by M$ specs + DMO_OUTPUT_DATA_BUFFER db; + CMediaBuffer* bufferin; +//+ uint8_t* imdata = dest ? dest->Data() : 0; + + Debug printf("DMO_VideoDecoder_DecodeInternal(%p,%p,%d,%d,%p)\n",this,src,size,is_keyframe,imdata); + +// this->m_pDMO_Filter->m_pAll->vt->GetBuffer(this->m_pDMO_Filter->m_pAll, &sample, 0, 0, 0); +// if (!sample) +// { +// Debug printf("ERROR: null sample\n"); +// return -1; +// } + + Setup_FS_Segment(); + + bufferin = CMediaBufferCreate(size, (void*)src, size, 0); + result = this->m_pDMO_Filter->m_pMedia->vt->ProcessInput(this->m_pDMO_Filter->m_pMedia, 0, + (IMediaBuffer*)bufferin, + (is_keyframe) ? DMO_INPUT_DATA_BUFFERF_SYNCPOINT : 0, + 0, 0); + ((IMediaBuffer*)bufferin)->vt->Release((IUnknown*)bufferin); + + if (result != S_OK) + { + /* something for process */ + if (result != S_FALSE) + printf("ProcessInputError r:0x%x=%d (keyframe: %d)\n", result, result, is_keyframe); + else + printf("ProcessInputError FALSE ?? (keyframe: %d)\n", is_keyframe); + return size; + } + + db.rtTimestamp = 0; + db.rtTimelength = 0; + db.dwStatus = 0; + db.pBuffer = (IMediaBuffer*) CMediaBufferCreate(this->m_sDestType.lSampleSize, + imdata, 0, 0); + result = this->m_pDMO_Filter->m_pMedia->vt->ProcessOutput(this->m_pDMO_Filter->m_pMedia, + (imdata) ? 0 : DMO_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER, + 1, &db, &status); + //m_pDMO_Filter->m_pMedia->vt->Lock(m_pDMO_Filter->m_pMedia, 0); + if ((unsigned)result == DMO_E_NOTACCEPTING) + printf("ProcessOutputError: Not accepting\n"); + else if (result) + printf("ProcessOutputError: r:0x%x=%d %ld stat:%ld\n", result, result, status, db.dwStatus); + + ((IMediaBuffer*)db.pBuffer)->vt->Release((IUnknown*)db.pBuffer); + + //int r = m_pDMO_Filter->m_pMedia->vt->Flush(m_pDMO_Filter->m_pMedia); + //printf("FLUSH %d\n", r); + + return 0; +} + +/* + * bits == 0 - leave unchanged + */ +//int SetDestFmt(DMO_VideoDecoder * this, int bits = 24, fourcc_t csp = 0); +int DMO_VideoDecoder_SetDestFmt(DMO_VideoDecoder *this, int bits, unsigned int csp) +{ + HRESULT result; + int should_test=1; + int stoped = 0; + + Debug printf("DMO_VideoDecoder_SetDestFmt (%p, %d, %d)\n",this,bits,(int)csp); + + /* if (!CImage::Supported(csp, bits)) + return -1; +*/ + // BitmapInfo temp = m_obh; + + if (!csp) // RGB + { + int ok = true; + + switch (bits) + { + case 15: + this->m_sDestType.subtype = MEDIASUBTYPE_RGB555; + break; + case 16: + this->m_sDestType.subtype = MEDIASUBTYPE_RGB565; + break; + case 24: + this->m_sDestType.subtype = MEDIASUBTYPE_RGB24; + break; + case 32: + this->m_sDestType.subtype = MEDIASUBTYPE_RGB32; + break; + default: + ok = false; + break; + } + + if (ok) { + this->iv.m_obh.biBitCount=bits; + if( bits == 15 || bits == 16 ) { + this->iv.m_obh.biSize=sizeof(BITMAPINFOHEADER)+12; + this->iv.m_obh.biCompression=3;//BI_BITFIELDS + this->iv.m_obh.biSizeImage=abs((int)(2*this->iv.m_obh.biWidth*this->iv.m_obh.biHeight)); + } + + if( bits == 16 ) { + this->iv.m_obh.colors[0]=0xF800; + this->iv.m_obh.colors[1]=0x07E0; + this->iv.m_obh.colors[2]=0x001F; + } else if ( bits == 15 ) { + this->iv.m_obh.colors[0]=0x7C00; + this->iv.m_obh.colors[1]=0x03E0; + this->iv.m_obh.colors[2]=0x001F; + } else { + this->iv.m_obh.biSize = sizeof(BITMAPINFOHEADER); + this->iv.m_obh.biCompression = 0; //BI_RGB + //this->iv.m_obh.biHeight = labs(this->iv.m_obh.biHeight); + this->iv.m_obh.biSizeImage = labs(this->iv.m_obh.biWidth * this->iv.m_obh.biHeight) + * ((this->iv.m_obh.biBitCount + 7) / 8); + } + } + //.biSizeImage=abs(temp.biWidth*temp.biHeight*((temp.biBitCount+7)/8)); + } else + { // YUV + int ok = true; + switch (csp) + { + case fccYUY2: + this->m_sDestType.subtype = MEDIASUBTYPE_YUY2; + break; + case fccYV12: + this->m_sDestType.subtype = MEDIASUBTYPE_YV12; + break; + case fccIYUV: + this->m_sDestType.subtype = MEDIASUBTYPE_IYUV; + break; + case fccI420: + this->m_sDestType.subtype = MEDIASUBTYPE_I420; + break; + case fccUYVY: + this->m_sDestType.subtype = MEDIASUBTYPE_UYVY; + break; + case fccYVYU: + this->m_sDestType.subtype = MEDIASUBTYPE_YVYU; + break; + case fccYVU9: + this->m_sDestType.subtype = MEDIASUBTYPE_YVU9; + default: + ok = false; + break; + } + + if (ok) { + if (csp != 0 && csp != 3 && this->iv.m_obh.biHeight > 0) + this->iv.m_obh.biHeight *= -1; // YUV formats uses should have height < 0 + this->iv.m_obh.biSize = sizeof(BITMAPINFOHEADER); + this->iv.m_obh.biCompression=csp; + this->iv.m_obh.biBitCount=bits; + this->iv.m_obh.biSizeImage=labs(this->iv.m_obh.biBitCount* + this->iv.m_obh.biWidth*this->iv.m_obh.biHeight)>>3; + } + } + this->m_sDestType.lSampleSize = this->iv.m_obh.biSizeImage; + memcpy(&(this->m_sVhdr2->bmiHeader), &this->iv.m_obh, sizeof(this->iv.m_obh)); + this->m_sVhdr2->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + if (this->m_sVhdr2->bmiHeader.biCompression == 3) + this->m_sDestType.cbFormat = sizeof(VIDEOINFOHEADER) + 12; + else + this->m_sDestType.cbFormat = sizeof(VIDEOINFOHEADER); + + + switch(csp) + { + case fccYUY2: + if(!(this->m_Caps & CAP_YUY2)) + should_test=false; + break; + case fccYV12: + if(!(this->m_Caps & CAP_YV12)) + should_test=false; + break; + case fccIYUV: + if(!(this->m_Caps & CAP_IYUV)) + should_test=false; + break; + case fccI420: + if(!(this->m_Caps & CAP_I420)) + should_test=false; + break; + case fccUYVY: + if(!(this->m_Caps & CAP_UYVY)) + should_test=false; + break; + case fccYVYU: + if(!(this->m_Caps & CAP_YVYU)) + should_test=false; + break; + case fccYVU9: + if(!(this->m_Caps & CAP_YVU9)) + should_test=false; + break; + } + + Setup_FS_Segment(); + +// if(should_test) +// result = this->m_pDMO_Filter->m_pOutputPin->vt->QueryAccept(this->m_pDMO_Filter->m_pOutputPin, &this->m_sDestType); +// else +// result = -1; + + // test accept + if(!this->m_pDMO_Filter) return 0; + result = this->m_pDMO_Filter->m_pMedia->vt->SetOutputType(this->m_pDMO_Filter->m_pMedia, 0, &this->m_sDestType, DMO_SET_TYPEF_TEST_ONLY); + + if (result != 0) + { + if (csp) + printf("Warning: unsupported color space\n"); + else + printf("Warning: unsupported bit depth\n"); + + this->m_sDestType.lSampleSize = this->iv.m_decoder.biSizeImage; + memcpy(&(this->m_sVhdr2->bmiHeader), &this->iv.m_decoder, sizeof(this->iv.m_decoder)); + this->m_sVhdr2->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + if (this->m_sVhdr2->bmiHeader.biCompression == 3) + this->m_sDestType.cbFormat = sizeof(VIDEOINFOHEADER) + 12; + else + this->m_sDestType.cbFormat = sizeof(VIDEOINFOHEADER); + + return -1; + } + + memcpy( &this->iv.m_decoder, &this->iv.m_obh, sizeof(this->iv.m_obh)); + +// m_obh=temp; +// if(csp) +// m_obh.biBitCount=BitmapInfo::BitCount(csp); + this->iv.m_bh->biBitCount = bits; + + //DMO_VideoDecoder_Restart(this); + + this->m_pDMO_Filter->m_pMedia->vt->SetOutputType(this->m_pDMO_Filter->m_pMedia, 0, &this->m_sDestType, 0); + + return 0; +} + + +int DMO_VideoDecoder_SetDirection(DMO_VideoDecoder *this, int d) +{ + this->iv.m_obh.biHeight = (d) ? this->iv.m_bh->biHeight : -this->iv.m_bh->biHeight; + this->m_sVhdr2->bmiHeader.biHeight = this->iv.m_obh.biHeight; + return 0; +} + diff --git a/src/libw32dll/dmo/DMO_VideoDecoder.h b/src/libw32dll/dmo/DMO_VideoDecoder.h new file mode 100644 index 000000000..1f48523a1 --- /dev/null +++ b/src/libw32dll/dmo/DMO_VideoDecoder.h @@ -0,0 +1,26 @@ +#ifndef AVIFILE_DMO_VIDEODECODER_H +#define AVIFILE_DMO_VIDEODECODER_H + +typedef struct _DMO_VideoDecoder DMO_VideoDecoder; + +int DMO_VideoDecoder_GetCapabilities(DMO_VideoDecoder *this); + +DMO_VideoDecoder * DMO_VideoDecoder_Open(char* dllname, GUID* guid, BITMAPINFOHEADER * format, int flip, int maxauto); + +void DMO_VideoDecoder_Destroy(DMO_VideoDecoder *this); + +void DMO_VideoDecoder_StartInternal(DMO_VideoDecoder *this); + +void DMO_VideoDecoder_StopInternal(DMO_VideoDecoder *this); + +int DMO_VideoDecoder_DecodeInternal(DMO_VideoDecoder *this, const void* src, int size, int is_keyframe, char* pImage); + +/* + * bits == 0 - leave unchanged + */ +//int SetDestFmt(DMO_VideoDecoder * this, int bits = 24, fourcc_t csp = 0); +int DMO_VideoDecoder_SetDestFmt(DMO_VideoDecoder *this, int bits, unsigned int csp); +int DMO_VideoDecoder_SetDirection(DMO_VideoDecoder *this, int d); + + +#endif /* AVIFILE_DMO_VIDEODECODER_H */ diff --git a/src/libw32dll/dmo/Makefile.am b/src/libw32dll/dmo/Makefile.am new file mode 100644 index 000000000..a5aa17323 --- /dev/null +++ b/src/libw32dll/dmo/Makefile.am @@ -0,0 +1,42 @@ + +AM_CFLAGS = $(X_CFLAGS) -fno-omit-frame-pointer \ + -Wmissing-prototypes -Wimplicit-function-declaration \ + -DWIN32_PATH=\"@w32_path@\" -DNOAVIFILE_HEADERS \ + -I$(srcdir)/.. -I$(srcdir)/../wine + +#DEBUG_CFLAGS = @DEBUG_CFLAGS@ $(X_CFLAGS) -fno-omit-frame-pointer \ +# -Wmissing-prototypes -Wimplicit-function-declaration \ +# -DWIN32_PATH=\\\"@w32_path@\\\" -DNOAVIFILE_HEADERS \ +# -I$(srcdir)/.. -I$(srcdir)/../wine + +if HAVE_W32DLL +dmo_filter_lib = libdmo_filter.la +endif + +noinst_LTLIBRARIES = $(dmo_filter_lib) + +libdmo_filter_la_SOURCES = \ + buffer.c \ + DMO_AudioDecoder.c \ + dmo.c \ + dmo_guids.c \ + DMO_VideoDecoder.c + +noinst_HEADERS = \ + DMO_AudioDecoder.h \ + dmo_guids.h \ + dmo_interfaces.h \ + DMO_Filter.h \ + dmo.h \ + DMO_VideoDecoder.h + +debug: + @$(MAKE) CFLAGS="$(DEBUG_CFLAGS)" + +mostlyclean-generic: + -rm -f *~ \#* .*~ .\#* + +maintainer-clean-generic: + -@echo "This command is intended for maintainers to use;" + -@echo "it deletes files that may require special tools to rebuild." + -rm -f Makefile.in diff --git a/src/libw32dll/dmo/buffer.c b/src/libw32dll/dmo/buffer.c new file mode 100644 index 000000000..3d53c3ce9 --- /dev/null +++ b/src/libw32dll/dmo/buffer.c @@ -0,0 +1,119 @@ +#include "DMO_Filter.h" + +#include "wine/winerror.h" +#include "wine/windef.h" + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +struct _CMediaBuffer +{ + IMediaBuffer_vt* vt; + DECLARE_IUNKNOWN(); + GUID interfaces[2]; + void* mem; + unsigned long len; + unsigned long maxlen; + int freemem; +}; + +static HRESULT STDCALL CMediaBuffer_SetLength(IMediaBuffer* This, + unsigned long cbLength) +{ + CMediaBuffer* cmb = (CMediaBuffer*) This; + Debug printf("CMediaBuffer_SetLength(%p) called (%ld, %ld)\n", This, cbLength, cmb->maxlen); + if (cbLength > cmb->maxlen) + return E_INVALIDARG; + cmb->len = cbLength; + return S_OK; +} + +static HRESULT STDCALL CMediaBuffer_GetMaxLength(IMediaBuffer* This, + /* [out] */ unsigned long *pcbMaxLength) +{ + CMediaBuffer* cmb = (CMediaBuffer*) This; + Debug printf("CMediaBuffer_GetMaxLength(%p) called -> %ld\n", This, cmb->maxlen); + if (!pcbMaxLength) + return E_POINTER; + *pcbMaxLength = cmb->maxlen; + return S_OK; +} + +static HRESULT STDCALL CMediaBuffer_GetBufferAndLength(IMediaBuffer* This, + /* [out] */ char** ppBuffer, + /* [out] */ unsigned long* pcbLength) +{ + CMediaBuffer* cmb = (CMediaBuffer*) This; + Debug printf("CMediaBuffer_GetBufferAndLength(%p) called -> %p %ld\n", This, cmb->mem, cmb->len); + if (!ppBuffer && !pcbLength) + return E_POINTER; + if (ppBuffer) + *ppBuffer = cmb->mem; + if (pcbLength) + *pcbLength = cmb->len; + return S_OK; +} + +static void CMediaBuffer_Destroy(CMediaBuffer* This) +{ + Debug printf("CMediaBuffer_Destroy(%p) called\n", This); + if (This->freemem) + free(This->mem); + free(This->vt); + free(This); +} + +IMPLEMENT_IUNKNOWN(CMediaBuffer) + +CMediaBuffer* CMediaBufferCreate(unsigned long maxlen, void* mem, + unsigned long len, int copy) +{ + CMediaBuffer* This = (CMediaBuffer*) malloc(sizeof(CMediaBuffer)); + + if (!This) + return NULL; + + This->vt = (IMediaBuffer_vt*) malloc(sizeof(IMediaBuffer_vt)); + if (!This->vt) + { + CMediaBuffer_Destroy(This); + return NULL; + } + + This->refcount = 1; + This->len = len; + This->maxlen = maxlen; + This->freemem = 0; + This->mem = mem; + if (copy) + /* make a private copy of data */ + This->mem = 0; + if (This->mem == NULL) + { + if (This->maxlen) + { + This->mem = malloc(This->maxlen); + if (!This->mem) + { + CMediaBuffer_Destroy(This); + return NULL; + } + This->freemem = 1; + if (copy) + memcpy(This->mem, mem, This->len); + } + } + This->vt->QueryInterface = CMediaBuffer_QueryInterface; + This->vt->AddRef = CMediaBuffer_AddRef; + This->vt->Release = CMediaBuffer_Release; + + This->vt->SetLength = CMediaBuffer_SetLength; + This->vt->GetMaxLength = CMediaBuffer_GetMaxLength; + This->vt->GetBufferAndLength = CMediaBuffer_GetBufferAndLength; + + This->interfaces[0] = IID_IUnknown; + This->interfaces[1] = IID_IMediaBuffer; + + return This; +} diff --git a/src/libw32dll/dmo/dmo.c b/src/libw32dll/dmo/dmo.c new file mode 100644 index 000000000..98cfbad40 --- /dev/null +++ b/src/libw32dll/dmo/dmo.c @@ -0,0 +1,156 @@ +#include "DMO_Filter.h" +#include "driver.h" +#include "com.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "win32.h" // printf macro + +void trapbug(); +typedef long STDCALL (*GETCLASS) (const GUID*, const GUID*, void**); + +void DMO_Filter_Destroy(DMO_Filter* This) +{ + if (This->m_pOptim) + This->m_pOptim->vt->Release((IUnknown*)This->m_pOptim); + if (This->m_pInPlace) + This->m_pInPlace->vt->Release((IUnknown*)This->m_pInPlace); + if (This->m_pMedia) + This->m_pMedia->vt->Release((IUnknown*)This->m_pMedia); + + free(This); + CodecRelease(); +} + +DMO_Filter* DMO_FilterCreate(const char* dllname, const GUID* id, + DMO_MEDIA_TYPE* in_fmt, + DMO_MEDIA_TYPE* out_fmt) +{ + HRESULT hr = 0; + const char* em = NULL; + DMO_Filter* This = (DMO_Filter*) malloc(sizeof(DMO_Filter)); + if (!This) + return NULL; + + memset(This, 0, sizeof(DMO_Filter)); + CodecAlloc(); + + //This->Start = DS_Filter_Start; + //This->Stop = DS_Filter_Stop; + + for (;;) + { + GETCLASS func; + struct IClassFactory* factory = NULL; + struct IUnknown* object = NULL; + unsigned int i; + unsigned long inputs, outputs; + + This->m_iHandle = LoadLibraryA(dllname); + if (!This->m_iHandle) + { + em = "could not open DMO DLL"; + break; + } + func = (GETCLASS)GetProcAddress((unsigned)This->m_iHandle, "DllGetClassObject"); + if (!func) + { + em = "illegal or corrupt DMO DLL"; + break; + } +//trapbug(); + hr = func(id, &IID_IClassFactory, (void**)&factory); + if (hr || !factory) + { + em = "no such class object"; + break; + } + hr = factory->vt->CreateInstance(factory, 0, &IID_IUnknown, (void**)&object); + factory->vt->Release((IUnknown*)factory); + if (hr || !object) + { + em = "class factory failure"; + break; + } + hr = object->vt->QueryInterface(object, &IID_IMediaObject, (void**)&This->m_pMedia); + if (hr == 0) + { + /* query for some extra available interface */ + HRESULT r = object->vt->QueryInterface(object, &IID_IMediaObjectInPlace, (void**)&This->m_pInPlace); + if (r == 0 && This->m_pInPlace) + printf("DMO dll supports InPlace - PLEASE REPORT to developer\n"); + r = object->vt->QueryInterface(object, &IID_IDMOVideoOutputOptimizations, (void**)&This->m_pOptim); + if (r == 0 && This->m_pOptim) + { + unsigned long flags; + r = This->m_pOptim->vt->QueryOperationModePreferences(This->m_pOptim, 0, &flags); + printf("DMO dll supports VO Optimizations %ld %lx\n", r, flags); + if (flags & DMO_VOSF_NEEDS_PREVIOUS_SAMPLE) + printf("DMO dll might use previous sample when requested\n"); + } + } + object->vt->Release((IUnknown*)object); + if (hr || !This->m_pMedia) + { + em = "object does not provide IMediaObject interface"; + break; + } + hr = This->m_pMedia->vt->SetInputType(This->m_pMedia, 0, in_fmt, 0); + if (hr) + { + em = "input format not accepted"; + break; + } + + if (0) { + DMO_MEDIA_TYPE dmo; + /* VIDEOINFOHEADER* vi; -- not used */ + memset(&dmo, 0, sizeof(dmo)); + i = This->m_pMedia->vt->GetOutputType(This->m_pMedia, 0, 2, &dmo); + printf("GetOutputType %x \n", i); + printf("DMO 0x%x (%.4s) 0x%x (%.4s)\n" + //printf("DMO 0x%x 0x%x\n" + ":: fixszsamp:%d tempcomp:%d sampsz:%ld\n" + ":: formtype: 0x%x\n" + ":: unk %p cbform: %ld pbform:%p\n", + dmo.majortype.f1, + (const char*)&dmo.majortype.f1, + dmo.subtype.f1, + (const char*)&dmo.subtype.f1, + dmo.bFixedSizeSamples, dmo.bTemporalCompression, + dmo.lSampleSize, + dmo.formattype.f1, + dmo.pUnk, dmo.cbFormat, dmo.pbFormat + ); +/* vi = (VIDEOINFOHEADER*) dmo.pbFormat; + vi = (VIDEOINFOHEADER*) out_fmt->pbFormat; + for (i = 0; i < out_fmt->cbFormat; i++) + printf("BYTE %d %02x %02x\n", i, ((uint8_t*)dmo.pbFormat)[i], ((uint8_t*)out_fmt->pbFormat)[i]); +*/ + } + + hr = This->m_pMedia->vt->SetOutputType(This->m_pMedia, 0, out_fmt, 0); + if (hr) + { + em = "output format no accepted"; + break; + } + + inputs = outputs = 0; + hr = This->m_pMedia->vt->GetOutputSizeInfo(This->m_pMedia, 0, &inputs, &outputs); + printf("GetOutput r=0x%lx size:%ld align:%ld\n", hr, inputs, outputs); + + // This->m_pMedia->vt->AllocateStreamingResources(This->m_pMedia); + hr = This->m_pMedia->vt->GetStreamCount(This->m_pMedia, &inputs, &outputs); + printf("StreamCount r=0x%lx %ld %ld\n", hr, inputs, outputs); + + break; + } + if (em) + { + DMO_Filter_Destroy(This); + printf("IMediaObject ERROR: %p %s (0x%lx : %ld)\n", em, em ? em : "", hr, hr); + This = 0; + } + return This; +} diff --git a/src/libw32dll/dmo/dmo.h b/src/libw32dll/dmo/dmo.h new file mode 100644 index 000000000..b230a9494 --- /dev/null +++ b/src/libw32dll/dmo/dmo.h @@ -0,0 +1,81 @@ +#ifndef DMO_H +#define DMO_H + +/* + * + * Definition of important DMO interfaces. + * Created using freely-available DirectX 8.1 SDK + * ( http://msdn.microsoft.com ) + * + */ + +#include "DirectShow/iunk.h" +#include "DirectShow/guids.h" + +typedef AM_MEDIA_TYPE DMO_MEDIA_TYPE; + + + +enum _DMO_INPUT_DATA_BUFFER_FLAGS +{ + DMO_INPUT_DATA_BUFFERF_SYNCPOINT = 0x1, + DMO_INPUT_DATA_BUFFERF_TIME = 0x2, + DMO_INPUT_DATA_BUFFERF_TIMELENGTH = 0x4 +}; + +enum _DMO_OUTPUT_DATA_BUFFER_FLAGS +{ + DMO_OUTPUT_DATA_BUFFERF_SYNCPOINT = 0x1, + DMO_OUTPUT_DATA_BUFFERF_TIME = 0x2, + DMO_OUTPUT_DATA_BUFFERF_TIMELENGTH = 0x4, + DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE = 0x1000000 +}; + +enum _DMO_INPUT_STATUS_FLAGS +{ + DMO_INPUT_STATUSF_ACCEPT_DATA = 0x1 +}; + +enum _DMO_INPUT_STREAM_INFO_FLAGS +{ + DMO_INPUT_STREAMF_WHOLE_SAMPLES = 0x1, + DMO_INPUT_STREAMF_SINGLE_SAMPLE_PER_BUFFER = 0x2, + DMO_INPUT_STREAMF_FIXED_SAMPLE_SIZE = 0x4, + DMO_INPUT_STREAMF_HOLDS_BUFFERS = 0x8 +}; + +enum _DMO_OUTPUT_STREAM_INFO_FLAGS +{ + DMO_OUTPUT_STREAMF_WHOLE_SAMPLES = 0x1, + DMO_OUTPUT_STREAMF_SINGLE_SAMPLE_PER_BUFFER = 0x2, + DMO_OUTPUT_STREAMF_FIXED_SAMPLE_SIZE = 0x4, + DMO_OUTPUT_STREAMF_DISCARDABLE = 0x8, + DMO_OUTPUT_STREAMF_OPTIONAL = 0x10 +}; + +enum _DMO_SET_TYPE_FLAGS +{ + DMO_SET_TYPEF_TEST_ONLY = 0x1, + DMO_SET_TYPEF_CLEAR = 0x2 +}; + +enum _DMO_PROCESS_OUTPUT_FLAGS +{ + DMO_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER = 0x1 +}; + +enum _DMO_VIDEO_OUTPUT_STREAM_FLAGS +{ + DMO_VOSF_NEEDS_PREVIOUS_SAMPLE = 0x1 +}; + + +/* MediaErr.h */ +#define DMO_E_INVALIDSTREAMINDEX 0x80040201 +#define DMO_E_INVALIDTYPE 0x80040202 +#define DMO_E_TYPE_NOT_SET 0x80040203 +#define DMO_E_NOTACCEPTING 0x80040204 +#define DMO_E_TYPE_NOT_ACCEPTED 0x80040205 +#define DMO_E_NO_MORE_ITEMS 0x80040206 + +#endif /* DMO_H */ diff --git a/src/libw32dll/dmo/dmo_guids.c b/src/libw32dll/dmo/dmo_guids.c new file mode 100644 index 000000000..8dbeb4045 --- /dev/null +++ b/src/libw32dll/dmo/dmo_guids.c @@ -0,0 +1,42 @@ +#include "dmo_guids.h" +int DMO_DEBUG = 0; + +const GUID IID_IMediaBuffer = { 0x59eff8b9, 0x938c, 0x4a26, +{ 0x82, 0xf2, 0x95, 0xcb, 0x84, 0xcd, 0xc8, 0x37}}; +const GUID IID_IMediaObject = { 0xd8ad0f58, 0x5494, 0x4102, +{ 0x97, 0xc5, 0xec, 0x79, 0x8e, 0x59, 0xbc, 0xf4}}; +const GUID IID_IEnumDMO = { 0x2c3cd98a, 0x2bfa, 0x4a53, +{ 0x9c, 0x27, 0x52, 0x49, 0xba, 0x64, 0xba, 0x0f}}; +const GUID IID_IMediaObjectInPlace = { 0x651b9ad0, 0x0fc7, 0x4aa9, +{ 0x95, 0x38, 0xd8, 0x99, 0x31, 0x01, 0x07, 0x41}}; +const GUID IID_IDMOQualityControl = { 0x65abea96, 0xcf36, 0x453f, +{ 0xaf, 0x8a, 0x70, 0x5e, 0x98, 0xf1, 0x62, 0x60}}; +const GUID IID_IDMOVideoOutputOptimizations = { 0xbe8f4f4e, 0x5b16, 0x4d29, +{ 0xb3, 0x50, 0x7f, 0x6b, 0x5d, 0x92, 0x98, 0xac}}; + + +const GUID DMOCATEGORY_AUDIO_DECODER = { 0x57f2db8b, 0xe6bb, 0x4513, +{ 0x9d, 0x43, 0xdc, 0xd2, 0xa6, 0x59, 0x31, 0x25}}; +const GUID DMOCATEGORY_AUDIO_ENCODER = { 0x33d9a761, 0x90c8, 0x11d0, +{ 0xbd, 0x43, 0x00, 0xa0, 0xc9, 0x11, 0xce, 0x86}}; +const GUID DMOCATEGORY_VIDEO_DECODER = { 0x4a69b442, 0x28be, 0x4991, +{ 0x96, 0x9c, 0xb5, 0x00, 0xad, 0xf5, 0xd8, 0xa8}}; +const GUID DMOCATEGORY_VIDEO_ENCODER = { 0x33d9a760, 0x90c8, 0x11d0, +{ 0xbd, 0x43, 0x00, 0xa0, 0xc9, 0x11, 0xce, 0x86}}; +const GUID DMOCATEGORY_AUDIO_EFFECT = { 0xf3602b3f, 0x0592, 0x48df, +{ 0xa4, 0xcd, 0x67, 0x47, 0x21, 0xe7, 0xeb, 0xeb}}; +const GUID DMOCATEGORY_VIDEO_EFFECT = { 0xd990ee14, 0x776c, 0x4723, +{ 0xbe, 0x46, 0x3d, 0xa2, 0xf5, 0x6f, 0x10,0xb9}}; +const GUID DMOCATEGORY_AUDIO_CAPTURE_EFFECT = { 0xf665aaba, 0x3e09, 0x4920, +{ 0xaa, 0x5f, 0x21, 0x98, 0x11, 0x14, 0x8f, 0x09}}; + + +const GUID DMOCATEGORY_ACOUSTIC_ECHO_CANCEL = { 0xBF963D80L, 0xC559, 0x11D0, +{ 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}}; + +const GUID DMOCATEGORY_AUDIO_NOISE_SUPPRESS = { 0xe07f903f, 0x62fd, 0x4e60, +{ 0x8c, 0xdd, 0xde, 0xa7, 0x23, 0x66, 0x65, 0xb5}}; + +const GUID DMOCATEGORY_AGC = { 0xe88c9ba0l, 0xc557, 0x11d0, +{ 0x8a, 0x2b, 0x00, 0xa0, 0xc9, 0x25, 0x5a, 0xc1}}; + diff --git a/src/libw32dll/dmo/dmo_guids.h b/src/libw32dll/dmo/dmo_guids.h new file mode 100644 index 000000000..d0467c545 --- /dev/null +++ b/src/libw32dll/dmo/dmo_guids.h @@ -0,0 +1,35 @@ +#ifndef DMO_GUIDS_H +#define DMO_GUIDS_H + +#include "DirectShow/guids.h" + +extern const GUID IID_IMediaBuffer; +extern const GUID IID_IMediaObject; +extern const GUID IID_IEnumDMO; +extern const GUID IID_IMediaObjectInPlace; +extern const GUID IID_IDMOQualityControl; +extern const GUID IID_IDMOVideoOutputOptimizations; + +/* to be removed +extern const GUID DMOCATEGORY_AUDIO_DECODER; +extern const GUID DMOCATEGORY_AUDIO_ENCODER; +extern const GUID DMOCATEGORY_VIDEO_DECODER; +extern const GUID DMOCATEGORY_VIDEO_ENCODER; +extern const GUID DMOCATEGORY_AUDIO_EFFECT; +extern const GUID DMOCATEGORY_VIDEO_EFFECT; +extern const GUID DMOCATEGORY_AUDIO_CAPTURE_EFFECT; + +// Acoustic Echo Canceller +// Matches KSNODETYPE_ACOUSTIC_ECHO_CANCEL +extern const GUID DMOCATEGORY_ACOUSTIC_ECHO_CANCEL; + +// Noise Supression +// Matches KSNODETYPE_AUDIO_NOISE_SUPPRESS +extern const GUID DMOCATEGORY_AUDIO_NOISE_SUPPRESS; + +// Automatic Gain Control +// Matches KSNODETYPE_AGC +extern const GUID DMOCATEGORY_AGC; +*/ + +#endif diff --git a/src/libw32dll/dmo/dmo_interfaces.h b/src/libw32dll/dmo/dmo_interfaces.h new file mode 100644 index 000000000..474dc06ce --- /dev/null +++ b/src/libw32dll/dmo/dmo_interfaces.h @@ -0,0 +1,194 @@ +#ifndef DMO_INTERFACE_H +#define DMO_INTERFACE_H + +#include "dmo.h" + +/* + * IMediaBuffer interface + */ +typedef struct _IMediaBuffer IMediaBuffer; +typedef struct IMediaBuffer_vt +{ + INHERIT_IUNKNOWN(); + + HRESULT STDCALL ( *SetLength )(IMediaBuffer* This, + unsigned long cbLength); + HRESULT STDCALL ( *GetMaxLength )(IMediaBuffer* This, + /* [out] */ unsigned long *pcbMaxLength); + HRESULT STDCALL ( *GetBufferAndLength )(IMediaBuffer* This, + /* [out] */ char** ppBuffer, + /* [out] */ unsigned long* pcbLength); +} IMediaBuffer_vt; +struct _IMediaBuffer { IMediaBuffer_vt* vt; }; + + +typedef struct _DMO_OUTPUT_DATA_BUFFER +{ + IMediaBuffer *pBuffer; + unsigned long dwStatus; + REFERENCE_TIME rtTimestamp; + REFERENCE_TIME rtTimelength; +} DMO_OUTPUT_DATA_BUFFER; + + +/* + * IMediaObject interface + */ +typedef struct _IMediaObject IMediaObject; +typedef struct IMediaObject_vt +{ + INHERIT_IUNKNOWN(); + + HRESULT STDCALL ( *GetStreamCount )(IMediaObject * This, + /* [out] */ unsigned long *pcInputStreams, + /* [out] */ unsigned long *pcOutputStreams); + HRESULT STDCALL ( *GetInputStreamInfo )(IMediaObject * This, + unsigned long dwInputStreamIndex, + /* [out] */ unsigned long *pdwFlags); + HRESULT STDCALL ( *GetOutputStreamInfo )(IMediaObject * This, + unsigned long dwOutputStreamIndex, + /* [out] */ unsigned long *pdwFlags); + HRESULT STDCALL ( *GetInputType )(IMediaObject * This, + unsigned long dwInputStreamIndex, + unsigned long dwTypeIndex, + /* [out] */ DMO_MEDIA_TYPE *pmt); + HRESULT STDCALL ( *GetOutputType )(IMediaObject * This, + unsigned long dwOutputStreamIndex, + unsigned long dwTypeIndex, + /* [out] */ DMO_MEDIA_TYPE *pmt); + HRESULT STDCALL ( *SetInputType )(IMediaObject * This, + unsigned long dwInputStreamIndex, + /* [in] */ const DMO_MEDIA_TYPE *pmt, + unsigned long dwFlags); + HRESULT STDCALL ( *SetOutputType )(IMediaObject * This, + unsigned long dwOutputStreamIndex, + /* [in] */ const DMO_MEDIA_TYPE *pmt, + unsigned long dwFlags); + HRESULT STDCALL ( *GetInputCurrentType )(IMediaObject * This, + unsigned long dwInputStreamIndex, + /* [out] */ DMO_MEDIA_TYPE *pmt); + HRESULT STDCALL ( *GetOutputCurrentType )(IMediaObject * This, + unsigned long dwOutputStreamIndex, + /* [out] */ DMO_MEDIA_TYPE *pmt); + HRESULT STDCALL ( *GetInputSizeInfo )(IMediaObject * This, + unsigned long dwInputStreamIndex, + /* [out] */ unsigned long *pcbSize, + /* [out] */ unsigned long *pcbMaxLookahead, + /* [out] */ unsigned long *pcbAlignment); + HRESULT STDCALL ( *GetOutputSizeInfo )(IMediaObject * This, + unsigned long dwOutputStreamIndex, + /* [out] */ unsigned long *pcbSize, + /* [out] */ unsigned long *pcbAlignment); + HRESULT STDCALL ( *GetInputMaxLatency )(IMediaObject * This, + unsigned long dwInputStreamIndex, + /* [out] */ REFERENCE_TIME *prtMaxLatency); + HRESULT STDCALL ( *SetInputMaxLatency )(IMediaObject * This, + unsigned long dwInputStreamIndex, + REFERENCE_TIME rtMaxLatency); + HRESULT STDCALL ( *Flush )(IMediaObject * This); + HRESULT STDCALL ( *Discontinuity )(IMediaObject * This, + unsigned long dwInputStreamIndex); + HRESULT STDCALL ( *AllocateStreamingResources )(IMediaObject * This); + HRESULT STDCALL ( *FreeStreamingResources )(IMediaObject * This); + HRESULT STDCALL ( *GetInputStatus )(IMediaObject * This, + unsigned long dwInputStreamIndex, + /* [out] */ unsigned long *dwFlags); + HRESULT STDCALL ( *ProcessInput )(IMediaObject * This, + unsigned long dwInputStreamIndex, + IMediaBuffer *pBuffer, + unsigned long dwFlags, + REFERENCE_TIME rtTimestamp, + REFERENCE_TIME rtTimelength); + HRESULT STDCALL ( *ProcessOutput )(IMediaObject * This, + unsigned long dwFlags, + unsigned long cOutputBufferCount, + /* [size_is][out][in] */ DMO_OUTPUT_DATA_BUFFER *pOutputBuffers, + /* [out] */ unsigned long *pdwStatus); + HRESULT STDCALL ( *Lock )(IMediaObject * This, long bLock); +} IMediaObject_vt; +struct _IMediaObject { IMediaObject_vt* vt; }; + +/* + * IEnumDMO interface + */ +typedef struct _IEnumDMO IEnumDMO; +typedef struct IEnumDMO_vt +{ + INHERIT_IUNKNOWN(); + + HRESULT STDCALL ( *Next )(IEnumDMO * This, + unsigned long cItemsToFetch, + /* [length_is][size_is][out] */ CLSID *pCLSID, + /* [string][length_is][size_is][out] */ WCHAR **Names, + /* [out] */ unsigned long *pcItemsFetched); + HRESULT STDCALL ( *Skip )(IEnumDMO * This, + unsigned long cItemsToSkip); + HRESULT STDCALL ( *Reset )(IEnumDMO * This); + HRESULT STDCALL ( *Clone )(IEnumDMO * This, + /* [out] */ IEnumDMO **ppEnum); +} IEnumDMO_vt; +struct _IEnumDMO { IEnumDMO_vt* vt; }; + +/* + * IMediaObjectInPlace interface + */ +typedef struct _IMediaObjectInPlace IMediaObjectInPlace; +typedef struct IMediaObjectInPlace_vt +{ + INHERIT_IUNKNOWN(); + + HRESULT STDCALL ( *Process )(IMediaObjectInPlace * This, + /* [in] */ unsigned long ulSize, + /* [size_is][out][in] */ BYTE *pData, + /* [in] */ REFERENCE_TIME refTimeStart, + /* [in] */ unsigned long dwFlags); + HRESULT STDCALL ( *Clone )(IMediaObjectInPlace * This, + /* [out] */ IMediaObjectInPlace **ppMediaObject); + HRESULT STDCALL ( *GetLatency )(IMediaObjectInPlace * This, + /* [out] */ REFERENCE_TIME *pLatencyTime); + +} IMediaObjectInPlace_vt; +struct _IMediaObjectInPlace { IMediaObjectInPlace_vt* vt; }; + + +/* + * IDMOQualityControl interface + */ +typedef struct _IDMOQualityControl IDMOQualityControl; +typedef struct IDMOQualityControl_vt +{ + INHERIT_IUNKNOWN(); + + HRESULT STDCALL ( *SetNow )(IDMOQualityControl * This, + /* [in] */ REFERENCE_TIME rtNow); + HRESULT STDCALL ( *SetStatus )(IDMOQualityControl * This, + /* [in] */ unsigned long dwFlags); + HRESULT STDCALL ( *GetStatus )(IDMOQualityControl * This, + /* [out] */ unsigned long *pdwFlags); +} IDMOQualityControl_vt; +struct _IDMOQualityControl { IDMOQualityControl_vt* vt; }; + +/* + * IDMOVideoOutputOptimizations interface + */ +typedef struct _IDMOVideoOutputOptimizations IDMOVideoOutputOptimizations; +typedef struct IDMOVideoOutputOptimizations_vt +{ + INHERIT_IUNKNOWN(); + + HRESULT STDCALL ( *QueryOperationModePreferences )(IDMOVideoOutputOptimizations * This, + unsigned long ulOutputStreamIndex, + unsigned long *pdwRequestedCapabilities); + HRESULT STDCALL ( *SetOperationMode )(IDMOVideoOutputOptimizations * This, + unsigned long ulOutputStreamIndex, + unsigned long dwEnabledFeatures); + HRESULT STDCALL ( *GetCurrentOperationMode )(IDMOVideoOutputOptimizations * This, + unsigned long ulOutputStreamIndex, + unsigned long *pdwEnabledFeatures); + HRESULT STDCALL ( *GetCurrentSampleRequirements )(IDMOVideoOutputOptimizations * This, + unsigned long ulOutputStreamIndex, + unsigned long *pdwRequestedFeatures); +} IDMOVideoOutputOptimizations_vt; +struct _IDMOVideoOutputOptimizations { IDMOVideoOutputOptimizations_vt* vt; }; + +#endif /* DMO_INTERFACE_H */ |