⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dmo_win32.c

📁 大名鼎鼎的CE下播放软件,TCPPMP的源代码!!!2410下可以流畅的解QVGA的H264,MPEG4等格式.
💻 C
📖 第 1 页 / 共 3 页
字号:
/*****************************************************************************
 *
 * This program is free software ; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 *
 * $Id: dmo_win32.c 622 2006-01-31 19:02:53Z picard $
 *
 * The Core Pocket Media Player
 * Copyright (c) 2004-2005 Gabor Kovacs
 *
 ****************************************************************************/

#include "../common.h"

#if defined(TARGET_WIN32) || defined(TARGET_WINCE)

#ifndef STRICT
#define STRICT
#endif
#define _WIN32_WINNT 0x0400
#define INITGUID
#include <objbase.h>

#define DMO_CLASS		FOURCC('A','D','M','O')

// string table
#define DMO_MODULE		0x200
#define DMO_MODULEPPC	0x201
#define DMO_CLASSID		0x202

// registry
#define DMO_FOUND		0x400

#define WMV_ID			FOURCC('W','M','V','_')
#define WMS_ID			FOURCC('W','M','S','_')
#define WMVA_ID			FOURCC('W','M','V','A')
#define WMA_ID			FOURCC('W','M','A','_')
#define WMAV_ID			FOURCC('W','M','A','V')

#define DMO_INPUT_STATUSF_ACCEPT_DATA				0x00000001

#define DMO_INPUT_DATA_BUFFERF_SYNCPOINT			0x00000001
#define DMO_INPUT_DATA_BUFFERF_TIME					0x00000002
#define DMO_INPUT_DATA_BUFFERF_TIMELENGTH			0x00000004

#define DMO_INPUT_STREAMF_WHOLE_SAMPLES				0x00000001
#define DMO_INPUT_STREAMF_SINGLE_SAMPLE_PER_BUFFER	0x00000002
#define DMO_INPUT_STREAMF_FIXED_SAMPLE_SIZE			0x00000004
#define DMO_INPUT_STREAMF_HOLDS_BUFFERS				0x00000008

#define DMO_SET_TYPEF_TEST_ONLY						0x00000001
#define DMO_SET_TYPEF_CLEAR							0x00000002

#define DMO_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER	0x00000001

#define	DMO_OUTPUT_DATA_BUFFERF_SYNCPOINT			0x00000001
#define	DMO_OUTPUT_DATA_BUFFERF_TIME				0x00000002
#define	DMO_OUTPUT_DATA_BUFFERF_TIMELENGTH			0x00000004
#define	DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE			0x01000000

const guid ID_IMEDIABUFFER = {0x59eff8b9,0x938c,0x4a26,{0x82,0xf2,0x95,0xcb,0x84,0xcd,0xc8,0x37}};
const guid ID_IUNKNOWN = {0x00000000,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
const guid ID_ICLASSFACTORY = {00000001,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
const guid ID_IDMOQUALITYCONTROL = {0x65abea96,0xcf36,0x453f,{0xaf,0x8a,0x70,0x5e,0x98,0xf1,0x62,0x60}};
const guid WMCMEDIATYPE_Video = {0x73646976, 0x0000, 0x0010,{0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
const guid WMCMEDIATYPE_Audio = {0x73647561, 0x0000, 0x0010,{0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
const guid WMCFORMAT_VideoInfo = {0x05589f80, 0xc356, 0x11ce,{0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}};
const guid WMCFORMAT_WaveFormatEx = {0x05589f81, 0xc356, 0x11ce,{0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}};
const guid WMCMEDIASUBTYPE = {0x00000000,0x0000, 0x0010,{0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71}};
const guid WMCMEDIASUBTYPE_RGB565 = {0xe436eb7b, 0x524f, 0x11ce,{0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}};
const guid IID_IMediaObject = { 0xd8ad0f58, 0x5494, 0x4102,{0x97, 0xc5, 0xec, 0x79, 0x8e, 0x59, 0xbc, 0xf4}};

typedef int64_t REFERENCE_TIME;

struct IMediaObject;
struct IMediaBuffer;
struct IDMOQualityControl;

typedef struct VIDEOINFOHEADER 
{
	RECT rcSource;
	RECT rcTarget;
	DWORD dwBitRate;
	DWORD dwBitErrorRate;
	REFERENCE_TIME AvgTimePerFrame;
	BITMAPINFOHEADER bmiHeader;

} VIDEOINFOHEADER;

typedef struct DMO_MEDIA_TYPE
{
    guid majortype;
    guid subtype;
    BOOL bFixedSizeSamples;
    BOOL bTemporalCompression;
    ULONG lSampleSize;
    guid formattype;
    IUnknown* pUnk;
    ULONG cbFormat;
    BYTE* pbFormat;

} DMO_MEDIA_TYPE;

typedef struct DMO_OUTPUT_DATA_BUFFER
{
    struct IMediaBuffer* pBuffer;
    DWORD dwStatus;
    REFERENCE_TIME rtTimestamp;
    REFERENCE_TIME rtTimelength;

} DMO_OUTPUT_DATA_BUFFER;

typedef struct IMediaBufferVMT
{
    HRESULT (STDCALL *QueryInterface)(void* This, const guid* riid, void **ppvObject);    
    ULONG (STDCALL *AddRef)(void* This);     
    ULONG (STDCALL *Release)(void* This);    
    HRESULT (STDCALL *SetLength)(void* This, DWORD cbLength);    
    HRESULT (STDCALL *GetMaxLength)(void* This, DWORD *pcbMaxLength);    
    HRESULT (STDCALL *GetBufferAndLength)(void* This, BYTE **ppBuffer, DWORD *pcbLength);
    
} IMediaBufferVMT;

typedef struct IMediaBuffer
{
    struct IMediaBufferVMT *VMT;

} IMediaBuffer;

typedef struct IDMOQualityControlVMT
{
    HRESULT (STDCALL *QueryInterface)(struct IDMOQualityControl* This, const guid* riid, void** ppvObject);
    ULONG (STDCALL *AddRef)(struct IDMOQualityControl* This);
    ULONG (STDCALL *Release)(struct IDMOQualityControl* This);
    HRESULT (STDCALL *SetNow)(struct IDMOQualityControl* This, REFERENCE_TIME rtNow);
    HRESULT (STDCALL *SetStatus)(struct IDMOQualityControl* This, DWORD dwFlags);
    HRESULT (STDCALL *GetStatus)(struct IDMOQualityControl* This, DWORD *pdwFlags);

} IDMOQualityControlVMT;

typedef struct IDMOQualityControl
{
	IDMOQualityControlVMT *VMT;

} IDMOQualityControl;
 
typedef struct IMediaObjectVMT
{
    HRESULT (STDCALL *QueryInterface)(struct IMediaObject * This, const guid* riid, void** ppvObject);
    ULONG (STDCALL *AddRef)(struct IMediaObject * This);
    ULONG (STDCALL *Release)(struct IMediaObject * This);
    HRESULT (STDCALL *GetStreamCount)(struct IMediaObject * This, DWORD *pcInputStreams, DWORD *pcOutputStreams);
    HRESULT (STDCALL *GetInputStreamInfo)(struct IMediaObject * This, DWORD dwInputStreamIndex, DWORD *pdwFlags);
    HRESULT (STDCALL *GetOutputStreamInfo)(struct IMediaObject * This, DWORD dwOutputStreamIndex, DWORD *pdwFlags);    
	HRESULT (STDCALL *GetInputType)(struct IMediaObject * This, DWORD dwInputStreamIndex, DWORD dwTypeIndex, DMO_MEDIA_TYPE *pmt);
    HRESULT (STDCALL *GetOutputType)(struct IMediaObject * This, DWORD dwOutputStreamIndex, DWORD dwTypeIndex, DMO_MEDIA_TYPE *pmt);
    HRESULT (STDCALL *SetInputType)(struct IMediaObject * This, DWORD dwInputStreamIndex, const DMO_MEDIA_TYPE *pmt, DWORD dwFlags);    
    HRESULT (STDCALL *SetOutputType)(struct IMediaObject * This, DWORD dwOutputStreamIndex,const DMO_MEDIA_TYPE *pmt, DWORD dwFlags);    
    HRESULT (STDCALL *GetInputCurrentType)(struct IMediaObject * This, DWORD dwInputStreamIndex, DMO_MEDIA_TYPE *pmt);    
    HRESULT (STDCALL *GetOutputCurrentType)(struct IMediaObject * This, DWORD dwOutputStreamIndex, DMO_MEDIA_TYPE *pmt);    
    HRESULT (STDCALL *GetInputSizeInfo)(struct IMediaObject * This, DWORD dwInputStreamIndex, DWORD *pcbSize, DWORD *pcbMaxLookahead, DWORD *pcbAlignment);
    HRESULT (STDCALL *GetOutputSizeInfo)(struct IMediaObject * This, DWORD dwOutputStreamIndex, DWORD *pcbSize, DWORD *pcbAlignment);     
    HRESULT (STDCALL *GetInputMaxLatency)(struct IMediaObject * This, DWORD dwInputStreamIndex, REFERENCE_TIME *prtMaxLatency);    
    HRESULT (STDCALL *SetInputMaxLatency)(struct IMediaObject * This, DWORD dwInputStreamIndex, REFERENCE_TIME rtMaxLatency);    
    HRESULT (STDCALL *Flush)(struct IMediaObject * This);
    HRESULT (STDCALL *Discontinuity)(struct IMediaObject * This, DWORD dwInputStreamIndex);
    HRESULT (STDCALL *AllocateStreamingResources)(struct IMediaObject * This);    
    HRESULT (STDCALL *FreeStreamingResources)(struct IMediaObject * This);    
    HRESULT (STDCALL *GetInputStatus)(struct IMediaObject * This,DWORD dwInputStreamIndex,DWORD *dwFlags);    
    HRESULT (STDCALL *ProcessInput)(struct IMediaObject * This, DWORD dwInputStreamIndex, IMediaBuffer *pBuffer, DWORD dwFlags, REFERENCE_TIME rtTimestamp, REFERENCE_TIME rtTimelength);    
    HRESULT (STDCALL *ProcessOutput)(struct IMediaObject * This, DWORD dwFlags, DWORD cOutputBufferCount, DMO_OUTPUT_DATA_BUFFER *pOutputBuffers, DWORD *pdwStatus);   
    HRESULT (STDCALL *Lock)(struct IMediaObject * This, LONG bLock);
    
} IMediaObjectVMT;

typedef struct IMediaObject
{
    IMediaObjectVMT *VMT;

} IMediaObject;

#define DMO_INPUT		0x100
#define DMO_OUTPUT		0x101

typedef struct IOwnMediaBuffer
{
    struct IMediaBufferVMT *VMT;

	int RefCount;
	int Length;
	int Allocated; // -1 for external allocated buffer
	void* Data;

	struct IOwnMediaBuffer** Chain;
	struct IOwnMediaBuffer* Next;

} IOwnMediaBuffer;

typedef struct dmo
{
	codec Codec;

	HMODULE Module;
	guid ClassId;
	int (STDCALL *CreateCodecDMO)(IMediaObject**);
	int (STDCALL *CreateCodecDMOEx)(int Code,IMediaObject**);
	int (STDCALL *QueryUnloadCodecDMO)();
	int (STDCALL *DllGetClassObject)(const guid*,const guid*,IClassFactory**);
	int (STDCALL *DllCanUnloadNow)();

	IMediaObject* Media;
	IOwnMediaBuffer* InputBuffers;
	DMO_OUTPUT_DATA_BUFFER OutputBuffer[2];
	int OutputNoMask;
	int OutputNext;
	int OutputPrev;

	DMO_MEDIA_TYPE InType;
	DMO_MEDIA_TYPE OutType;
	int ConstSize;
	BITMAPINFOHEADER* Const;

	int WMPVersion;
	bool_t First;
	bool_t UseDropping;

} dmo;

static HRESULT STDCALL MoInitMediaType(DMO_MEDIA_TYPE* p, DWORD Size)
{
	p->pUnk = NULL;
	p->pbFormat = NULL;
	p->cbFormat = Size;
	if (Size)
	{
		p->pbFormat = CoTaskMemAlloc(Size);
		if (!p->pbFormat)
		{
			p->cbFormat = 0;
			return E_OUTOFMEMORY;
		}
	}
	return S_OK;
}

static HRESULT STDCALL MoFreeMediaType(DMO_MEDIA_TYPE* p)
{
	if (p->pUnk)
	{
		p->pUnk->lpVtbl->Release(p->pUnk);
		p->pUnk = NULL;
	}
	if (p->pbFormat)
	{
		CoTaskMemFree(p->pbFormat);
		p->pbFormat = NULL;
	}
	p->cbFormat = 0;
	return S_OK;
}

static HRESULT STDCALL MBQueryInterface(IOwnMediaBuffer * p, const guid* riid, void **ppvObject)
{
	if (memcmp(riid,&ID_IMEDIABUFFER,sizeof(GUID))==0 ||
		memcmp(riid,&ID_IUNKNOWN,sizeof(GUID))==0)
	{
		if (ppvObject)
		{
			++p->RefCount;
			*ppvObject = p;
		}
		return 0;
	}
	return -1;
}

static ULONG STDCALL MBAddRef(IOwnMediaBuffer * p)
{
	p->RefCount++;
	return 0;
}

static HRESULT STDCALL MBSetMaxLength(IOwnMediaBuffer * p, DWORD cbLength)
{
	if (cbLength > 0)
	{
		if ((int)cbLength > p->Allocated)
		{
			void* Data = realloc(p->Data,cbLength);
			if (!Data && cbLength)
				return E_OUTOFMEMORY;
			p->Data = Data;
			p->Allocated = cbLength;
		}
	}
	else
	{
		free(p->Data);
		p->Data = NULL;
		p->Allocated = 0;
	}
	if (p->Length > p->Allocated)
		p->Length = p->Allocated;
	return 0;
}

static ULONG STDCALL MBRelease(IOwnMediaBuffer * p)
{
	if (--p->RefCount<=0)
	{
		p->Length = 0;
		if (p->Chain)
		{
			p->Next = *p->Chain;
			*p->Chain = p;
		}
		else
		{
			free(p->Data);
			free(p);
			return 0;
		}
	}
	return p->RefCount;
}

static HRESULT STDCALL MBSetLength(IOwnMediaBuffer * p, DWORD cbLength)
{
	DEBUG_MSG2(DEBUG_VIDEO,T("MediaBuffer_SetLength %d (%d)"),cbLength,p->Allocated);
	if ((int)cbLength > p->Allocated)
		return -1;
	p->Length = cbLength;
	return 0;
}

static HRESULT STDCALL MBGetMaxLength(IOwnMediaBuffer * p, DWORD *pcbMaxLength)
{
	DEBUG_MSG1(DEBUG_VIDEO,T("MediaBuffer_GetMaxLength %d"),p->Allocated);
	if (pcbMaxLength)
		*pcbMaxLength = p->Allocated;
	return 0;
}

static HRESULT STDCALL MBGetBufferAndLength(IOwnMediaBuffer * p, BYTE **ppBuffer, DWORD *pcbLength)
{
	DEBUG_MSG1(DEBUG_VIDEO,T("MediaBuffer_GetBufferAndLength %d"),p->Length);
	if (ppBuffer)
		*ppBuffer = (BYTE*)p->Data;
	if (pcbLength)
		*pcbLength = p->Length;
	return 0;
}

static IMediaBufferVMT MediaBufferVMT =
{
    MBQueryInterface,
    MBAddRef,
    MBRelease,
    MBSetLength,
    MBGetMaxLength,
    MBGetBufferAndLength,
};

static void FreeBuffers(IOwnMediaBuffer** Chain)
{
	while (*Chain)
	{
		IOwnMediaBuffer* p = (*Chain)->Next;
		MBSetMaxLength(*Chain,0);
		free(*Chain);
		*Chain = p;
	}
}

static INLINE void AppendBuffer(IOwnMediaBuffer* p, int Length, const void* Data)
{
	memcpy((char*)p->Data + p->Length, Data, Length);
	p->Length += Length;
}

static IOwnMediaBuffer* AllocBuffer(int MaxLength,IOwnMediaBuffer** Chain)
{
	IOwnMediaBuffer* p = Chain ? *Chain : NULL;

	if (MaxLength <= 0)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -