From c989ead81b1629d601fbc25975a33a28952485e7 Mon Sep 17 00:00:00 2001 From: arpi Date: Tue, 26 Nov 2002 22:54:11 +0000 Subject: DMO interfaces (copied/converted(c++->c) from avifile) git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@8295 b3059339-0415-0410-9bf9-f77b7e298cf2 --- loader/dmo/DMO_Filter.h | 47 ++++ loader/dmo/DMO_VideoDecoder.c | 552 ++++++++++++++++++++++++++++++++++++++++++ loader/dmo/DMO_VideoDecoder.h | 26 ++ loader/dmo/Makefile | 45 ++++ loader/dmo/buffer.c | 119 +++++++++ loader/dmo/dmo.c | 156 ++++++++++++ loader/dmo/dmo.h | 81 +++++++ loader/dmo/dmo_guids.c | 42 ++++ loader/dmo/dmo_guids.h | 35 +++ loader/dmo/dmo_interfaces.h | 194 +++++++++++++++ 10 files changed, 1297 insertions(+) create mode 100644 loader/dmo/DMO_Filter.h create mode 100644 loader/dmo/DMO_VideoDecoder.c create mode 100644 loader/dmo/DMO_VideoDecoder.h create mode 100644 loader/dmo/Makefile create mode 100644 loader/dmo/buffer.c create mode 100644 loader/dmo/dmo.c create mode 100644 loader/dmo/dmo.h create mode 100644 loader/dmo/dmo_guids.c create mode 100644 loader/dmo/dmo_guids.h create mode 100644 loader/dmo/dmo_interfaces.h (limited to 'loader') diff --git a/loader/dmo/DMO_Filter.h b/loader/dmo/DMO_Filter.h new file mode 100644 index 0000000000..0c5855ad73 --- /dev/null +++ b/loader/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/loader/dmo/DMO_VideoDecoder.c b/loader/dmo/DMO_VideoDecoder.c new file mode 100644 index 0000000000..f62a0fab74 --- /dev/null +++ b/loader/dmo/DMO_VideoDecoder.c @@ -0,0 +1,552 @@ +/******************************************************** + + DirectShow Video decoder implementation + Copyright 2000 Eugene Kuznetsov (divx@euro.ru) + +*********************************************************/ + +#include "guids.h" +#include "interfaces.h" +#include "registry.h" + +#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 +#include +#include +#include +#include +#include +#include // 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; + + Setup_LDT_Keeper(); + + //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 ", &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/loader/dmo/DMO_VideoDecoder.h b/loader/dmo/DMO_VideoDecoder.h new file mode 100644 index 0000000000..1f48523a1e --- /dev/null +++ b/loader/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/loader/dmo/Makefile b/loader/dmo/Makefile new file mode 100644 index 0000000000..4562c1b792 --- /dev/null +++ b/loader/dmo/Makefile @@ -0,0 +1,45 @@ + +LIBNAME = libDMO_Filter.a + +include ../../config.mak + +# DS_AudioDec.c +SRCS = DMO_VideoDecoder.c buffer.c dmo.c dmo_guids.c +OBJS = $(SRCS:.c=.o) + +INCLUDE = -I. -I../dshow -I.. $(EXTRA_INC) +CFLAGS = $(OPTFLAGS) $(INCLUDE) -DNOAVIFILE_HEADERS + +.SUFFIXES: .c .o + +# .PHONY: all clean + +.c.o: + $(CC) -c $(CFLAGS) -o $@ $< + +$(LIBNAME): $(OBJS) + $(AR) r $(LIBNAME) $(OBJS) + +test: test.c $(LIBNAME) + $(CC) test.c $(CFLAGS) -o test ./libDMO_Filter.a ../libloader.a $(ARCH_LIBS) -lstdc++ + +all: $(LIBNAME) + +clean: + rm -f *.o *.a *~ + +distclean: + rm -f Makefile.bak *.o *.a *~ .depend test test.raw + +dep: depend + +depend: + $(CC) -MM $(CFLAGS) $(SRCS) 1>.depend + +# +# include dependency files if they exist +# +ifneq ($(wildcard .depend),) +include .depend +endif + diff --git a/loader/dmo/buffer.c b/loader/dmo/buffer.c new file mode 100644 index 0000000000..3d53c3ce99 --- /dev/null +++ b/loader/dmo/buffer.c @@ -0,0 +1,119 @@ +#include "DMO_Filter.h" + +#include "wine/winerror.h" +#include "wine/windef.h" + +#include +#include +#include + +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/loader/dmo/dmo.c b/loader/dmo/dmo.c new file mode 100644 index 0000000000..f328a86969 --- /dev/null +++ b/loader/dmo/dmo.c @@ -0,0 +1,156 @@ +#include "DMO_Filter.h" +#include "driver.h" +#include "com.h" +#include +#include +#include +#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; + 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/loader/dmo/dmo.h b/loader/dmo/dmo.h new file mode 100644 index 0000000000..bd94e75022 --- /dev/null +++ b/loader/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 "dshow/iunk.h" +#include "dshow/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/loader/dmo/dmo_guids.c b/loader/dmo/dmo_guids.c new file mode 100644 index 0000000000..8dbeb40459 --- /dev/null +++ b/loader/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/loader/dmo/dmo_guids.h b/loader/dmo/dmo_guids.h new file mode 100644 index 0000000000..3fe6d1c942 --- /dev/null +++ b/loader/dmo/dmo_guids.h @@ -0,0 +1,35 @@ +#ifndef DMO_GUIDS_H +#define DMO_GUIDS_H + +#include "dshow/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/loader/dmo/dmo_interfaces.h b/loader/dmo/dmo_interfaces.h new file mode 100644 index 0000000000..474dc06ceb --- /dev/null +++ b/loader/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 */ -- cgit v1.2.3