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

📄 vo_directx.c

📁 DawnLightPlayer,一个新的基于ffmpeg的全功能播放器
💻 C
📖 第 1 页 / 共 3 页
字号:
/********************************************** * Dawn Light Player *  *   vo_directx.c * * Created by kf701 * 14:51:05 03/22/08 CST * * $Id$ **********************************************/#if ENABLE_VO_DIRECTX#include <windows.h>#include <windowsx.h>#include <ddraw.h>#include "swscale.h"#include "avoutput.h"#include "avdecode.h"#include "avinput.h"#include "cmdutils.h"#include "global.h"#define WNDCLASSNAME_WINDOWED	"Dawn Light Player"#define WNDCLASSNAME_FULLSCREEN	"Fullscreen"#define WNDSTYLE WS_OVERLAPPEDWINDOW | WS_SIZEBOXstatic LPDIRECTDRAWCOLORCONTROL	g_cc = NULL;		static LPDIRECTDRAW7        g_lpdd = NULL;          static LPDIRECTDRAWSURFACE7  g_lpddsPrimary = NULL; static LPDIRECTDRAWSURFACE7  g_lpddsOverlay = NULL; static LPDIRECTDRAWSURFACE7  g_lpddsBack = NULL;    static LPDIRECTDRAWCLIPPER  g_lpddclipper;          static DDSURFACEDESC2		ddsdsf;                 static HINSTANCE            hddraw_dll;             static RECT                 rd;                     static RECT                 rs;                     static HWND                 hWnd=NULL;              static HWND                 hWndFS=NULL;           static HBRUSH               colorbrush = NULL;      static HBRUSH               blackbrush = NULL;      static HICON                mplayericon = NULL;     static HCURSOR              mplayercursor = NULL; static uint32_t image_width, image_height;       static uint32_t d_image_width, d_image_height;   static uint8_t  *image=NULL;                     static void* tmp_image = NULL;static uint32_t image_format=0;                  static uint32_t primary_image_format;static uint32_t vm_height=0;static uint32_t vm_width=0;static uint32_t vm_bpp=0;static uint32_t dstride;                         static uint32_t nooverlay = 0;                   static int vo_dx, vo_dy;static char *vo_title = "Dawn Light Player";static int vo_fs = 0;static int vo_doublebuffering = 0;static int vo_adapter_num = 0;static DWORD    destcolorkey;              static COLORREF windowcolor = RGB(0,0,16); static int adapter_count=0;static GUID selected_guid;static GUID *selected_guid_ptr = NULL;static RECT monitor_rect;	               static float window_aspect;static BOOL (WINAPI* myGetMonitorInfo)(HMONITOR, LPMONITORINFO) = NULL;static RECT last_rect = {0xDEADC0DE, 0xDEADC0DE, 0xDEADC0DE, 0xDEADC0DE};/***************************************************************************** * DirectDraw GUIDs. * Defining them here allows us to get rid of the dxguid library during * the linking stage. *****************************************************************************/const GUID IID_IDirectDraw7 ={	0x15e65ec0,0x3b9c,0x11d2,{0xb9,0x2f,0x00,0x60,0x97,0x97,0xea,0x5b}};const GUID IID_IDirectDrawColorControl ={	0x4b9f0ee0,0x0d7e,0x11d0,{0x9b,0x06,0x00,0xa0,0xc9,0x03,0xa3,0xb8}};typedef struct directx_fourcc_caps{	char*  img_format_name;      //human readable name	uint32_t img_format;         //as MPlayer image format	DDPIXELFORMAT g_ddpfOverlay; //as Directx Sourface description} directx_fourcc_caps;static directx_fourcc_caps g_ddpf[] ={	{"BGR8 ",PIX_FMT_BGR8,{sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 8,  0x00000000, 0x00000000, 0x00000000, 0}},	{"RGB15",PIX_FMT_RGB555,{sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16,  0x0000001F, 0x000003E0, 0x00007C00, 0}},	{"BGR15",PIX_FMT_BGR555,{sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16,  0x00007C00, 0x000003E0, 0x0000001F, 0}},	{"RGB16",PIX_FMT_RGB565,{sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16,  0x0000001F, 0x000007E0, 0x0000F800, 0}},	{"BGR16",PIX_FMT_BGR565,{sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16,  0x0000F800, 0x000007E0, 0x0000001F, 0}},	{"RGB24",PIX_FMT_RGB24,{sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 24,  0x000000FF, 0x0000FF00, 0x00FF0000, 0}},	{"BGR24",PIX_FMT_BGR24,{sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 24,  0x00FF0000, 0x0000FF00, 0x000000FF, 0}},	{"RGB32",PIX_FMT_RGB32,{sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 32,  0x000000FF, 0x0000FF00, 0x00FF0000, 0}},	{"BGR32",PIX_FMT_BGR32,{sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 32,  0x00FF0000, 0x0000FF00, 0x000000FF, 0}}};#define NUM_FORMATS (sizeof(g_ddpf) / sizeof(g_ddpf[0]))static uint32_t Directx_CreatePrimarySurface(){	DDSURFACEDESC2   ddsd;	if( g_lpddsPrimary )		g_lpddsPrimary->lpVtbl->Release( g_lpddsPrimary );	g_lpddsPrimary=NULL;	ZeroMemory(&ddsd, sizeof(ddsd));	ddsd.dwSize = sizeof(ddsd);	ddsd.dwFlags = DDSD_CAPS;	ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;	if (g_lpdd->lpVtbl->CreateSurface(g_lpdd,&ddsd, &g_lpddsPrimary, NULL ) == DD_OK)		av_log(NULL, AV_LOG_INFO, "vo_directx: primary surface created\n");	else	{		av_log(NULL, AV_LOG_ERROR, "vo_directx: could not create primary surface\n");		return -1;	}	return 0;}static uint32_t Directx_CreateOverlay(uint32_t imgfmt){	HRESULT ddrval;	DDSURFACEDESC2   ddsdOverlay;	uint32_t        i=0;	while ( i < NUM_FORMATS +1 && imgfmt != g_ddpf[i].img_format )		i++;	if ( !g_lpdd || !g_lpddsPrimary )		return -1;	if ( g_lpddsOverlay )		g_lpddsOverlay->lpVtbl->Release( g_lpddsOverlay );	if ( g_lpddsBack )		g_lpddsBack->lpVtbl->Release( g_lpddsBack );	g_lpddsOverlay = NULL;	g_lpddsBack = NULL;	/* create our overlay */	ZeroMemory(&ddsdOverlay, sizeof(ddsdOverlay));	ddsdOverlay.dwSize = sizeof(ddsdOverlay);	ddsdOverlay.ddsCaps.dwCaps = DDSCAPS_OVERLAY | DDSCAPS_FLIP |		DDSCAPS_COMPLEX | DDSCAPS_VIDEOMEMORY;	ddsdOverlay.dwFlags = DDSD_CAPS|DDSD_HEIGHT | DDSD_WIDTH |		DDSD_BACKBUFFERCOUNT | DDSD_PIXELFORMAT;	ddsdOverlay.dwWidth = image_width;	ddsdOverlay.dwHeight = image_height;	ddsdOverlay.dwBackBufferCount = 2;	ddsdOverlay.ddpfPixelFormat = g_ddpf[i].g_ddpfOverlay;	if ( vo_doublebuffering )	{		if (g_lpdd->lpVtbl->CreateSurface(g_lpdd,&ddsdOverlay, &g_lpddsOverlay, NULL)== DD_OK)		{			av_log(NULL, AV_LOG_INFO, "vo_directx: overlay with format %s created\n",g_ddpf[i].img_format_name);			/* get the surface directly attached to the primary (the back buffer) */			ddsdOverlay.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;			if (g_lpddsOverlay->lpVtbl->GetAttachedSurface(g_lpddsOverlay,&ddsdOverlay.ddsCaps, &g_lpddsBack) != DD_OK)			{				av_log(NULL, AV_LOG_ERROR, "vo_directx: can't get attached surface\n");				return -1;			}			return 0;		}		vo_doublebuffering=0; /* disable tribblebuffering */		av_log(NULL, AV_LOG_INFO, "vo_directx: cannot create tribblebuffer overlay with format %s\n",g_ddpf[i].img_format_name);	}	/* single buffer */	av_log(NULL, AV_LOG_INFO, "vo_directx: using singlebuffer overlay\n");	ddsdOverlay.dwBackBufferCount=0;	ddsdOverlay.ddsCaps.dwCaps=DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY;	ddsdOverlay.dwFlags= DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT;	ddsdOverlay.ddpfPixelFormat=g_ddpf[i].g_ddpfOverlay;	/* try to create the overlay surface */	ddrval = g_lpdd->lpVtbl->CreateSurface(g_lpdd,&ddsdOverlay, &g_lpddsOverlay, NULL);	if( ddrval != DD_OK )	{		if( ddrval == DDERR_INVALIDPIXELFORMAT )			av_log(NULL, AV_LOG_ERROR, "vo_directx: invalid pixelformat: %s\n",g_ddpf[i].img_format_name);		else			av_log(NULL, AV_LOG_ERROR, "vo_directx: CreateSurface error\n");		switch (ddrval)		{			case DDERR_INCOMPATIBLEPRIMARY:				{					av_log(NULL, AV_LOG_ERROR, "incompatible primary surface\n");					break;				}			case DDERR_INVALIDCAPS:				{					av_log(NULL, AV_LOG_ERROR, "invalid caps\n");					break;				}			case DDERR_INVALIDOBJECT:				{					av_log(NULL, AV_LOG_ERROR, "invalid object\n");					break;				}			case DDERR_INVALIDPARAMS:				{					av_log(NULL, AV_LOG_ERROR, "invalid parameters\n");					break;				}			case DDERR_NODIRECTDRAWHW:				{					av_log(NULL, AV_LOG_ERROR, "no directdraw hardware\n");					break;				}			case DDERR_NOEMULATION:				{					av_log(NULL, AV_LOG_ERROR, "can't emulate\n");					break;				}			case DDERR_NOFLIPHW:				{					av_log(NULL, AV_LOG_ERROR, "hardware can't do flip\n");					break;				}			case DDERR_NOOVERLAYHW:				{					av_log(NULL, AV_LOG_ERROR, "hardware can't do overlay\n");					break;				}			case DDERR_OUTOFMEMORY:				{					av_log(NULL, AV_LOG_ERROR, "not enough system memory\n");					break;				}			case DDERR_UNSUPPORTEDMODE:				{					av_log(NULL, AV_LOG_ERROR, "unsupported mode\n");					break;				}			case DDERR_OUTOFVIDEOMEMORY:				{					av_log(NULL, AV_LOG_ERROR, "not enough video memory\n");					break;				}			default:				av_log(NULL, AV_LOG_ERROR, "create surface failed with 0x%x\n",ddrval);		}		return -1;	}	g_lpddsBack = g_lpddsOverlay;	return 0;}static uint32_t Directx_CreateBackpuffer(){	DDSURFACEDESC2   ddsd;	if( g_lpddsBack )		g_lpddsBack->lpVtbl->Release(g_lpddsBack);	g_lpddsBack=NULL;	ZeroMemory(&ddsd, sizeof(ddsd));	ddsd.dwSize = sizeof(ddsd);	ddsd.ddsCaps.dwCaps= DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;	ddsd.dwFlags= DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;	ddsd.dwWidth=image_width;	ddsd.dwHeight=image_height;	if(g_lpdd->lpVtbl->CreateSurface( g_lpdd, &ddsd, &g_lpddsBack, 0 ) != DD_OK )	{		av_log(NULL, AV_LOG_ERROR, "vo_directx: can't create backpuffer\n");		return -1;	}	av_log(NULL, AV_LOG_INFO, "vo_directx: backbuffer created\n");	return 0;}static void directx_uninit(void){	if( NULL != g_cc )		g_cc->lpVtbl->Release(g_cc);	g_cc = NULL;	if( NULL != g_lpddclipper )		g_lpddclipper->lpVtbl->Release(g_lpddclipper);	g_lpddclipper = NULL;	av_log(NULL, AV_LOG_INFO, "vo_directx: clipper released\n");	if( NULL != g_lpddsBack )		g_lpddsBack->lpVtbl->Release(g_lpddsBack);	g_lpddsBack = NULL;	av_log(NULL, AV_LOG_INFO, "vo_directx: back surface released\n");	if( vo_doublebuffering && !nooverlay )	{		if( g_lpddsOverlay != NULL )			g_lpddsOverlay->lpVtbl->Release(g_lpddsOverlay);		g_lpddsOverlay = NULL;		av_log(NULL, AV_LOG_INFO, "vo_directx: overlay surface released\n");	}	if( g_lpddsPrimary != NULL )		g_lpddsPrimary->lpVtbl->Release(g_lpddsPrimary);	g_lpddsPrimary = NULL;	av_log(NULL, AV_LOG_INFO, "vo_directx: primary released\n");	if( hWndFS )		DestroyWindow(hWndFS);	hWndFS = NULL;	if( hWnd )		DestroyWindow(hWnd);	hWnd = NULL;	av_log(NULL, AV_LOG_INFO, "vo_directx: window destroyed\n");	UnregisterClass(WNDCLASSNAME_WINDOWED, GetModuleHandle(NULL));	UnregisterClass(WNDCLASSNAME_FULLSCREEN, GetModuleHandle(NULL));	blackbrush = NULL;	colorbrush = NULL;	av_log(NULL, AV_LOG_INFO, "vo_directx: GDI resources deleted\n");	if( g_lpdd != NULL )	{		g_lpdd->lpVtbl->Release(g_lpdd);	}	FreeLibrary( hddraw_dll);	hddraw_dll= NULL;}static BOOL WINAPI EnumCallbackEx(		GUID FAR *lpGUID,		LPSTR lpDriverDescription,		LPSTR lpDriverName,		LPVOID lpContext,		HMONITOR  hm){	if( adapter_count == vo_adapter_num )	{		MONITORINFO mi;		if (!lpGUID)			selected_guid_ptr = NULL;		else		{			selected_guid = *lpGUID;			selected_guid_ptr = &selected_guid;		}		mi.cbSize = sizeof(mi);		if (myGetMonitorInfo(hm, &mi))		{			monitor_rect = mi.rcMonitor;		}	}	adapter_count++;	return 1;}static uint32_t Directx_InitDirectDraw(){	HRESULT    (WINAPI *OurDirectDrawCreateEx)(GUID *,LPVOID *, REFIID,IUnknown FAR *);	DDSURFACEDESC2 ddsd;	LPDIRECTDRAWENUMERATEEX OurDirectDrawEnumerateEx;	HINSTANCE user32dll = LoadLibrary("user32.dll");	adapter_count = 0;

⌨️ 快捷键说明

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