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

📄 dmo_win32.c

📁 betaplayer的源码 tcpmp的老版本
💻 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.c 11 2004-07-15 13:46:20Z picard $
 *
 * BetaPlayer Core
 * Copyright (c) 2004 Gabor Kovacs
 *
 ****************************************************************************/

#include "../stdafx.h"

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

//#define static 

#if defined(_WIN32_WCE)
#define ACCESS_LOAD		0
#define ACCESS_SAVE		0 
#else
#define ACCESS_LOAD		KEY_READ
#define ACCESS_SAVE		KEY_READ | KEY_WRITE | KEY_SET_VALUE 
#endif

#if defined(_WIN32_WCE)
#define TWIN(a) L ## a
#else
#define TWIN(a) a
#endif

#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

DEFINE_GUID(ID_IMEDIABUFFER,0x59eff8b9,0x938c,0x4a26,0x82,0xf2,0x95,0xcb,0x84,0xcd,0xc8,0x37);
DEFINE_GUID(ID_IUNKNOWN,0x00000000,0x0000,0x0000,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
DEFINE_GUID(ID_ICLASSFACTORY,00000001,0x0000,0x0000,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);

DEFINE_GUID(ID_IDMOQUALITYCONTROL,0x65abea96,0xcf36,0x453f,0xaf,0x8a,0x70,0x5e,0x98,0xf1,0x62,0x60);

EXTERN_GUID(WMCMEDIATYPE_Video,0x73646976, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
EXTERN_GUID(WMCMEDIATYPE_Audio,0x73647561, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);

EXTERN_GUID(WMCFORMAT_VideoInfo,0x05589f80, 0xc356, 0x11ce, 0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a); 
EXTERN_GUID(WMCFORMAT_WaveFormatEx,0x05589f81, 0xc356, 0x11ce, 0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a); 

EXTERN_GUID(WMCMEDIASUBTYPE,		0,		    0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71);
EXTERN_GUID(WMCMEDIASUBTYPE_RGB565,	0xe436eb7b, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70);

const IID 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, REFIID 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, REFIID 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, REFIID 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;

static HRESULT (STDCALL* FuncMoInitMediaType)( DMO_MEDIA_TYPE*, DWORD Size );
static HRESULT (STDCALL* FuncMoFreeMediaType)( DMO_MEDIA_TYPE* );

#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
{
	node VMT;
	
	int Id;
	const CLSID *ClassId;
	HMODULE Module;
	int (STDCALL *CreateCodecDMO)(IMediaObject**);
	int (STDCALL *QueryUnloadCodecDMO)();
	int (STDCALL *DllGetClassObject)(REFCLSID,REFIID,IClassFactory**);
	int (STDCALL *DllCanUnloadNow)();

	int FourCCCount;
	int FourCC[32];

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

	int WMPVersion;
	int FormatType;
	int FormatSize;
	void* InputFormat;
	void* OutputFormat;
	pin Output;

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

	int TotalBytes;
	int TotalPackets;
	int DroppedPackets;
	bool_t Pending;
	bool_t First;
	bool_t UseDropping;
	packet Packet;

	struct dmo* Chain;

} dmo;

//****************************************************

HRESULT STDCALL MBQueryInterface( IOwnMediaBuffer * p, REFIID 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;
}

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

HRESULT STDCALL MBSetMaxLength( IOwnMediaBuffer * p, DWORD cbLength)
{
	if (cbLength > 0)
	{
		if ((int)cbLength > p->Allocated)
		{
			p->Data = ReAlloc(p->Data,cbLength);
			p->Allocated = p->Data ? cbLength:0;
		}
	}
	else
	{
		Free(p->Data);
		p->Data = NULL;
		p->Allocated = 0;
	}
	if (p->Length > p->Allocated)
		p->Length = p->Allocated;
	return 0;
}

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;
}

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;
}

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

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, void* Data )
{
	memcpy((char*)p->Data + p->Length, Data, Length );
	p->Length += Length;
}

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

	if (MaxLength <= 0)
		return NULL;

	if (p)
		*Chain = p->Next;
	else
	{
		p = (IOwnMediaBuffer*) CAlloc(sizeof(IOwnMediaBuffer),1);
		if (!p)
			return NULL;
		p->VMT = &MediaBufferVMT;
	}

	p->Chain = Chain;
	p->Length = 0;

	MBSetMaxLength(p,MaxLength);

	p->VMT->AddRef(p);

	return (IMediaBuffer*)p;
}

//****************************************************

bool_t BuildI420( dmo* p )
{
	// manual video format guessing (for wince4 non pocketpc)

	VIDEOINFOHEADER* VideoInfo;
	video* Video = (video*) p->OutputFormat;
	memcpy(p->OutputFormat,p->InputFormat,sizeof(video));

	Video->Pixel.Flags = PF_FOURCC;
	Video->Pixel.FourCC = FOURCC_I420;
	Video->Pixel.BitCount = 16;
	Video->Pitch = Video->Width;

	if (FuncMoInitMediaType(&p->OutType,sizeof(VIDEOINFOHEADER)) != S_OK)
		return 0;

	VideoInfo = (VIDEOINFOHEADER*)p->OutType.pbFormat;
	memset(VideoInfo,0,sizeof(VIDEOINFOHEADER));

	VideoInfo->bmiHeader.biSize = sizeof(VideoInfo->bmiHeader);
	VideoInfo->bmiHeader.biWidth = Video->Width;
	VideoInfo->bmiHeader.biHeight = Video->Height;
	VideoInfo->bmiHeader.biCompression = Video->Pixel.FourCC;
	VideoInfo->bmiHeader.biBitCount = (WORD)Video->Pixel.BitCount;
	VideoInfo->bmiHeader.biPlanes = 1;
	VideoInfo->bmiHeader.biSizeImage = (Video->Width * Video->Height * Video->Pixel.BitCount)/8;

	VideoInfo->rcSource.left   = 0;
	VideoInfo->rcSource.top    = 0;
	VideoInfo->rcSource.right  = Video->Width;
	VideoInfo->rcSource.bottom = Video->Height;
	VideoInfo->rcTarget        = VideoInfo->rcSource;

	p->OutType.majortype = WMCMEDIATYPE_Video;
	p->OutType.formattype = WMCFORMAT_VideoInfo;
	p->OutType.subtype = WMCMEDIASUBTYPE;
	p->OutType.subtype.Data1 = FOURCC_YUY2; // tricky
	p->OutType.bTemporalCompression = 0;
	p->OutType.bFixedSizeSamples = 1;
	p->OutType.lSampleSize = 0;

/*	
	if (FuncMoInitMediaType(&p->OutType,sizeof(VIDEOINFOHEADER)) != S_OK)
		return 0;

	VideoInfo = (VIDEOINFOHEADER*)p->OutType.pbFormat;
	memset(VideoInfo,0,sizeof(VIDEOINFOHEADER));

⌨️ 快捷键说明

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