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

📄 vo_directx.c

📁 君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图片解码,浏览,电子书,录音,想学ucos,识货的人就下吧 russblock fmradio explore set
💻 C
📖 第 1 页 / 共 4 页
字号:
/****************************************************************************** * vo_directx.c: Directx v2 or later DirectDraw interface for MPlayer * Copyright (c) 2002 - 2005 Sascha Sommer <saschasommer@freenet.de>. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/#include <windows.h>#include <windowsx.h>#include <ddraw.h>#include <mplaylib.h>#include <mplaylib.h>#include <errno.h>#include "config.h"#include "video_out.h"#include "video_out_internal.h"#include "fastmemcpy.h"#include "input/input.h"#include "osdep/keycodes.h"#include "input/mouse.h"#include "mp_msg.h"#include "aspect.h"#include "geometry.h"#include "mp_fifo.h"#ifdef HAVE_NEW_GUI#include "gui/interface.h"#endif#ifndef WM_XBUTTONDOWN# define WM_XBUTTONDOWN    0x020B# define WM_XBUTTONUP      0x020C# define WM_XBUTTONDBLCLK  0x020D#endif#define WNDCLASSNAME_WINDOWED	"MPlayer - The Movie Player"#define WNDCLASSNAME_FULLSCREEN	"MPlayer - Fullscreen"#define WNDSTYLE WS_OVERLAPPEDWINDOW|WS_SIZEBOXstatic LPDIRECTDRAWCOLORCONTROL	g_cc = NULL;		//color control interfacestatic LPDIRECTDRAW7        g_lpdd = NULL;          //DirectDraw Objectstatic LPDIRECTDRAWSURFACE7  g_lpddsPrimary = NULL;  //Primary Surface: viewport through the Desktopstatic LPDIRECTDRAWSURFACE7  g_lpddsOverlay = NULL;  //Overlay Surfacestatic LPDIRECTDRAWSURFACE7  g_lpddsBack = NULL;     //Back surfacestatic LPDIRECTDRAWCLIPPER  g_lpddclipper;          //clipper object, can only be used without overlaystatic DDSURFACEDESC2		ddsdsf;                 //surface descripiton needed for lockingstatic HINSTANCE            hddraw_dll;             //handle to ddraw.dllstatic RECT                 rd;                     //rect of our stretched imagestatic RECT                 rs;                     //rect of our source imagestatic HWND                 hWnd=NULL;              //handle to the windowstatic HWND                 hWndFS=NULL;           //fullscreen windowstatic HBRUSH               colorbrush = NULL;      // Handle to colorkey brushstatic HBRUSH               blackbrush = NULL;      // Handle to black brushstatic HICON                mplayericon = NULL;     // Handle to mplayer iconstatic HCURSOR              mplayercursor = NULL;   // Handle to mplayer cursorstatic uint32_t image_width, image_height;          //image width and heightstatic uint32_t d_image_width, d_image_height;      //image width and height zoomed static uint8_t  *image=NULL;                        //image datastatic uint32_t image_format=0;                       //image formatstatic 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;                            //surface stridestatic uint32_t nooverlay = 0;                      //NonOverlay modestatic DWORD    destcolorkey;                       //colorkey for our surfacestatic COLORREF windowcolor = RGB(0,0,16);          //windowcolor == colorkeystatic int adapter_count=0;static GUID selected_guid;static GUID *selected_guid_ptr = NULL;static RECT monitor_rect;	                        //monitor coordinates static float window_aspect;static BOOL (WINAPI* myGetMonitorInfo)(HMONITOR, LPMONITORINFO) = NULL;static RECT last_rect = {0xDEADC0DE, 0xDEADC0DE, 0xDEADC0DE, 0xDEADC0DE};extern void vo_draw_text(int dxs,int dys,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride));extern int vidmode;/***************************************************************************** * 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   uint32_t drv_caps;           //what hw supports with this format   DDPIXELFORMAT g_ddpfOverlay; //as Directx Sourface description} directx_fourcc_caps;static directx_fourcc_caps g_ddpf[] ={                                                                         	{"YV12 ",IMGFMT_YV12 ,0,{sizeof(DDPIXELFORMAT), DDPF_FOURCC,MAKEFOURCC('Y','V','1','2'),0,0,0,0,0}},	{"I420 ",IMGFMT_I420 ,0,{sizeof(DDPIXELFORMAT), DDPF_FOURCC,MAKEFOURCC('I','4','2','0'),0,0,0,0,0}},   //yv12 with swapped uv 	{"IYUV ",IMGFMT_IYUV ,0,{sizeof(DDPIXELFORMAT), DDPF_FOURCC,MAKEFOURCC('I','Y','U','V'),0,0,0,0,0}},   //same as i420	{"YVU9 ",IMGFMT_YVU9 ,0,{sizeof(DDPIXELFORMAT), DDPF_FOURCC,MAKEFOURCC('Y','V','U','9'),0,0,0,0,0}},		{"YUY2 ",IMGFMT_YUY2 ,0,{sizeof(DDPIXELFORMAT), DDPF_FOURCC,MAKEFOURCC('Y','U','Y','2'),0,0,0,0,0}},	{"UYVY ",IMGFMT_UYVY ,0,{sizeof(DDPIXELFORMAT), DDPF_FOURCC,MAKEFOURCC('U','Y','V','Y'),0,0,0,0,0}}, 	{"BGR8 ",IMGFMT_BGR8 ,0,{sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 8,  0x00000000, 0x00000000, 0x00000000, 0}},   	{"RGB15",IMGFMT_RGB15,0,{sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16,  0x0000001F, 0x000003E0, 0x00007C00, 0}},   //RGB 5:5:5	{"BGR15",IMGFMT_BGR15,0,{sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16,  0x00007C00, 0x000003E0, 0x0000001F, 0}},   	{"RGB16",IMGFMT_RGB16,0,{sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16,  0x0000001F, 0x000007E0, 0x0000F800, 0}},   //RGB 5:6:5    {"BGR16",IMGFMT_BGR16,0,{sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16,  0x0000F800, 0x000007E0, 0x0000001F, 0}},   	{"RGB24",IMGFMT_RGB24,0,{sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 24,  0x000000FF, 0x0000FF00, 0x00FF0000, 0}},       {"BGR24",IMGFMT_BGR24,0,{sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 24,  0x00FF0000, 0x0000FF00, 0x000000FF, 0}},      {"RGB32",IMGFMT_RGB32,0,{sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 32,  0x000000FF, 0x0000FF00, 0x00FF0000, 0}},      {"BGR32",IMGFMT_BGR32,0,{sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 32,  0x00FF0000, 0x0000FF00, 0x000000FF, 0}}   };#define NUM_FORMATS (sizeof(g_ddpf) / sizeof(g_ddpf[0]))static vo_info_t info ={	"Directx DDraw YUV/RGB/BGR renderer",	"directx",	"Sascha Sommer <saschasommer@freenet.de>",	""};LIBVO_EXTERN(directx)static void draw_alpha(int x0, int y0, int w, int h, unsigned char *src,		unsigned char *srca, int stride){    switch(image_format) {    case IMGFMT_YV12 :    case IMGFMT_I420 :	case IMGFMT_IYUV :	case IMGFMT_YVU9 :    	vo_draw_alpha_yv12(w,h,src,srca,stride,((uint8_t *) image) + dstride*y0 + x0,dstride);	break;	case IMGFMT_YUY2 :	    vo_draw_alpha_yuy2(w,h,src,srca,stride,((uint8_t *) image)+ dstride*y0 + 2*x0 ,dstride);    break;    case IMGFMT_UYVY :        vo_draw_alpha_yuy2(w,h,src,srca,stride,((uint8_t *) image) + dstride*y0 + 2*x0 + 1,dstride);    break;	case IMGFMT_RGB15:	    case IMGFMT_BGR15:		vo_draw_alpha_rgb15(w,h,src,srca,stride,((uint8_t *) image)+dstride*y0+2*x0,dstride);    break;    case IMGFMT_RGB16:	case IMGFMT_BGR16:        vo_draw_alpha_rgb16(w,h,src,srca,stride,((uint8_t *) image)+dstride*y0+2*x0,dstride);    break;    case IMGFMT_RGB24:	case IMGFMT_BGR24:        vo_draw_alpha_rgb24(w,h,src,srca,stride,((uint8_t *) image)+dstride*y0+4*x0,dstride);    break;    case IMGFMT_RGB32:	case IMGFMT_BGR32:        vo_draw_alpha_rgb32(w,h,src,srca,stride,((uint8_t *) image)+dstride*y0+4*x0,dstride);    break;    }}static void draw_osd(void){    vo_draw_text(image_width,image_height,draw_alpha);}static intquery_format(uint32_t format){    uint32_t i=0;    while ( i < NUM_FORMATS )    {		if (g_ddpf[i].img_format == format)		    return g_ddpf[i].drv_caps;	    i++;    }    return 0;}static uint32_t Directx_CreatePrimarySurface(){    DDSURFACEDESC2   ddsd;    //cleanup	if(g_lpddsPrimary)g_lpddsPrimary->lpVtbl->Release(g_lpddsPrimary);	g_lpddsPrimary=NULL;	    if(vidmode)g_lpdd->lpVtbl->SetDisplayMode(g_lpdd,vm_width,vm_height,vm_bpp,vo_refresh_rate,0);    ZeroMemory(&ddsd, sizeof(ddsd));    ddsd.dwSize = sizeof(ddsd);    //set flags and create a primary surface.    ddsd.dwFlags = DDSD_CAPS;    ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;    if(g_lpdd->lpVtbl->CreateSurface(g_lpdd,&ddsd, &g_lpddsPrimary, NULL )== DD_OK)		mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>primary surface created\n");	else	{		mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>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;    //cleanup	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)   //tribblebuffering	{		if (g_lpdd->lpVtbl->CreateSurface(g_lpdd,&ddsdOverlay, &g_lpddsOverlay, NULL)== DD_OK)		{			mp_msg(MSGT_VO, MSGL_V,"<vo_directx><INFO>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)			{				mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't get attached surface\n");				return 1;			}			return 0;		}		vo_doublebuffering=0; //disable tribblebuffering		mp_msg(MSGT_VO, MSGL_V,"<vo_directx><WARN>cannot create tribblebuffer overlay with format %s\n",g_ddpf[i].img_format_name);	} 	//single buffer	mp_msg(MSGT_VO, MSGL_V,"<vo_directx><INFO>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)mp_msg(MSGT_VO,MSGL_V,"<vo_directx><ERROR> invalid pixelformat: %s\n",g_ddpf[i].img_format_name);       else mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>");       switch(ddrval)	   {	      case DDERR_INCOMPATIBLEPRIMARY:			 {mp_msg(MSGT_VO, MSGL_ERR,"incompatible primary surface\n");break;}		  case DDERR_INVALIDCAPS:			 {mp_msg(MSGT_VO, MSGL_ERR,"invalid caps\n");break;}	      case DDERR_INVALIDOBJECT:		     {mp_msg(MSGT_VO, MSGL_ERR,"invalid object\n");break;}	      case DDERR_INVALIDPARAMS:		     {mp_msg(MSGT_VO, MSGL_ERR,"invalid parameters\n");break;}	      case DDERR_NODIRECTDRAWHW:		     {mp_msg(MSGT_VO, MSGL_ERR,"no directdraw hardware\n");break;}	      case DDERR_NOEMULATION:		     {mp_msg(MSGT_VO, MSGL_ERR,"can't emulate\n");break;}	      case DDERR_NOFLIPHW:		     {mp_msg(MSGT_VO, MSGL_ERR,"hardware can't do flip\n");break;}	      case DDERR_NOOVERLAYHW:		     {mp_msg(MSGT_VO, MSGL_ERR,"hardware can't do overlay\n");break;}	      case DDERR_OUTOFMEMORY:		     {mp_msg(MSGT_VO, MSGL_ERR,"not enough system memory\n");break;}	      case DDERR_UNSUPPORTEDMODE:			 {mp_msg(MSGT_VO, MSGL_ERR,"unsupported mode\n");break;}  		  case DDERR_OUTOFVIDEOMEMORY:			 {mp_msg(MSGT_VO, MSGL_ERR,"not enough video memory\n");break;}          default:             mp_msg(MSGT_VO, MSGL_ERR,"create surface failed with 0x%x\n",ddrval);       	   }	   return 1;	}    g_lpddsBack = g_lpddsOverlay;	return 0;}static uint32_t Directx_CreateBackpuffer(){    DDSURFACEDESC2   ddsd;	//cleanup	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 )	{		mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't create backpuffer\n");		return 1;	}    mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>backbuffer created\n");	return 0;}static void uninit(void){	if (g_cc != NULL)	{		g_cc->lpVtbl->Release(g_cc);	}	g_cc=NULL;	if (g_lpddclipper != NULL) g_lpddclipper->lpVtbl->Release(g_lpddclipper);	g_lpddclipper = NULL;	mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>clipper released\n");	if (g_lpddsBack != NULL) g_lpddsBack->lpVtbl->Release(g_lpddsBack);	g_lpddsBack = NULL;	mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>back surface released\n");	if(vo_doublebuffering && !nooverlay)	{		if (g_lpddsOverlay != NULL)g_lpddsOverlay->lpVtbl->Release(g_lpddsOverlay);        g_lpddsOverlay = NULL;		mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>overlay surface released\n");	}	if (g_lpddsPrimary != NULL) g_lpddsPrimary->lpVtbl->Release(g_lpddsPrimary);    g_lpddsPrimary = NULL;	mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>primary released\n");	if(hWndFS)DestroyWindow(hWndFS);	hWndFS = NULL;	if((WinID == -1) && hWnd) DestroyWindow(hWnd);	hWnd = NULL;	mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>window destroyed\n");	UnregisterClass(WNDCLASSNAME_WINDOWED, GetModuleHandle(NULL));	UnregisterClass(WNDCLASSNAME_FULLSCREEN, GetModuleHandle(NULL));	if (mplayericon) DestroyIcon(mplayericon);	mplayericon = NULL;	if (mplayercursor) DestroyCursor(mplayercursor);	mplayercursor = NULL;	if (blackbrush) DeleteObject(blackbrush);	blackbrush = NULL;	if (colorbrush) DeleteObject(colorbrush);	colorbrush = NULL;	mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>GDI resources deleted\n");	if (g_lpdd != NULL){	    if(vidmode)g_lpdd->lpVtbl->RestoreDisplayMode(g_lpdd);	    g_lpdd->lpVtbl->Release(g_lpdd);	}  	mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>directdrawobject released\n");	FreeLibrary( hddraw_dll);	hddraw_dll= NULL;	mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>ddraw.dll freed\n");	mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>uninited\n");    }static BOOL WINAPI EnumCallbackEx(GUID FAR *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName, LPVOID lpContext, HMONITOR  hm){       mp_msg(MSGT_VO, MSGL_INFO ,"<vo_directx> adapter %d: ", adapter_count);    if (!lpGUID)    {        mp_msg(MSGT_VO, MSGL_INFO ,"%s", "Primary Display Adapter");    }    else    {        mp_msg(MSGT_VO, MSGL_INFO ,"%s", lpDriverDescription);    }        if(adapter_count == vo_adapter_num){        MONITORINFO mi;        if (!lpGUID)            selected_guid_ptr = NULL;        else

⌨️ 快捷键说明

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