📄 vo_directx.c
字号:
if(mpi->flags&MP_IMGFLAG_PLANAR) { if(image_format == IMGFMT_YV12) { mpi->planes[2]= image + dstride*image_height; mpi->planes[1]= image + dstride*image_height+ dstride*image_height/4; mpi->stride[1]=mpi->stride[2]=dstride/2; } else if(image_format == IMGFMT_IYUV || image_format == IMGFMT_I420) { mpi->planes[1]= image + dstride*image_height; mpi->planes[2]= image + dstride*image_height+ dstride*image_height/4; mpi->stride[1]=mpi->stride[2]=dstride/2; } else if(image_format == IMGFMT_YVU9) { mpi->planes[2] = image + dstride*image_height; mpi->planes[1] = image + dstride*image_height+ dstride*image_height/16; mpi->stride[1]=mpi->stride[2]=dstride/4; } } mpi->planes[0]=image; mpi->stride[0]=dstride; mpi->width=image_width; mpi->height=image_height; mpi->flags|=MP_IMGFLAG_DIRECT; mp_msg(MSGT_VO, MSGL_DBG3, "<vo_directx><INFO>Direct Rendering ENABLED\n"); return VO_TRUE; } return VO_FALSE;} static uint32_t put_image(mp_image_t *mpi){ uint32_t i = 0; uint8_t *d; uint8_t *s; uint32_t x = mpi->x; uint32_t y = mpi->y; uint32_t w = mpi->w; uint32_t h = mpi->h; if (WinID != -1) Directx_ManageDisplay(); if((mpi->flags&MP_IMGFLAG_DIRECT)||(mpi->flags&MP_IMGFLAG_DRAW_CALLBACK)) { mp_msg(MSGT_VO, MSGL_DBG3 ,"<vo_directx><INFO>put_image: nothing to do: drawslices\n"); return VO_TRUE; } if (mpi->flags&MP_IMGFLAG_PLANAR) { if(image_format!=IMGFMT_YVU9)draw_slice(mpi->planes,mpi->stride,mpi->w,mpi->h,0,0); else { // copy Y d=image+dstride*y+x; s=mpi->planes[0]; mem2agpcpy_pic(d,s,w,h,dstride,mpi->stride[0]); w/=4;h/=4;x/=4;y/=4; // copy V d=image+dstride*image_height + dstride*y/4+x; s=mpi->planes[2]; mem2agpcpy_pic(d,s,w,h,dstride/4,mpi->stride[1]); // copy U d=image+dstride*image_height + dstride*image_height/16 + dstride/4*y+x; s=mpi->planes[1]; mem2agpcpy_pic(d,s,w,h,dstride/4,mpi->stride[2]); } } else //packed { fast_memcpy( image, mpi->planes[0], image_height * dstride); } return VO_TRUE;}static intconfig(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t options, char *title, uint32_t format){ RECT rd; vo_fs = options & 0x01; image_format = format; image_width = width; image_height = height; d_image_width = d_width; d_image_height = d_height; if(format != primary_image_format)nooverlay = 0; window_aspect= (float)d_image_width / (float)d_image_height;#ifdef HAVE_NEW_GUI if(use_gui){ guiGetEvent(guiSetShVideo, 0); }#endif /*release all directx objects*/ if (g_cc != NULL)g_cc->lpVtbl->Release(g_cc); g_cc=NULL; if(g_lpddclipper)g_lpddclipper->lpVtbl->Release(g_lpddclipper); g_lpddclipper=NULL; if (g_lpddsBack != NULL) g_lpddsBack->lpVtbl->Release(g_lpddsBack); g_lpddsBack = NULL; if(vo_doublebuffering) if (g_lpddsOverlay != NULL)g_lpddsOverlay->lpVtbl->Release(g_lpddsOverlay); g_lpddsOverlay = NULL; if (g_lpddsPrimary != NULL) g_lpddsPrimary->lpVtbl->Release(g_lpddsPrimary); g_lpddsPrimary = NULL; mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>overlay surfaces released\n"); if(!vidmode){ if(!vo_geometry){ GetWindowRect(hWnd,&rd); vo_dx=rd.left; vo_dy=rd.top; } vo_dx += monitor_rect.left; /* move position to global window space */ vo_dy += monitor_rect.top; rd.left = vo_dx; rd.top = vo_dy; rd.right = rd.left + d_image_width; rd.bottom = rd.top + d_image_height; if (WinID == -1) { if (vo_border) AdjustWindowRect(&rd,WNDSTYLE,FALSE); SetWindowPos(hWnd,NULL, vo_dx, vo_dy,rd.right-rd.left,rd.bottom-rd.top,SWP_SHOWWINDOW|SWP_NOOWNERZORDER); } } else ShowWindow(hWnd,SW_SHOW); if(vo_fs && !vidmode)ShowWindow(hWndFS,SW_SHOW); if (WinID == -1) SetWindowText(hWnd,title); if(vidmode)vo_fs=0; /*create the surfaces*/ if(Directx_CreatePrimarySurface())return 1; //create palette for 256 color mode if(image_format==IMGFMT_BGR8){ LPDIRECTDRAWPALETTE ddpalette=NULL; char* palette=malloc(4*256); int i; for(i=0; i<256; i++){ palette[4*i+0] = ((i >> 5) & 0x07) * 255 / 7; palette[4*i+1] = ((i >> 2) & 0x07) * 255 / 7; palette[4*i+2] = ((i >> 0) & 0x03) * 255 / 3; palette[4*i+3] = PC_NOCOLLAPSE; } g_lpdd->lpVtbl->CreatePalette(g_lpdd,DDPCAPS_8BIT|DDPCAPS_INITIALIZE,palette,&ddpalette,NULL); g_lpddsPrimary->lpVtbl->SetPalette(g_lpddsPrimary,ddpalette); free(palette); ddpalette->lpVtbl->Release(ddpalette); } if (!nooverlay && Directx_CreateOverlay(image_format)) { if(format == primary_image_format)nooverlay=1; /*overlay creation failed*/ else { mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't use overlay mode: please use -vo directx:noaccel\n"); return 1; } } if(nooverlay) { if(Directx_CreateBackpuffer()) { mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't get the driver to work on your system :(\n"); return 1; } mp_msg(MSGT_VO, MSGL_V,"<vo_directx><INFO>back surface created\n"); vo_doublebuffering = 0; /*create clipper for nonoverlay mode*/ if(g_lpdd->lpVtbl->CreateClipper(g_lpdd, 0, &g_lpddclipper,NULL)!= DD_OK){mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't create clipper\n");return 1;} if(g_lpddclipper->lpVtbl->SetHWnd (g_lpddclipper, 0, hWnd)!= DD_OK){mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't associate clipper with window\n");return 1;} if(g_lpddsPrimary->lpVtbl->SetClipper (g_lpddsPrimary,g_lpddclipper)!=DD_OK){mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't associate primary surface with clipper\n");return 1;} mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>clipper succesfully created\n"); }else{ if(DD_OK != g_lpddsOverlay->lpVtbl->QueryInterface(g_lpddsOverlay,&IID_IDirectDrawColorControl,(void**)&g_cc)) mp_msg(MSGT_VO, MSGL_V,"<vo_directx><WARN>unable to get DirectDraw ColorControl interface\n"); } Directx_ManageDisplay(); memset(&ddsdsf, 0,sizeof(DDSURFACEDESC2)); ddsdsf.dwSize = sizeof (DDSURFACEDESC2); g_lpddsBack->lpVtbl->Lock(g_lpddsBack,NULL,&ddsdsf, DDLOCK_NOSYSLOCK | DDLOCK_WAIT, NULL); dstride = ddsdsf.lPitch; image = ddsdsf.lpSurface; return 0;}//function to set color controls// brightness [0, 10000]// contrast [0, 20000]// hue [-180, 180]// saturation [0, 20000]static uint32_t color_ctrl_set(char *what, int value){ uint32_t r = VO_NOTIMPL; DDCOLORCONTROL dcc; //printf("\n*** %s = %d\n", what, value); if (!g_cc) { //printf("\n *** could not get color control interface!!!\n"); return VO_NOTIMPL; } ZeroMemory(&dcc, sizeof(dcc)); dcc.dwSize = sizeof(dcc); if (!strcmp(what, "brightness")) { dcc.dwFlags = DDCOLOR_BRIGHTNESS; dcc.lBrightness = (value + 100) * 10000 / 200; r = VO_TRUE; } else if (!strcmp(what, "contrast")) { dcc.dwFlags = DDCOLOR_CONTRAST; dcc.lContrast = (value + 100) * 20000 / 200; r = VO_TRUE; } else if (!strcmp(what, "hue")) { dcc.dwFlags = DDCOLOR_HUE; dcc.lHue = value * 180 / 100; r = VO_TRUE; } else if (!strcmp(what, "saturation")) { dcc.dwFlags = DDCOLOR_SATURATION; dcc.lSaturation = (value + 100) * 20000 / 200; r = VO_TRUE; } if (r == VO_TRUE) { g_cc->lpVtbl->SetColorControls(g_cc, &dcc); } return r;}//analoguous to color_ctrl_setstatic uint32_t color_ctrl_get(char *what, int *value){ uint32_t r = VO_NOTIMPL; DDCOLORCONTROL dcc; if (!g_cc) { //printf("\n *** could not get color control interface!!!\n"); return VO_NOTIMPL; } ZeroMemory(&dcc, sizeof(dcc)); dcc.dwSize = sizeof(dcc); if (g_cc->lpVtbl->GetColorControls(g_cc, &dcc) != DD_OK) { return r; } if (!strcmp(what, "brightness") && (dcc.dwFlags & DDCOLOR_BRIGHTNESS)) { *value = dcc.lBrightness * 200 / 10000 - 100; r = VO_TRUE; } else if (!strcmp(what, "contrast") && (dcc.dwFlags & DDCOLOR_CONTRAST)) { *value = dcc.lContrast * 200 / 20000 - 100; r = VO_TRUE; } else if (!strcmp(what, "hue") && (dcc.dwFlags & DDCOLOR_HUE)) { *value = dcc.lHue * 100 / 180; r = VO_TRUE; } else if (!strcmp(what, "saturation") && (dcc.dwFlags & DDCOLOR_SATURATION)) { *value = dcc.lSaturation * 200 / 20000 - 100; r = VO_TRUE; }// printf("\n*** %s = %d\n", what, *value); return r;}static int control(uint32_t request, void *data, ...){ switch (request) { case VOCTRL_GET_IMAGE: return get_image(data); case VOCTRL_QUERY_FORMAT: last_rect.left = 0xDEADC0DE; // reset window position cache return query_format(*((uint32_t*)data)); case VOCTRL_DRAW_IMAGE: return put_image(data); case VOCTRL_BORDER: if(WinID != -1) return VO_TRUE; if(vidmode) { mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>border has no meaning in exclusive mode\n"); } else { if(vo_border) { vo_border = 0; SetWindowLong(hWnd, GWL_STYLE, WS_POPUP); } else { vo_border = 1; SetWindowLong(hWnd, GWL_STYLE, WNDSTYLE); } // needed AFAICT to force the window to // redisplay with the new style. --Joey if (!vo_fs) { ShowWindow(hWnd,SW_HIDE); ShowWindow(hWnd,SW_SHOW); } last_rect.left = 0xDEADC0DE; // reset window position cache Directx_ManageDisplay(); } return VO_TRUE; case VOCTRL_ONTOP: if(WinID != -1) return VO_TRUE; if(vidmode) { mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>ontop has no meaning in exclusive mode\n"); } else { if(vo_ontop) vo_ontop = 0; else vo_ontop = 1; last_rect.left = 0xDEADC0DE; // reset window position cache Directx_ManageDisplay(); } return VO_TRUE; case VOCTRL_ROOTWIN: if(WinID != -1) return VO_TRUE; if(vidmode) { mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>rootwin has no meaning in exclusive mode\n"); } else { if(vo_rootwin) vo_rootwin = 0; else vo_rootwin = 1; last_rect.left = 0xDEADC0DE; // reset window position cache Directx_ManageDisplay(); } return VO_TRUE; case VOCTRL_FULLSCREEN: { if(vidmode) { mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>currently we do not allow to switch from exclusive to windowed mode\n"); } else { if(!vo_fs) { vo_fs=1; ShowWindow(hWndFS,SW_SHOW); ShowWindow(hWnd,SW_HIDE); SetForegroundWindow(hWndFS); } else { vo_fs=0; ShowWindow(hWndFS,SW_HIDE); ShowWindow(hWnd,SW_SHOW); } last_rect.left = 0xDEADC0DE; // reset window position cache Directx_ManageDisplay(); break; } return VO_TRUE; } case VOCTRL_SET_EQUALIZER: { va_list ap; int value; va_start(ap, data); value = va_arg(ap, int); va_end(ap); return color_ctrl_set(data, value); } case VOCTRL_GET_EQUALIZER: { va_list ap; int *value; va_start(ap, data); value = va_arg(ap, int*); va_end(ap); return color_ctrl_get(data, value); } case VOCTRL_UPDATE_SCREENINFO: if (vidmode) { vo_screenwidth = vm_width; vo_screenheight = vm_height; } else { vo_screenwidth = monitor_rect.right - monitor_rect.left; vo_screenheight = monitor_rect.bottom - monitor_rect.top; } aspect_save_screenres(vo_screenwidth, vo_screenheight); return VO_TRUE; case VOCTRL_RESET: last_rect.left = 0xDEADC0DE; // reset window position cache // fall-through intended }; return VO_NOTIMPL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -