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

📄 overlay_gdi.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_gdi.c 543 2006-01-07 22:06:24Z picard $
 *
 * The Core Pocket Media Player
 * Copyright (c) 2004-2005 Gabor Kovacs
 *
 ****************************************************************************/

#include "../common.h"

#ifdef _WIN32

//#define BLITTEST

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

typedef struct gdi
{
	overlay p;
	int DIBSection;
	HBITMAP Bitmap;
	HGDIOBJ Bitmap0; //bitmap returned by selectobject
	HDC DC2;
	video Overlay;
	rect OverlayRect;
	planes Planes;

#ifdef BLITTEST
	void* Soft2;
	planes Planes2;
#endif

} gdi;

static int AllocBitmap(gdi* p)
{
#ifndef BLITTEST
	int OldFlags = p->Overlay.Pixel.Flags;
#endif
	p->p.Dirty = 1;

	if (p->DIBSection)
	{
		int i;
		struct 
		{
			BITMAPINFOHEADER Head;
			int BitMask[3];
		} Info;
		HDC DC = GetDC(NULL);

		memset(&Info,0,sizeof(Info));
		Info.Head.biSize = sizeof(Info.Head);
		Info.Head.biWidth = p->Overlay.Width;
		Info.Head.biHeight = -p->Overlay.Height;
		Info.Head.biPlanes = 1;
		Info.Head.biBitCount = (WORD)p->Overlay.Pixel.BitCount;
		Info.Head.biCompression = (p->Overlay.Pixel.BitCount==16 || p->Overlay.Pixel.BitCount==32) ? BI_BITFIELDS:BI_RGB;
		Info.Head.biSizeImage = (p->Overlay.Width * p->Overlay.Height * p->Overlay.Pixel.BitCount) >> 3;
		for (i=0;i<3;++i)
			Info.BitMask[i] = p->Overlay.Pixel.BitMask[i];

		p->Bitmap = CreateDIBSection(DC,(BITMAPINFO*)&Info,DIB_RGB_COLORS,&p->Planes[0],NULL,0);

		if (p->Bitmap)
			p->Bitmap0 = SelectObject(p->DC2,p->Bitmap);

		ReleaseDC(NULL,DC);
	}
	else
		p->Planes[0] = Alloc16(p->Overlay.Pitch * p->Overlay.Height);

	if (((uintptr_t)p->Planes[0] & 15) || (p->Overlay.Pitch & 15))
		p->Overlay.Pixel.Flags &= ~PF_16ALIGNED;
	else
		p->Overlay.Pixel.Flags |= PF_16ALIGNED;

#ifndef BLITTEST
	if (OldFlags != p->Overlay.Pixel.Flags)
	{
		BlitRelease(p->p.Soft);
		p->p.Soft = BlitCreate(&p->Overlay,&p->p.Input.Format.Video,&p->p.FX,&p->p.Caps);
		BlitAlign(p->p.Soft, &p->OverlayRect, &p->p.SrcAlignedRect);
	}
#endif

	return p->Planes[0] != NULL;
}

static void FreeBitmap(gdi* p)
{
	if (p->Bitmap) 
	{ 
		SelectObject(p->DC2,p->Bitmap0);
		DeleteObject(p->Bitmap); 
		p->Bitmap = 0;
	}

	if (p->Planes[0])
	{
		if (!p->DIBSection)
			Free16(p->Planes[0]);

		p->Planes[0] = NULL;
	}
}

static void Done(gdi* p)
{
	FreeBitmap(p);

	if (p->DC2) 
	{
		DeleteDC(p->DC2); 
		p->DC2 = 0;
	}

#ifdef BLITTEST
	SurfaceFree(p->Planes2);
	BlitRelease(p->Soft2);
	p->Soft2 = NULL;
#endif
}

static int Init(gdi* p)
{
	HDC DC;
	QueryDesktop(&p->p.Output.Format.Video);

	p->Planes[0] = NULL;

	p->Overlay.Width = 0;
	p->Overlay.Height = 0;
	p->Overlay.Direction = 0;
	p->Overlay.Aspect = ASPECT_ONE;
	p->Overlay.Pixel = p->p.Output.Format.Video.Pixel;
	if (p->Overlay.Pixel.BitCount==24) 
		DefaultRGB(&p->Overlay.Pixel,24,8,8,8,0,0,0); //BI_BITFIELDS not supported for 24bpp
	p->Overlay.Pixel.Flags |= PF_16ALIGNED; // assume it will be aligned

	p->DIBSection = (p->Overlay.Pixel.Flags & PF_RGB) != 0;
	p->Bitmap = 0;
	p->Bitmap0 = 0;

	DC = GetDC(NULL);
	p->DC2 = CreateCompatibleDC(DC);
	ReleaseDC(NULL,DC);

	p->p.ClearFX = BLITFX_ONLYDIFF;
	return ERR_NONE;
}

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

static int Update(gdi* p)
{
	rect OldGUI = p->p.GUIAlignedRect;
	rect Old = p->p.DstAlignedRect;

	int OldWidth = p->Overlay.Width;
	int OldHeight = p->Overlay.Height;

	VirtToPhy(&p->p.Viewport,&p->p.DstAlignedRect,&p->p.Output.Format.Video);
	VirtToPhy(NULL,&p->p.SrcAlignedRect,&p->p.Input.Format.Video);

	AnyAlign(&p->p.DstAlignedRect, &p->p.SrcAlignedRect, &p->p.FX, 2, 2, 1, SCALE_ONE*1024 ); 

	PhyToVirt(&p->p.DstAlignedRect,&p->p.GUIAlignedRect,&p->p.Output.Format.Video);

	p->Overlay.Width = ALIGN16(p->p.GUIAlignedRect.Width); // we need PF_16ALIGNED for pitch
	p->Overlay.Height = p->p.GUIAlignedRect.Height;
	p->Overlay.Pitch = (p->Overlay.Width * p->Overlay.Pixel.BitCount) >> 3;
	p->Overlay.Pitch = (p->Overlay.Pitch+1) & ~1; //word aligned (it doesn't mater anymore, Width is aligned)

	p->OverlayRect.x = p->OverlayRect.y = 0;
	p->OverlayRect.Width = p->p.GUIAlignedRect.Width;
	p->OverlayRect.Height = p->p.GUIAlignedRect.Height;

#ifdef BLITTEST
	{
		rect TestAlignedRect = p->OverlayRect;
		packetformat TestFormat = {0};
		TestFormat.Type = PACKET_VIDEO;
		TestFormat.Format.Video = p->Overlay;
		TestFormat.Format.Video.Pixel.Flags &= (PF_PALETTE|PF_RGB);
		//TestFormat.Format.Video.Pixel.Flags |= PF_FOURCC;
		//TestFormat.Format.Video.Pixel.FourCC = FOURCC_Y422;
		//PacketFormatDefault(&TestFormat);
		DefaultRGB(&TestFormat.Format.Video.Pixel,32,8,8,8,0,0,0);
		DefaultPitch(&TestFormat.Format.Video);

		SurfaceFree(p->Planes2);
		SurfaceAlloc(p->Planes2,&TestFormat.Format.Video);

		BlitRelease(p->Soft2);
		p->Soft2 = BlitCreate(&TestFormat.Format.Video,&p->p.Input.Format.Video,&p->p.FX,&p->p.Caps);
		BlitAlign(p->Soft2,&TestAlignedRect, &p->p.SrcAlignedRect);

		BlitRelease(p->p.Soft);
		p->p.Soft = BlitCreate(&p->Overlay,&TestFormat.Format.Video,NULL,NULL);
		BlitAlign(p->p.Soft,&p->OverlayRect, &TestAlignedRect);
	}
#else
	BlitRelease(p->p.Soft);
	p->p.Soft = BlitCreate(&p->Overlay,&p->p.Input.Format.Video,&p->p.FX,&p->p.Caps);
	BlitAlign(p->p.Soft, &p->OverlayRect, &p->p.SrcAlignedRect);
#endif

	p->p.GUIAlignedRect.x += p->OverlayRect.x;
	p->p.GUIAlignedRect.y += p->OverlayRect.y;
	p->p.GUIAlignedRect.Width = p->OverlayRect.Width;
	p->p.GUIAlignedRect.Height = p->OverlayRect.Height;

	VirtToPhy(&p->p.GUIAlignedRect,&p->p.DstAlignedRect,&p->p.Output.Format.Video);

	if (OldWidth != p->Overlay.Width || OldHeight != p->Overlay.Height)
		FreeBitmap(p);

	if (p->p.Show && !EqRect(&Old,&p->p.DstAlignedRect))
	{
		WinInvalidate(&OldGUI,0);
		WinInvalidate(&p->p.Viewport,1);
		WinValidate(&p->p.GUIAlignedRect);
	}
	return ERR_NONE;
}

static int Blit(gdi* p, const constplanes Data, const constplanes DataLast )
{
	HDC DC;

	if (!p->Planes[0] && !AllocBitmap(p))
		return ERR_OUT_OF_MEMORY;

#ifdef BLITTEST
	BlitImage(p->Soft2,p->Planes2,Data,DataLast,-1,-1);
	BlitImage(p->p.Soft,p->Planes,p->Planes2,NULL,-1,-1);
#else
	BlitImage(p->p.Soft,p->Planes,Data,DataLast,-1,-1);
#endif

	if (!p->DIBSection)
	{
		if (p->Bitmap)
		{
			SelectObject(p->DC2,p->Bitmap0);
			DeleteObject(p->Bitmap);
		}

		p->Bitmap = CreateBitmap( p->Overlay.Width, p->Overlay.Height, 1, 
			p->Overlay.Pixel.BitCount, (char*)p->Planes[0]);

		if (!p->Bitmap)
			return ERR_OUT_OF_MEMORY;

		p->Bitmap0 = SelectObject(p->DC2,p->Bitmap);
	}

	DC = GetDC(NULL);
	BitBlt(DC,p->p.GUIAlignedRect.x,p->p.GUIAlignedRect.y,
		   p->OverlayRect.Width,p->OverlayRect.Height,p->DC2,p->OverlayRect.x,p->OverlayRect.y,SRCCOPY);
	ReleaseDC(NULL,DC);

	return ERR_NONE;
}

static int Create(gdi* p)
{
	p->p.Init = Init;
	p->p.Done = Done;
	p->p.Blit = Blit;
	p->p.Update = Update;
	p->p.Reset = Reset;
	return ERR_NONE;
}

static const nodedef GDI = 
{
	sizeof(gdi)|CF_GLOBAL,
	GDI_ID,
	OVERLAY_CLASS,
	PRI_DEFAULT,
	(nodecreate)Create,
};

void OverlayGDI_Init() 
{ 
	NodeRegisterClass(&GDI);
}

void OverlayGDI_Done() 
{ 
	NodeUnRegisterClass(GDI_ID);
}

#endif

⌨️ 快捷键说明

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