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

📄 overlay_ddrawce.c

📁 大名鼎鼎的CE下播放软件,TCPPMP的源代码!!!2410下可以流畅的解QVGA的H264,MPEG4等格式.
💻 C
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************
 *
 * 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_ddrawce.c 615 2006-01-26 16:57:51Z picard $
 *
 * The Core Pocket Media Player
 * Copyright (c) 2004-2005 Gabor Kovacs
 *
 ****************************************************************************/

#include "../common.h"

#ifdef _WIN32

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

#if _MSC_VER > 1000
#pragma warning( push, 3 )
#endif

#include "ddrawce.h"
#include "overlay_ddraw.h"

static int AdjustDesc( DDSURFACEDESC* Desc )
{
	int Dir = 0;

	if (abs(Desc->lPitch) < abs(Desc->lXPitch))
	{
		DWORD Tmp;
		
		Tmp = Desc->dwWidth;
		Desc->dwWidth = Desc->dwHeight;
		Desc->dwHeight = Tmp;

		Tmp = Desc->lPitch;
		Desc->lPitch = Desc->lXPitch;
		Desc->lXPitch = Tmp;

		Dir |= DIR_SWAPXY;
	}

	if (Desc->lXPitch < 0)
	{
		Dir |= DIR_MIRRORLEFTRIGHT;
		Desc->lpSurface = (char*)Desc->lpSurface + Desc->lXPitch * (Desc->dwWidth-1);
		Desc->lXPitch = -Desc->lXPitch;
	}
	if (Desc->lPitch < 0)
	{
		Dir |= DIR_MIRRORUPDOWN;
		Desc->lpSurface = (char*)Desc->lpSurface + Desc->lPitch * (Desc->dwHeight-1);
		Desc->lPitch = -Desc->lPitch;
	}

	return Dir;
}

static void Desc2Surface( DDSURFACEDESC* Desc, video* p )
{
	memset(p,0,sizeof(video));
	p->Direction = AdjustDesc(Desc);
	p->Aspect = ASPECT_ONE;
	p->Width = Desc->dwWidth;
	p->Height = Desc->dwHeight;

	if (Desc->ddpfPixelFormat.dwFlags & DDPF_FOURCC)
	{
		p->Pixel.Flags = PF_FOURCC;
		p->Pixel.FourCC = Desc->ddpfPixelFormat.dwFourCC;
	}
	else
	if (Desc->ddpfPixelFormat.dwFlags & DDPF_RGB)
	{
		p->Pixel.Flags = PF_RGB;
		p->Pixel.BitCount = Desc->ddpfPixelFormat.dwRGBBitCount;
		p->Pixel.BitMask[0] = Desc->ddpfPixelFormat.dwRBitMask;
		p->Pixel.BitMask[1] = Desc->ddpfPixelFormat.dwGBitMask;
		p->Pixel.BitMask[2] = Desc->ddpfPixelFormat.dwBBitMask;
	}
	else
	if (Desc->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED)
	{
		p->Pixel.Flags = PF_PALETTE;
		p->Pixel.BitCount = 8;
	}
}

static bool_t Surface2Desc( const video* p, DDSURFACEDESC* Desc, bool_t PixelFormat )
{
	memset(Desc,0,sizeof(DDSURFACEDESC));
	Desc->dwSize = sizeof(DDSURFACEDESC);
	Desc->dwFlags = DDSD_WIDTH | DDSD_HEIGHT;

	Desc->dwWidth = p->Width;
	Desc->dwHeight = p->Height;

	if (PixelFormat)
	{
		Desc->dwFlags |= DDSD_PIXELFORMAT;
		Desc->ddpfPixelFormat.dwSize = sizeof(Desc->ddpfPixelFormat);

		if (p->Pixel.Flags & PF_FOURCC)
		{
			Desc->ddpfPixelFormat.dwFlags = DDPF_FOURCC;
			Desc->ddpfPixelFormat.dwFourCC = p->Pixel.FourCC;
		}
		else
		if (p->Pixel.Flags & PF_RGB)
		{
			Desc->ddpfPixelFormat.dwFlags = DDPF_RGB;
			Desc->ddpfPixelFormat.dwRGBBitCount = p->Pixel.BitCount;
			Desc->ddpfPixelFormat.dwRBitMask = p->Pixel.BitMask[0];
			Desc->ddpfPixelFormat.dwGBitMask = p->Pixel.BitMask[1];
			Desc->ddpfPixelFormat.dwBBitMask = p->Pixel.BitMask[2];
		}
		else
		if (p->Pixel.Flags & PF_PALETTE && p->Pixel.BitCount==8)
		{
			Desc->ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED;
			Desc->ddpfPixelFormat.dwRGBBitCount = p->Pixel.BitCount;
		}
		else
			return 0;
	}

	return 1;
}

static bool_t ClearBuffer(ddraw* p,LPDIRECTDRAWSURFACE Buffer)
{
	bool_t Result = 0;
	DDSURFACEDESC Desc;
	Desc.dwSize = sizeof(Desc);

	TRY_BEGIN
	if (IDirectDrawSurface_Lock(p->DDBuffer,NULL,&Desc,DDLOCK_WAITNOTBUSY,NULL) == DD_OK)
	{
		int v,x2,y2,pitch2;

		AdjustDesc(&Desc);
		FillInfo(&p->Overlay.Pixel);
		v = RGBToFormat(CRGB(0,0,0),&p->Overlay.Pixel);

		TRY_BEGIN
		if (PlanarYUV(&p->Overlay.Pixel,&x2,&y2,&pitch2) && p->Overlay.Pixel.BitCount==8)
		{
			uint8_t* i = (uint8_t*)Desc.lpSurface;
			FillColor(i,Desc.lPitch,0,0,p->Overlay.Width,p->Overlay.Height,8,v & 255);
			i += Desc.lPitch * p->Overlay.Height;
			FillColor(i,Desc.lPitch >> pitch2,0,0,p->Overlay.Width >> x2,p->Overlay.Height >> y2,8,(v>>8)&255);
			i += (Desc.lPitch >> x2) * (p->Overlay.Height >> y2);
			FillColor(i,Desc.lPitch >> pitch2,0,0,p->Overlay.Width >> x2,p->Overlay.Height >> y2,8,(v>>16)&255);
		}
		else
		if (PackedYUV(&p->Overlay.Pixel) && p->Overlay.Pixel.BitCount==16)
			FillColor(Desc.lpSurface,Desc.lPitch,0,0,p->Overlay.Width >> 1,p->Overlay.Height,32,v);
		else
			FillColor(Desc.lpSurface,Desc.lPitch,0,0,p->Overlay.Width,p->Overlay.Height,p->Overlay.Pixel.BitCount,v);
		Result = 1;
		TRY_END

		IDirectDrawSurface_Unlock(p->DDBuffer,NULL);
	}
	TRY_END
	return Result;
}

static HRESULT PASCAL EnumBackBuffer(LPDIRECTDRAWSURFACE p, LPDDSURFACEDESC Desc, LPVOID Context)
{
    if (*((LPDIRECTDRAWSURFACE *)Context)) 
	{
		IDirectDrawSurface_Release(p);
		return DDENUMRET_CANCEL;
	}
	*((LPDIRECTDRAWSURFACE *)Context) = p;
	return DDENUMRET_OK;
}

static void ReleaseBuffers(ddraw* p)
{
	if (p->DDBackBuffer) 
	{ 
		IDirectDrawSurface_Release(p->DDBackBuffer); 
		p->DDBackBuffer = NULL;
	}

	if (p->DDBuffer) 
	{ 
		if (p->Mode == MODE_OVERLAY)
			IDirectDrawSurface_UpdateOverlay(p->DDBuffer,NULL,p->DDPrimary,NULL,DDOVER_HIDE,NULL);
		IDirectDrawSurface_Release(p->DDBuffer); 
		p->DDBuffer = NULL;
	}
}

static bool_t CreateBuffer(ddraw* p,bool_t PixelFormat)
{
	DDSURFACEDESC Desc;

	p->BufferPixelFormat = PixelFormat;

	ReleaseBuffers(p);

	if (!Surface2Desc(&p->Overlay,&Desc,PixelFormat))
		return 0;

	Desc.dwFlags |= DDSD_CAPS;
	Desc.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY;
	if (p->Mode == MODE_OVERLAY)
	{
		Desc.ddsCaps.dwCaps |= DDSCAPS_OVERLAY;
		Desc.ddsCaps.dwCaps |= DDSCAPS_FLIP;
		Desc.dwFlags |= DDSD_BACKBUFFERCOUNT;
		Desc.dwBackBufferCount = 1;
	}

	DEBUG_MSG5(DEBUG_VIDEO,T("DDRAW CreateSurface %08x %dx%d %08x %08x"),Desc.ddsCaps.dwCaps,Desc.dwWidth,Desc.dwHeight,Desc.ddpfPixelFormat.dwFlags,Desc.ddpfPixelFormat.dwFourCC);

	if (IDirectDraw_CreateSurface(p->DD,&Desc,&p->DDBuffer,NULL) != DD_OK)
	{
		if (p->Mode == MODE_OVERLAY)
		{
			// try without backbuffer...
			Desc.ddsCaps.dwCaps &= ~(DDSCAPS_FLIP);
			Desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
			IDirectDraw_CreateSurface(p->DD,&Desc,&p->DDBuffer,NULL);
		}

		if (!p->DDBuffer)
		{
			DEBUG_MSG(DEBUG_VIDEO,T("DDRAW CreateSurface Failed"));
			return 0;
		}
	}
	else
	if (p->Mode == MODE_OVERLAY)
		IDirectDrawSurface_EnumAttachedSurfaces(p->DDBuffer,&p->DDBackBuffer,EnumBackBuffer);

	if (IDirectDrawSurface_GetSurfaceDesc(p->DDBuffer,&Desc) == DD_OK)
		Desc2Surface(&Desc,&p->Overlay);

	DEBUG_MSG(DEBUG_VIDEO,T("DDRAW CreateSurface Ok"));

	if (!ClearBuffer(p,p->DDBuffer))
	{
		ReleaseBuffers(p);
		return 0;
	}

	if (p->DDBackBuffer)
		ClearBuffer(p,p->DDBackBuffer);

	return 1;
}

static int UpdateOverlay(ddraw* p)
{
	rect OverlayRect;
	rect DstAlignedRect;

	DstAlignedRect = p->p.GUIAlignedRect;
	PhyToVirt(&p->OverlayRect,&OverlayRect,&p->Overlay);

	p->Src.left = OverlayRect.x;
	p->Src.top = OverlayRect.y;
	p->Src.right = OverlayRect.x + OverlayRect.Width;
	p->Src.bottom = OverlayRect.y + OverlayRect.Height;
 
	p->Dst.left = DstAlignedRect.x;
	p->Dst.top = DstAlignedRect.y;
	p->Dst.right = DstAlignedRect.x + DstAlignedRect.Width;
	p->Dst.bottom = DstAlignedRect.y + DstAlignedRect.Height;

	if (p->Mode == MODE_OVERLAY && p->DDBuffer &&
		OverlayRect.Width>0 && OverlayRect.Height>0 &&
		DstAlignedRect.Width>0 && DstAlignedRect.Height>0)
	{
		DWORD hResult;
		int Flags = 0;

		if (p->p.Show)
			Flags |= DDOVER_SHOW;
		else
			Flags |= DDOVER_HIDE;

		if (p->p.ColorKey != RGB_NULL)
			Flags |= DDOVER_KEYDEST;

		hResult = IDirectDrawSurface_UpdateOverlay(p->DDBuffer,&p->Src,p->DDPrimary,&p->Dst,Flags,NULL);
		if (hResult != DD_OK)
		{
			DEBUG_MSG1(DEBUG_VIDEO,T("DDRAW UpdateOverlay failed %08x"),hResult);
		}
	}

	return ERR_NONE;
}

static int GetAlign(int i)
{
	int v=1;
	while (v<16 && v<i)
		v<<=1;

⌨️ 快捷键说明

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