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

📄 overlay_raw.c

📁 大名鼎鼎的CE下播放软件,TCPPMP的源代码!!!2410下可以流畅的解QVGA的H264,MPEG4等格式.
💻 C
字号:
/*****************************************************************************
 *
 * 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: overlay_raw.c 543 2006-01-07 22:06:24Z picard $
 *
 * The Core Pocket Media Player
 * Copyright (c) 2004-2005 Gabor Kovacs
 *
 ****************************************************************************/

#include "../common.h"

#ifdef TARGET_WINCE

#define WIN32_LEAN_AND_MEAN
#ifndef STRICT
#define STRICT
#endif
#include <windows.h>

typedef struct raw
{
	overlay Overlay;
	void* Ptr;
	RawFrameBufferInfo Info;

} raw;

static const datatable Params[] = 
{
	{ RAW_WIDTH,	TYPE_INT, DF_SETUP | DF_RDONLY | DF_HIDDEN },
	{ RAW_HEIGHT,	TYPE_INT, DF_SETUP | DF_RDONLY | DF_HIDDEN },
	{ RAW_PITCHX,	TYPE_INT, DF_SETUP | DF_RDONLY | DF_HIDDEN },
	{ RAW_PITCHY,	TYPE_INT, DF_SETUP | DF_RDONLY | DF_HIDDEN },
	{ RAW_BPP,		TYPE_INT, DF_SETUP | DF_RDONLY | DF_HIDDEN },
	{ RAW_FORMAT,	TYPE_INT, DF_SETUP | DF_RDONLY | DF_HIDDEN },
	{ RAW_POINTER,	TYPE_INT, DF_SETUP | DF_RDONLY | DF_HEX | DF_HIDDEN },

	DATATABLE_END(RAW_ID),
};

static bool_t GetRawFrameBuffer(RawFrameBufferInfo* Info)
{
	HDC DC = GetDC(NULL);
	memset(Info,0,sizeof(RawFrameBufferInfo));

	ExtEscape(DC, GETRAWFRAMEBUFFER, 0, NULL, sizeof(RawFrameBufferInfo), (char*)Info);
	if (!Info->pFramePointer && QueryPlatform(PLATFORM_VER) >= 421)
	{
		//try gxinfo
		DWORD Code = GETGXINFO;
		if (ExtEscape(DC, ESC_QUERYESCSUPPORT, sizeof(DWORD), (char*)&Code, 0, NULL) > 0)
		{
			DWORD DCWidth = GetDeviceCaps(DC,HORZRES);
			DWORD DCHeight = GetDeviceCaps(DC,VERTRES);
			GXDeviceInfo GXInfo;
			memset(&GXInfo,0,sizeof(GXInfo));
			GXInfo.Version = 100;
			ExtEscape(DC, GETGXINFO, 0, NULL, sizeof(GXInfo), (char*)&GXInfo);

			// avoid VGA devices (or QVGA smartphones emulating 176x220)
			if (GXInfo.cbStride>0 && !(GXInfo.ffFormat & kfLandscape) &&
				((DCWidth == GXInfo.cxWidth && DCHeight == GXInfo.cyHeight) ||
				 (DCWidth == GXInfo.cyHeight && DCHeight == GXInfo.cxWidth)))
			{
				bool_t Detect = 0;
				TRY_BEGIN
				{
					int* p = (int*)GXInfo.pvFrameBuffer;
					COLORREF Old = GetPixel(DC,0,0);
					*p ^= -1;
					Detect = GetPixel(DC,0,0) != Old;
					*p ^= -1;
				}
				TRY_END

				if (Detect)
				{
					Info->pFramePointer = GXInfo.pvFrameBuffer;
					Info->cxPixels = GXInfo.cxWidth;
					Info->cyPixels = GXInfo.cyHeight;
					Info->cxStride = GXInfo.cBPP/8;
					Info->cyStride = GXInfo.cbStride;
					Info->wBPP = (WORD)GXInfo.cBPP;
					Info->wFormat = (WORD)GXInfo.ffFormat;
				}
			}
		}
	}

	ReleaseDC(NULL,DC);
	return Info->pFramePointer != NULL;
}

static int Enum(raw* p, int* No, datadef* Param)
{
	if (OverlayEnum(&p->Overlay,No,Param)==ERR_NONE)
		return ERR_NONE;
	return NodeEnumTable(No,Param,Params);
}

static int Get(raw* p,int No,void* Data,int Size)
{
	int Result = OverlayGet(&p->Overlay,No,Data,Size);
	switch (No)
	{
	case RAW_WIDTH: GETVALUE(p->Info.cxPixels,int); break;
	case RAW_HEIGHT: GETVALUE(p->Info.cyPixels,int); break;
	case RAW_PITCHX: GETVALUE(p->Info.cxStride,int); break;
	case RAW_PITCHY: GETVALUE(p->Info.cyStride,int); break;
	case RAW_BPP: GETVALUE(p->Info.wBPP,int); break;
	case RAW_FORMAT: GETVALUE(p->Info.wFormat,int); break;
	case RAW_POINTER: GETVALUE((int)p->Info.pFramePointer,int); break;
	}
	return Result;
}

static int Init(raw* p)
{
	RawFrameBufferInfo Info;

	if (!GetRawFrameBuffer(&p->Info))
		return ERR_DEVICE_ERROR;

	memcpy(&Info,&p->Info,sizeof(Info));

	if (abs(Info.cyStride) < abs(Info.cxStride))
	{
		if (abs(Info.cxStride)*8 < Info.cyPixels*Info.wBPP &&
			abs(Info.cxStride)*8 >= Info.cxPixels*Info.wBPP) //swapped resolution
			SwapInt(&Info.cxPixels,&Info.cyPixels);
	}
	else
	{
		if (abs(Info.cyStride)*8 < Info.cxPixels*Info.wBPP &&
			abs(Info.cyStride)*8 >= Info.cyPixels*Info.wBPP) //swapped resolution
			SwapInt(&Info.cxPixels,&Info.cyPixels);
	}

	memset(&p->Overlay.Output.Format.Video,0,sizeof(video));
	p->Overlay.Output.Format.Video.Width = Info.cxPixels;
	p->Overlay.Output.Format.Video.Height = Info.cyPixels;
	p->Overlay.Output.Format.Video.Direction = 0;
	p->Overlay.Output.Format.Video.Aspect = ASPECT_ONE;

	switch (Info.wFormat)
	{
	case kfDirect555:
	case kfDirect|kfDirect555:
	case kfDirect|kfDirect555|kfLandscape:
	case FORMAT_555:
		DefaultRGB(&p->Overlay.Output.Format.Video.Pixel,Info.wBPP,5,5,5,0,0,0);
		break;
	case kfDirect565:
	case kfDirect|kfDirect565:
	case kfDirect|kfDirect565|kfLandscape:
	case FORMAT_565:
		DefaultRGB(&p->Overlay.Output.Format.Video.Pixel,Info.wBPP,5,6,5,0,0,0);
		break;
	default:
		return ERR_DEVICE_ERROR;
	}

	// we need the physical start of the framebuffer
	if (Info.cxStride<0) 
		Info.pFramePointer += (Info.cxStride * (Info.cxPixels-1));
	if (Info.cyStride<0) 
		Info.pFramePointer += (Info.cyStride * (Info.cyPixels-1));

	if (abs(Info.cyStride) < abs(Info.cxStride))
	{
		p->Overlay.Output.Format.Video.Direction |= DIR_SWAPXY;
		p->Overlay.Output.Format.Video.Pitch = abs(Info.cxStride);
		SwapInt(&p->Overlay.Output.Format.Video.Width,&p->Overlay.Output.Format.Video.Height);

		if (Info.cxStride<0) 
			p->Overlay.Output.Format.Video.Direction |= DIR_MIRRORUPDOWN;
		if (Info.cyStride<0) 
			p->Overlay.Output.Format.Video.Direction |= DIR_MIRRORLEFTRIGHT;
	}
	else
	{
		p->Overlay.Output.Format.Video.Pitch = abs(Info.cyStride);

		if (Info.cxStride<0) 
			p->Overlay.Output.Format.Video.Direction |= DIR_MIRRORLEFTRIGHT;
		if (Info.cyStride<0) 
			p->Overlay.Output.Format.Video.Direction |= DIR_MIRRORUPDOWN;
	}

	if (((int)Info.pFramePointer & 15)==0 && (p->Overlay.Output.Format.Video.Pitch & 15)==0)
		p->Overlay.Output.Format.Video.Pixel.Flags |= PF_16ALIGNED;

	p->Ptr = Info.pFramePointer;

	if (p->Overlay.Output.Format.Video.Direction & DIR_SWAPXY)
		p->Overlay.SetFX |= BLITFX_VMEMROTATED;
	p->Overlay.SetFX = BLITFX_AVOIDTEARING;
	AdjustOrientation(&p->Overlay.Output.Format.Video,1);
	return ERR_NONE;
}

static void Done(raw* p)
{
}

static int Reset(raw* p)
{
	Done(p);
	Init(p);
	return ERR_NONE;
}

static int Lock(raw* p, planes Planes, bool_t OnlyAligned)
{
	Planes[0] = p->Ptr;
	return ERR_NONE;
}

static int Unlock(raw* p)
{
	return ERR_NONE;
}

static int Create(raw* p)
{
	// skip when GAPI is already available (but not for QVGA smartphones)
	if (NodeEnumObject(NULL,GAPI_ID) &&  
		GetSystemMetrics(SM_CXSCREEN)*GetSystemMetrics(SM_CYSCREEN) < 320*240)
		return ERR_NOT_SUPPORTED;

	p->Overlay.Node.Enum = Enum;
	p->Overlay.Node.Get = Get;
	p->Overlay.Init = Init;
	p->Overlay.Done = Done;
	p->Overlay.Reset = Reset;
	p->Overlay.Lock = Lock;
	p->Overlay.Unlock = Unlock;
	if (Init(p) != ERR_NONE) // check if supported
		return ERR_NOT_SUPPORTED;
	Done(p);
	return ERR_NONE;
}

static const nodedef RAW =
{
	sizeof(raw)|CF_GLOBAL, //no setup
	RAW_ID,
	OVERLAY_CLASS,
	PRI_DEFAULT+95,
	(nodecreate)Create,
};

void OverlayRAW_Init() 
{ 
	NodeRegisterClass(&RAW); 
}

void OverlayRAW_Done()
{
	NodeUnRegisterClass(RAW_ID);
}

#endif

⌨️ 快捷键说明

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