📄 vo_directx.c
字号:
/********************************************** * 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 + -