/** * \brief Update screen information. * * This function should be called in libvo's "control" callback * with parameter VOCTRL_UPDATE_SCREENINFO. * Note that this also enables the new API where geometry and aspect * calculations are done in video_out.c:config_video_out * * Global libvo variables changed: * xinerama_x * xinerama_y * vo_screenwidth * vo_screenheight */ void w32_update_xinerama_info(struct vo *vo) { struct vo_w32_state *w32 = vo->w32; struct mp_vo_opts *opts = vo->opts; int screen = opts->fs ? opts->fsscreen_id : opts->screen_id; vo->xinerama_x = vo->xinerama_y = 0; if (opts->fs && screen == -2) { int tmp; vo->xinerama_x = GetSystemMetrics(SM_XVIRTUALSCREEN); vo->xinerama_y = GetSystemMetrics(SM_YVIRTUALSCREEN); tmp = GetSystemMetrics(SM_CXVIRTUALSCREEN); if (tmp) vo->opts->screenwidth = tmp; tmp = GetSystemMetrics(SM_CYVIRTUALSCREEN); if (tmp) vo->opts->screenheight = tmp; } else if (screen == -1) { MONITORINFO mi; HMONITOR m = MonitorFromWindow(w32->window, MONITOR_DEFAULTTOPRIMARY); mi.cbSize = sizeof(mi); GetMonitorInfoW(m, &mi); vo->xinerama_x = mi.rcMonitor.left; vo->xinerama_y = mi.rcMonitor.top; vo->opts->screenwidth = mi.rcMonitor.right - mi.rcMonitor.left; vo->opts->screenheight = mi.rcMonitor.bottom - mi.rcMonitor.top; } else if (screen >= 0) { w32->mon_cnt = 0; w32->mon_id = screen; EnumDisplayMonitors(NULL, NULL, mon_enum, (LONG_PTR)vo); } aspect_save_screenres(vo, vo->opts->screenwidth, vo->opts->screenheight); }
static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t flags, char *title, uint32_t format) { image_width = width; image_height = height; vo_fs = flags & VOFLAG_FULLSCREEN; vo_dwidth = d_width; vo_dheight = d_height; vo_screenwidth = screenwidth; vo_screenheight = screenheight; aspect_save_orig(width, height); aspect_save_prescale(d_width, d_height); aspect_save_screenres(vo_screenwidth, vo_screenheight); resize(); int xs, ys; mp_get_chroma_shift(format, &xs, &ys); mpgxConfigYUVp(image_width, image_height, image_width >> xs, image_height >> ys); return VO_FALSE; }
/** * \brief Update screen information. * * This function should be called in libvo's "control" callback * with parameter VOCTRL_UPDATE_SCREENINFO. * Note that this also enables the new API where geometry and aspect * calculations are done in video_out.c:config_video_out * * Global libvo variables changed: * xinerama_x * xinerama_y * vo_screenwidth * vo_screenheight */ void w32_update_xinerama_info(void) { xinerama_x = xinerama_y = 0; if (xinerama_screen < -1) { int tmp; xinerama_x = GetSystemMetrics(SM_XVIRTUALSCREEN); xinerama_y = GetSystemMetrics(SM_YVIRTUALSCREEN); tmp = GetSystemMetrics(SM_CXVIRTUALSCREEN); if (tmp) vo_screenwidth = tmp; tmp = GetSystemMetrics(SM_CYVIRTUALSCREEN); if (tmp) vo_screenheight = tmp; } else if (xinerama_screen == -1 && myMonitorFromWindow && myGetMonitorInfo) { MONITORINFO mi; HMONITOR m = myMonitorFromWindow(vo_window, MONITOR_DEFAULTTOPRIMARY); mi.cbSize = sizeof(mi); myGetMonitorInfo(m, &mi); xinerama_x = mi.rcMonitor.left; xinerama_y = mi.rcMonitor.top; vo_screenwidth = mi.rcMonitor.right - mi.rcMonitor.left; vo_screenheight = mi.rcMonitor.bottom - mi.rcMonitor.top; } else if (xinerama_screen > 0 && myEnumDisplayMonitors) { mon_cnt = 0; myEnumDisplayMonitors(NULL, NULL, mon_enum, 0); } aspect_save_screenres(vo_screenwidth, vo_screenheight); }
int main(int argc, char *argv[]) { int w,h,z=DEF_ZOOM; //printf("argc: %d\n",argc); switch(argc) { case 10: z = atoi(argv[9]); case 9: monitor_aspect = (float)atoi(argv[7])/(float)atoi(argv[8]); case 7: aspect_save_prescale(atoi(argv[5]),atoi(argv[6])); printf("prescale size: %sx%s\n",argv[5],argv[6]); case 5: aspect_save_screenres(atoi(argv[1]),atoi(argv[2])); printf("screenres: %sx%s\n",argv[1],argv[2]); aspect_save_orig(atoi(argv[3]),atoi(argv[4])); printf("original size: %sx%s\n",argv[3],argv[4]); w=atoi(argv[3]); h=atoi(argv[4]); break; default: printf("USAGE: %s <screenw> <screenh> <origw> <origh>\n[<prescalew> " "<prescaleh>] [<screenaspectw> <screenaspecth>] [<zoom 0/1>]\n", argv[0]); return 1; } printf("monitor_aspect: %f\n",monitor_aspect); aspect(&w,&h,z); printf("new size: %dx%d\n",w,h); return 0; }
static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_QUERY_FORMAT: return query_format(*((uint32_t*)data)); case VOCTRL_UPDATE_SCREENINFO: vo_screenwidth = fb_vinfo.xres; vo_screenheight = fb_vinfo.yres; aspect_save_screenres(vo_screenwidth, vo_screenheight); return VO_TRUE; } return VO_NOTIMPL; }
static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t flags, char *title, uint32_t format) { // if (f >= 0) mga_uninit(); if(!vo_screenwidth || !vo_screenheight) { int fd; struct fb_var_screeninfo fbinfo; if(-1 != (fd = open(FBDEV, O_RDONLY))) { if(0 == ioctl(fd, FBIOGET_VSCREENINFO, &fbinfo)) { if(!vo_screenwidth) vo_screenwidth = fbinfo.xres; if(!vo_screenheight) vo_screenheight = fbinfo.yres; } else { perror("FBIOGET_VSCREENINFO"); } close(fd); } else { perror(FBDEV); } } if(vo_screenwidth && vo_screenheight){ aspect_save_orig(width,height); aspect_save_prescale(d_width,d_height); aspect_save_screenres(vo_screenwidth,vo_screenheight); if(flags&VOFLAG_FULLSCREEN) { /* -fs */ aspect(&d_width,&d_height,A_ZOOM); vo_fs = VO_TRUE; } else { aspect(&d_width,&d_height,A_NOZOOM); vo_fs = VO_FALSE; } mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_MGA_AspectResized,d_width,d_height); } vo_dwidth=d_width; vo_dheight=d_height; mga_vid_config.dest_width = d_width; mga_vid_config.dest_height= d_height; mga_vid_config.x_org= 0; // (720-mga_vid_config.dest_width)/2; mga_vid_config.y_org= 0; // (576-mga_vid_config.dest_height)/2; if(vo_screenwidth && vo_screenheight){ mga_vid_config.x_org=(vo_screenwidth-d_width)/2; mga_vid_config.y_org=(vo_screenheight-d_height)/2; } return mga_init(width,height,format); }
static void resize(void){ /* * this function is called by aa lib if windows resizes * further during init, because here we have to calculate * a little bit */ aa_resize(c); aspect_save_screenres(aa_imgwidth(c),aa_imgheight(c)); image_height = aa_imgheight(c); //src_height; image_width = aa_imgwidth(c); //src_width; aspect(&image_width,&image_height,A_ZOOM); image_x = (aa_imgwidth(c) - image_width) / 2; image_y = (aa_imgheight(c) - image_height) / 2; screen_w = image_width * aa_scrwidth(c) / aa_imgwidth(c); screen_h = image_height * aa_scrheight(c) / aa_imgheight(c); screen_x = (aa_scrwidth(c) - screen_w) / 2; screen_y = (aa_scrheight(c) - screen_h) / 2; if(sws) sws_freeContext(sws); sws = sws_getContextFromCmdLine(src_width,src_height,image_format, image_width,image_height,IMGFMT_Y8); memset(image, 0, sizeof(image)); image[0] = aa_image(c) + image_y * aa_imgwidth(c) + image_x; memset(image_stride, 0, sizeof(image_stride)); image_stride[0] = aa_imgwidth(c); showosdmessage=0; }
static int config(uint32_t width, uint32_t height, uint32_t d_width,uint32_t d_height, uint32_t flags, char *title, uint32_t format){ title = "MPlayer VIDIX WIN32 Overlay"; panscan_init(); image_height = height; image_width = width; image_format = format; vo_screenwidth = GetSystemMetrics(SM_CXSCREEN); vo_screenheight = GetSystemMetrics(SM_CYSCREEN); vo_depthonscreen = GetDeviceCaps(GetDC(GetDesktopWindow()),BITSPIXEL); aspect_save_orig(width, height); aspect_save_prescale(d_width, d_height); aspect_save_screenres(vo_screenwidth, vo_screenheight); vo_dx = 0; vo_dy = 0; vo_dx=( vo_screenwidth - d_width ) / 2; vo_dy=( vo_screenheight - d_height ) / 2; geometry(&vo_dx, &vo_dy, &d_width, &d_height, vo_screenwidth, vo_screenheight); vo_fs = flags&VOFLAG_FULLSCREEN; aspect(&d_width, &d_height, A_NOZOOM); vo_dwidth=d_width; vo_dheight=d_height; window_aspect = (float)d_width / (float)d_height; if(!vo_config_count){ HINSTANCE hInstance = GetModuleHandle(NULL); WNDCLASS wc; RECT rd; rd.left = vo_dx; rd.top = vo_dy; rd.right = rd.left + vo_dwidth; rd.bottom = rd.top + vo_dheight; AdjustWindowRect(&rd,WS_OVERLAPPEDWINDOW| WS_SIZEBOX,0); wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hCursor = LoadCursor(NULL,IDC_ARROW); wc.hIcon =ExtractIcon(hInstance,"mplayer.exe",0); //LoadIcon(NULL,IDI_APPLICATION); wc.hbrBackground = CreateSolidBrush(RGB(255,0,255)); wc.lpszClassName = "MPlayer - The Movie Player"; wc.lpszMenuName = NULL; RegisterClass(&wc); hWnd = CreateWindow("MPlayer - The Movie Player", title, WS_OVERLAPPEDWINDOW| WS_SIZEBOX, rd.left, rd.top, rd.right - rd.left, rd.bottom - rd.top, NULL, NULL, hInstance, NULL); wc.hbrBackground = CreateSolidBrush(RGB(0,0,0)); wc.lpszClassName = "MPlayer - Fullscreen"; RegisterClass(&wc); hWndFS = CreateWindow("MPlayer - Fullscreen","MPlayer VIDIX Fullscreen",WS_POPUP,0,0,vo_screenwidth,vo_screenheight,hWnd,NULL,hInstance,NULL); } ShowWindow(hWnd,SW_SHOW); if(vo_fs)ShowWindow(hWndFS,SW_SHOW); return 0; }
static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t flags, char *title, uint32_t format) { int x_off, y_off; int wanted_width, wanted_height; static unsigned char *vo_dga_base; static int prev_width, prev_height; #ifdef HAVE_DGA2 // needed to change DGA video mode int mX = VO_DGA_INVALID_RES, mY = VO_DGA_INVALID_RES, mVBI = 100000, mMaxY = 0, i, j = 0; int dga_modenum; XDGAMode *modeline; XDGADevice *dgadevice; #else #ifdef HAVE_XF86VM unsigned int vm_event, vm_error; unsigned int vm_ver, vm_rev; int i, j = 0, have_vm = 0; int mX = VO_DGA_INVALID_RES, mY = VO_DGA_INVALID_RES, mVBI = 100000, mMaxY = 0, dga_modenum; #endif int bank, ram; #endif vo_dga_src_format = format; wanted_width = d_width; wanted_height = d_height; if (!wanted_height) wanted_height = height; if (!wanted_width) wanted_width = width; if (!vo_dbpp) { if ((format & IMGFMT_BGR_MASK) == IMGFMT_BGR) { vo_dga_src_mode = vd_ModeValid(format & 0xff); } } else { vo_dga_src_mode = vd_ModeValid(vo_dbpp); } vo_dga_hw_mode = SRC_MODE.vdm_hw_mode; if (!vo_dga_src_mode) { mp_msg(MSGT_VO, MSGL_ERR, "vo_dga: unsupported video format!\n"); return 1; } vo_dga_vp_width = vo_screenwidth; vo_dga_vp_height = vo_screenheight; mp_msg(MSGT_VO, MSGL_V, "vo_dga: XServer res: %dx%d\n", vo_dga_vp_width, vo_dga_vp_height); // choose a suitable mode ... #ifdef HAVE_DGA2 // Code to change the video mode added by Michael Graffam // [email protected] mp_msg(MSGT_VO, MSGL_V, "vo_dga: vo_modelines=%p, vo_modecount=%d\n", vo_modelines, vo_modecount); if (vo_modelines == NULL) { mp_msg(MSGT_VO, MSGL_ERR, "vo_dga: can't get modelines\n"); return 1; } mp_msg(MSGT_VO, MSGL_INFO, "vo_dga: DGA 2.0 available :-) Can switch resolution AND depth!\n"); for (i = 0; i < vo_modecount; i++) { if (vd_ModeEqual(vo_modelines[i].depth, vo_modelines[i].bitsPerPixel, vo_modelines[i].redMask, vo_modelines[i].greenMask, vo_modelines[i].blueMask, vo_dga_hw_mode)) { mp_msg(MSGT_VO, MSGL_V, "maxy: %4d, depth: %2d, %4dx%4d, ", vo_modelines[i].maxViewportY, vo_modelines[i].depth, vo_modelines[i].imageWidth, vo_modelines[i].imageHeight); if (check_res (i, wanted_width, wanted_height, vo_modelines[i].depth, vo_modelines[i].viewportWidth, vo_modelines[i].viewportHeight, (unsigned) vo_modelines[i].verticalRefresh, vo_modelines[i].maxViewportY, &mX, &mY, &mVBI, &mMaxY)) j = i; } } mp_msg(MSGT_VO, MSGL_INFO, "vo_dga: Selected hardware mode %4d x %4d @ %3d Hz @ depth %2d, bitspp %2d.\n", mX, mY, mVBI, HW_MODE.vdm_depth, HW_MODE.vdm_bitspp); mp_msg(MSGT_VO, MSGL_INFO, "vo_dga: Video parameters by codec: %3d x %3d, depth %2d, bitspp %2d.\n", width, height, SRC_MODE.vdm_depth, SRC_MODE.vdm_bitspp); vo_dga_vp_width = mX; vo_dga_vp_height = mY; if ((flags & VOFLAG_SWSCALE) || (flags & VOFLAG_FULLSCREEN)) { /* -zoom or -fs */ scale_dstW = (d_width + 7) & ~7; scale_dstH = d_height; scale_srcW = width; scale_srcH = height; aspect_save_screenres(mX, mY); aspect_save_orig(scale_srcW, scale_srcH); aspect_save_prescale(scale_dstW, scale_dstH); if (flags & VOFLAG_FULLSCREEN) /* -fs */ aspect(&scale_dstW, &scale_dstH, A_ZOOM); else if (flags & VOFLAG_SWSCALE) /* -fs */ aspect(&scale_dstW, &scale_dstH, A_NOZOOM); mp_msg(MSGT_VO, MSGL_INFO, "vo_dga: Aspect corrected size for SwScaler: %4d x %4d.\n", scale_dstW, scale_dstH); /* XXX this is a hack, but I'm lazy ;-) :: atmos */ width = scale_dstW; height = scale_dstH; } vo_dga_width = vo_modelines[j].bytesPerScanline / HW_MODE.vdm_bytespp; dga_modenum = vo_modelines[j].num; modeline = vo_modelines + j; #else #ifdef HAVE_XF86VM mp_msg(MSGT_VO, MSGL_INFO, "vo_dga: DGA 1.0 compatibility code: Using XF86VidMode for mode switching!\n"); if (XF86VidModeQueryExtension(mDisplay, &vm_event, &vm_error)) { XF86VidModeQueryVersion(mDisplay, &vm_ver, &vm_rev); mp_msg(MSGT_VO, MSGL_INFO, "vo_dga: XF86VidMode Extension v%i.%i\n", vm_ver, vm_rev); have_vm = 1; } else { mp_msg(MSGT_VO, MSGL_ERR, "vo_dga: XF86VidMode Extension not available.\n"); } #define GET_VREFRESH(dotclk, x, y)( (((dotclk)/(x))*1000)/(y) ) if (have_vm) { int modecount; XF86VidModeGetAllModeLines(mDisplay, mScreen, &modecount, &vo_dga_vidmodes); if (vo_dga_vidmodes != NULL) { for (i = 0; i < modecount; i++) { if (check_res(i, wanted_width, wanted_height, vo_dga_modes[vo_dga_hw_mode].vdm_depth, vo_dga_vidmodes[i]->hdisplay, vo_dga_vidmodes[i]->vdisplay, GET_VREFRESH(vo_dga_vidmodes[i]->dotclock, vo_dga_vidmodes[i]->htotal, vo_dga_vidmodes[i]->vtotal), 0, &mX, &mY, &mVBI, &mMaxY)) j = i; } mp_msg(MSGT_VO, MSGL_INFO, "vo_dga: Selected video mode %4d x %4d @ %3d Hz @ depth %2d, bitspp %2d, video %3d x %3d.\n", mX, mY, mVBI, vo_dga_modes[vo_dga_hw_mode].vdm_depth, vo_dga_modes[vo_dga_hw_mode].vdm_bitspp, width, height); } else { mp_msg(MSGT_VO, MSGL_INFO, "vo_dga: XF86VidMode returned no screens - using current resolution.\n"); } dga_modenum = j; vo_dga_vp_width = mX; vo_dga_vp_height = mY; } #else mp_msg(MSGT_VO, MSGL_INFO, "vo_dga: Only have DGA 1.0 extension and no XF86VidMode :-(\n"); mp_msg(MSGT_VO, MSGL_INFO, " Thus, resolution switching is NOT possible.\n"); #endif #endif vo_dga_src_width = width; vo_dga_src_height = height; if (vo_dga_src_width > vo_dga_vp_width || vo_dga_src_height > vo_dga_vp_height) { mp_msg(MSGT_VO, MSGL_ERR, "vo_dga: Sorry, video larger than viewport is not yet supported!\n"); // ugly, do something nicer in the future ... #ifndef HAVE_DGA2 #ifdef HAVE_XF86VM if (vo_dga_vidmodes) { XFree(vo_dga_vidmodes); vo_dga_vidmodes = NULL; } #endif #endif return 1; } if (vo_dga_vp_width == VO_DGA_INVALID_RES) { mp_msg(MSGT_VO, MSGL_ERR, "vo_dga: Something is wrong with your DGA. There doesn't seem to be a\n" " single suitable mode!\n" " Please file a bug report (see DOCS/HTML/en/bugreports.html)\n"); #ifndef HAVE_DGA2 #ifdef HAVE_XF86VM if (vo_dga_vidmodes) { XFree(vo_dga_vidmodes); vo_dga_vidmodes = NULL; } #endif #endif return 1; } // now let's start the DGA thing if (!vo_config_count || width != prev_width || height != prev_height) { #ifdef HAVE_DGA2 if (!XDGAOpenFramebuffer(mDisplay, mScreen)) { mp_msg(MSGT_VO, MSGL_ERR, "vo_dga: Framebuffer mapping failed!!!\n"); return 1; } dgadevice = XDGASetMode(mDisplay, mScreen, dga_modenum); XDGASync(mDisplay, mScreen); vo_dga_base = dgadevice->data; XFree(dgadevice); XDGASetViewport(mDisplay, mScreen, 0, 0, XDGAFlipRetrace); #else #ifdef HAVE_XF86VM if (have_vm) { XF86VidModeLockModeSwitch(mDisplay, mScreen, 0); // Two calls are needed to switch modes on my ATI Rage 128. Why? // for riva128 one call is enough! XF86VidModeSwitchToMode(mDisplay, mScreen, vo_dga_vidmodes[dga_modenum]); XF86VidModeSwitchToMode(mDisplay, mScreen, vo_dga_vidmodes[dga_modenum]); } #endif XF86DGAGetViewPortSize(mDisplay, mScreen, &vo_dga_vp_width, &vo_dga_vp_height); XF86DGAGetVideo(mDisplay, mScreen, (char **) &vo_dga_base, &vo_dga_width, &bank, &ram); XF86DGADirectVideo(mDisplay, mScreen, XF86DGADirectGraphics | XF86DGADirectMouse | XF86DGADirectKeyb); XF86DGASetViewPort(mDisplay, mScreen, 0, 0); #endif } // do some more checkings here ... mp_msg(MSGT_VO, MSGL_V, "vo_dga: bytes/line: %d, screen res: %dx%d, depth: %d, base: %p, bpp: %d\n", vo_dga_width, vo_dga_vp_width, vo_dga_vp_height, HW_MODE.vdm_bytespp, vo_dga_base, HW_MODE.vdm_bitspp); x_off = (vo_dga_vp_width - vo_dga_src_width) >> 1; y_off = (vo_dga_vp_height - vo_dga_src_height) >> 1; vo_dga_bytes_per_line = vo_dga_src_width * HW_MODE.vdm_bytespp; vo_dga_lines = vo_dga_src_height; vo_dga_src_offset = 0; vo_dga_vp_offset = (y_off * vo_dga_width + x_off) * HW_MODE.vdm_bytespp; vo_dga_vp_skip = (vo_dga_width - vo_dga_src_width) * HW_MODE.vdm_bytespp; // todo mp_msg(MSGT_VO, MSGL_V, "vo_dga: vp_off=%d, vp_skip=%d, bpl=%d\n", vo_dga_vp_offset, vo_dga_vp_skip, vo_dga_bytes_per_line); XGrabKeyboard(mDisplay, DefaultRootWindow(mDisplay), True, GrabModeAsync, GrabModeAsync, CurrentTime); if (vo_grabpointer) XGrabPointer(mDisplay, DefaultRootWindow(mDisplay), True, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); if (!vo_config_count || width != prev_width || height != prev_height) { init_video_buffers(vo_dga_base, vo_dga_vp_height, vo_dga_width * HW_MODE.vdm_bytespp, #ifdef HAVE_DGA2 modeline->maxViewportY, #else vo_dga_vp_height, #endif vo_doublebuffering); prev_width = width; prev_height = height; } mp_msg(MSGT_VO, MSGL_V, "vo_dga: Using %d frame buffer%s.\n", vo_dga_nr_video_buffers, vo_dga_nr_video_buffers == 1 ? "" : "s"); vo_dga_is_running = 1; return 0; }
static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t flags, char *title, uint32_t format) { if(tdfx_fd < 0) return 1; // When we are run as sub vo we must follow the size gaven to us if(!(flags & VOFLAG_XOVERLAY_SUB_VO)) { if(!vo_screenwidth) vo_screenwidth = tdfx_cfg.screen_width; if(!vo_screenheight) vo_screenheight = tdfx_cfg.screen_height; aspect_save_orig(width,height); aspect_save_prescale(d_width,d_height); aspect_save_screenres(vo_screenwidth,vo_screenheight); if(flags&VOFLAG_FULLSCREEN) { /* -fs */ aspect(&d_width,&d_height,A_ZOOM); vo_fs = VO_TRUE; } else { aspect(&d_width,&d_height,A_NOZOOM); vo_fs = VO_FALSE; } } src_width = width; src_height = height; buffer_size = 0; buffer_stride[0] = 0; src_fmt = 0; switch(format) { case IMGFMT_BGR8: case IMGFMT_BGR24: case IMGFMT_BGR32: if(use_overlay) mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_TDFXVID_NonNativeOverlayFormatNeedConversion); case IMGFMT_BGR15: case IMGFMT_BGR16: src_bpp = ((format & 0x3F)+7)/8; break; case IMGFMT_YV12: case IMGFMT_I420: buffer_size = src_width * src_height * 3 / 2; buffer_stride[0] = ((src_width+1)/2)*2; buffer_stride[1] = buffer_stride[2] = buffer_stride[0]/2; src_fmt = TDFX_VID_FORMAT_YUY2; case IMGFMT_YUY2: case IMGFMT_UYVY: src_bpp = 2; break; default: mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_TDFXVID_UnsupportedInputFormat,format); return 1; } img_fmt = format; src_stride = src_width*src_bpp; // The overlay need a 4 bytes aligned stride if(use_overlay) src_stride = ((src_stride+3)/4)*4; if(!src_fmt) src_fmt = format; if(!buffer_size) buffer_size = src_stride*src_height; if(!buffer_stride[0]) buffer_stride[0] = src_stride; dst_fmt = tdfx_cfg.screen_format; dst_bpp = ((dst_fmt & 0x3F)+7)/8; dst_width = d_width; dst_height = d_height; dst_stride = tdfx_cfg.screen_stride; tdfx_page = tdfx_cfg.screen_stride*tdfx_cfg.screen_height; front_buffer = tdfx_cfg.screen_start; back_buffer = front_buffer + tdfx_page; while(use_overlay) { tdfx_vid_overlay_t ov; uint32_t ov_fmt = src_fmt, ov_stride = src_stride; // Align the buffer back_buffer = (((back_buffer+3)/4)*4); // With the overlay the front buffer is not on the screen // so we take the back buffer front_buffer = back_buffer; switch(src_fmt) { case IMGFMT_BGR8: case IMGFMT_BGR24: case IMGFMT_BGR32: back_buffer = front_buffer + 2*(src_stride*src_height); ov_stride = dst_stride = src_width<<1; ov_fmt = IMGFMT_BGR16; break; } ov.src[0] = front_buffer; ov.src[1] = front_buffer + (src_stride*src_height); ov.src_width = src_width; ov.src_height = src_height; ov.src_stride = ov_stride; ov.format = ov_fmt; ov.dst_width = dst_width; ov.dst_height = dst_height; ov.dst_x = vo_dx; ov.dst_y = vo_dy; ov.use_colorkey = 0; if(ioctl(tdfx_fd,TDFX_VID_SET_OVERLAY,&ov)) { mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_TDFXVID_OverlaySetupFailed); use_overlay = 0; break; } tdfx_ov = ov; if(use_overlay == 1) { if(ioctl(tdfx_fd,TDFX_VID_OVERLAY_ON)) { mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_TDFXVID_OverlayOnFailed); use_overlay = 0; break; } use_overlay++; } mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_TDFXVID_OverlayReady, src_width,src_stride,src_height,src_bpp, dst_width,dst_stride,dst_height,dst_bpp); break; } if(!use_overlay) mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_TDFXVID_TextureBlitReady, src_width,src_stride,src_height,src_bpp, dst_width,dst_stride,dst_height,dst_bpp); return 0; }
static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t flags, char *title, uint32_t format) { screenwidth = fb_vinfo.xres; screenheight = fb_vinfo.yres; aspect_save_screenres(fb_vinfo.xres,fb_vinfo.yres); in_width = width; in_height = height; in_format = format; aspect_save_orig(width,height); r_width = d_width; r_height = d_height; aspect_save_prescale(d_width,d_height); /* Setup the screen for rendering to */ switch(fb_vinfo.bits_per_pixel) { case 16: screendepth = 2; vid_voodoo_format = VOODOO_BLT_FORMAT_16; alpha_func_double = vo_draw_alpha_rgb16; break; case 24: screendepth = 3; vid_voodoo_format = VOODOO_BLT_FORMAT_24; alpha_func_double = vo_draw_alpha_rgb24; break; case 32: screendepth = 4; vid_voodoo_format = VOODOO_BLT_FORMAT_32; alpha_func_double = vo_draw_alpha_rgb32; break; default: mp_msg(MSGT_VO, MSGL_ERR, MSGTR_LIBVO_TDFXFB_BppOutputIsNotSupported, fb_vinfo.bits_per_pixel); return -1; } vid_voodoo_format |= screenwidth * screendepth; /* Some defaults here */ in_voodoo_format = VOODOO_BLT_FORMAT_YUYV; in_depth = 2; alpha_func = vo_draw_alpha_yuy2; switch(in_format) { case IMGFMT_YV12: case IMGFMT_I420: case IMGFMT_IYUV: case IMGFMT_YUY2: break; case IMGFMT_UYVY: in_voodoo_format = VOODOO_BLT_FORMAT_UYVY; break; case IMGFMT_BGR16: in_voodoo_format = VOODOO_BLT_FORMAT_16; alpha_func = vo_draw_alpha_rgb16; break; case IMGFMT_BGR24: in_depth = 3; in_voodoo_format = VOODOO_BLT_FORMAT_24; alpha_func = vo_draw_alpha_rgb24; break; case IMGFMT_BGR32: in_depth = 4; in_voodoo_format = VOODOO_BLT_FORMAT_32; alpha_func = vo_draw_alpha_rgb32; break; default: mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_TDFXFB_SomethingIsWrongWithControl); return -1; } in_voodoo_format |= in_width * in_depth; /* Linux lives in the first frame */ if(vo_doublebuffering) { vidpageoffset = screenwidth * screenheight * screendepth; hidpageoffset = vidpageoffset + screenwidth * screenheight * screendepth; } else vidpageoffset = hidpageoffset = 0; /* Console background */ inpageoffset = hidpageoffset + screenwidth * screenheight * screendepth; if(inpageoffset + in_width * in_depth * in_height > fb_finfo.smem_len) { mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_TDFXFB_NotEnoughVideoMemoryToPlay); return -1; } vidpage = (void *)memBase1 + (unsigned long)vidpageoffset; hidpage = (void *)memBase1 + (unsigned long)hidpageoffset; inpage = (void *)memBase1 + (unsigned long)inpageoffset; setup_screen(flags & VOFLAG_FULLSCREEN); memset(inpage, 0, in_width * in_height * in_depth); mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_TDFXFB_ScreenIs, screenwidth, screenheight, screendepth * 8, in_width, in_height, in_depth * 8, d_width, d_height); return 0; }
static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t flags, char *title, uint32_t format) { screenwidth = fb_vinfo.xres; screenheight = fb_vinfo.yres; screenstride = fb_finfo.line_length; aspect_save_screenres(fb_vinfo.xres,fb_vinfo.yres); in_width = width; in_height = height; in_format = format; aspect_save_orig(width,height); aspect_save_prescale(d_width,d_height); /* Setup the screen for rendering to */ screendepth = fb_vinfo.bits_per_pixel / 8; switch(in_format) { case IMGFMT_YUY2: in_depth = 2; in_s3_format = 1; alpha_func = vo_draw_alpha_yuy2; break; case IMGFMT_BGR15: in_depth = 2; in_s3_format = 3; alpha_func = vo_draw_alpha_rgb16; break; case IMGFMT_BGR16: in_depth = 2; in_s3_format = 5; alpha_func = vo_draw_alpha_rgb16; break; case IMGFMT_BGR24: in_depth = 3; in_s3_format = 6; alpha_func = vo_draw_alpha_rgb24; break; case IMGFMT_BGR32: in_depth = 4; in_s3_format = 7; alpha_func = vo_draw_alpha_rgb32; break; default: mp_msg(MSGT_VO, MSGL_FATAL, "s3fb: Eik! Something's wrong with control().\n"); return -1; } offset = in_width * in_depth * in_height; if (vo_doublebuffering) page = offset; else page = 0; if(screenheight * screenstride + page + offset > fb_finfo.smem_len) { mp_msg(MSGT_VO, MSGL_FATAL, "s3fb: Not enough video memory to play this movie. Try at a lower resolution\n"); return -1; } setup_screen(flags & VOFLAG_FULLSCREEN); if (vo_doublebuffering) inpage = inpage0 + page; mp_msg(MSGT_VO, MSGL_INFO, "s3fb: screen is %dx%d at %d bpp, in is %dx%d at %d bpp, norm is %dx%d\n", screenwidth, screenheight, screendepth * 8, in_width, in_height, in_depth * 8, d_width, d_height); return 0; }
static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t flags, char *title, uint32_t format) { struct fb_cmap *cmap; int vm = flags & VOFLAG_MODESWITCHING; int zoom = flags & VOFLAG_SWSCALE; int vt_fd; fs = flags & VOFLAG_FULLSCREEN; if(pre_init_err == -2) { mp_msg(MSGT_VO, MSGL_ERR, "Internal fatal error: config() was called before preinit()\n"); return -1; } if (pre_init_err) return 1; if (fb_mode_name && !vm) { mp_msg(MSGT_VO, MSGL_ERR, "-fbmode can only be used with -vm\n"); return 1; } if (vm && (parse_fbmode_cfg(fb_mode_cfgfile) < 0)) return 1; if (d_width && (fs || vm)) { out_width = d_width; out_height = d_height; } else { out_width = width; out_height = height; } in_width = width; in_height = height; pixel_format = format; if (fb_mode_name) { if (!(fb_mode = find_mode_by_name(fb_mode_name))) { mp_msg(MSGT_VO, MSGL_ERR, "can't find requested video mode\n"); return 1; } fb_mode2fb_vinfo(fb_mode, &fb_vinfo); } else if (vm) { monitor_hfreq = str2range(monitor_hfreq_str); monitor_vfreq = str2range(monitor_vfreq_str); monitor_dotclock = str2range(monitor_dotclock_str); if (!monitor_hfreq || !monitor_vfreq || !monitor_dotclock) { mp_msg(MSGT_VO, MSGL_ERR, "you have to specify the capabilities of" " the monitor.\n"); return 1; } if (!(fb_mode = find_best_mode(out_width, out_height, monitor_hfreq, monitor_vfreq, monitor_dotclock))) { mp_msg(MSGT_VO, MSGL_ERR, "can't find best video mode\n"); return 1; } mp_msg(MSGT_VO, MSGL_V, "using mode %dx%d @ %.1fHz\n", fb_mode->xres, fb_mode->yres, vsf(fb_mode)); fb_mode2fb_vinfo(fb_mode, &fb_vinfo); } fb_bpp_we_want = fb_bpp; set_bpp(&fb_vinfo, fb_bpp); fb_vinfo.xres_virtual = fb_vinfo.xres; fb_vinfo.yres_virtual = fb_vinfo.yres; if (fb_tty_fd >= 0 && ioctl(fb_tty_fd, KDSETMODE, KD_GRAPHICS) < 0) { mp_msg(MSGT_VO, MSGL_V, "Can't set graphics mode: %s\n", strerror(errno)); close(fb_tty_fd); fb_tty_fd = -1; } if (ioctl(fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_vinfo)) { mp_msg(MSGT_VO, MSGL_ERR, "Can't put VSCREENINFO: %s\n", strerror(errno)); if (fb_tty_fd >= 0 && ioctl(fb_tty_fd, KDSETMODE, KD_TEXT) < 0) { mp_msg(MSGT_VO, MSGL_ERR, "Can't restore text mode: %s\n", strerror(errno)); } return 1; } fb_pixel_size = fb_vinfo.bits_per_pixel / 8; fb_bpp = fb_vinfo.red.length + fb_vinfo.green.length + fb_vinfo.blue.length + fb_vinfo.transp.length; if (fb_bpp_we_want != fb_bpp) mp_msg(MSGT_VO, MSGL_WARN, "requested %d bpp, got %d bpp!!!\n", fb_bpp_we_want, fb_bpp); switch (fb_bpp) { case 32: draw_alpha_p = vo_draw_alpha_rgb32; break; case 24: draw_alpha_p = vo_draw_alpha_rgb24; break; case 16: draw_alpha_p = vo_draw_alpha_rgb16; break; case 15: draw_alpha_p = vo_draw_alpha_rgb15; break; default: return 1; } fb_xres = fb_vinfo.xres; fb_yres = fb_vinfo.yres; if (vm || fs) { out_width = fb_xres; out_height = fb_yres; } if (out_width < in_width || out_height < in_height) { mp_msg(MSGT_VO, MSGL_ERR, "screensize is smaller than video size\n"); return 1; } first_row = (out_height - in_height) / 2; last_row = (out_height + in_height) / 2; if (ioctl(fb_dev_fd, FBIOGET_FSCREENINFO, &fb_finfo)) { mp_msg(MSGT_VO, MSGL_ERR, "Can't get FSCREENINFO: %s\n", strerror(errno)); return 1; } lots_of_printf(); if (fb_finfo.type != FB_TYPE_PACKED_PIXELS) { mp_msg(MSGT_VO, MSGL_ERR, "type %d not supported\n", fb_finfo.type); return 1; } switch (fb_finfo.visual) { case FB_VISUAL_TRUECOLOR: break; case FB_VISUAL_DIRECTCOLOR: mp_msg(MSGT_VO, MSGL_V, "creating cmap for directcolor\n"); if (ioctl(fb_dev_fd, FBIOGETCMAP, &fb_oldcmap)) { mp_msg(MSGT_VO, MSGL_ERR, "can't get cmap: %s\n", strerror(errno)); return 1; } if (!(cmap = make_directcolor_cmap(&fb_vinfo))) return 1; if (ioctl(fb_dev_fd, FBIOPUTCMAP, cmap)) { mp_msg(MSGT_VO, MSGL_ERR, "can't put cmap: %s\n", strerror(errno)); return 1; } fb_cmap_changed = 1; free(cmap->red); free(cmap->green); free(cmap->blue); free(cmap); break; default: mp_msg(MSGT_VO, MSGL_ERR, "visual: %d not yet supported\n", fb_finfo.visual); return 1; } fb_line_len = fb_finfo.line_length; fb_size = fb_finfo.smem_len; frame_buffer = NULL; #ifdef CONFIG_VIDIX if(vidix_name) { unsigned image_width,image_height,x_offset,y_offset; if(zoom || fs){ aspect_save_orig(width,height); aspect_save_prescale(d_width,d_height); aspect_save_screenres(fb_xres,fb_yres); aspect(&image_width,&image_height,fs ? A_ZOOM : A_NOZOOM); } else { image_width=width; image_height=height; } if(fb_xres > image_width) x_offset = (fb_xres - image_width) / 2; else x_offset = 0; if(fb_yres > image_height) y_offset = (fb_yres - image_height) / 2; else y_offset = 0; if(vidix_init(width,height,x_offset,y_offset,image_width, image_height,format,fb_bpp, fb_xres,fb_yres) != 0) { mp_msg(MSGT_VO, MSGL_ERR, "Can't initialize VIDIX driver\n"); vidix_name = NULL; vidix_term(); return -1; } else mp_msg(MSGT_VO, MSGL_V, "Using VIDIX\n"); vidix_start(); if (vidix_grkey_support()) { vidix_grkey_get(&gr_key); gr_key.key_op = KEYS_PUT; if (!(vo_colorkey & 0xff000000)) { gr_key.ckey.op = CKEY_TRUE; gr_key.ckey.red = (vo_colorkey & 0x00ff0000) >> 16; gr_key.ckey.green = (vo_colorkey & 0x0000ff00) >> 8; gr_key.ckey.blue = vo_colorkey & 0x000000ff; } else gr_key.ckey.op = CKEY_FALSE; vidix_grkey_set(&gr_key); }
static int control(uint32_t request, void *data, ...) { switch (request) { case VOCTRL_QUERY_FORMAT: return query_format(*((uint32_t*)data)); case VOCTRL_GET_IMAGE: return get_image(data); case VOCTRL_DRAW_IMAGE: return draw_image(data); case VOCTRL_SET_EQUALIZER: { va_list ap; short value; uint32_t luma,prev; if ( strcmp( data,"brightness" ) && strcmp( data,"contrast" ) ) return VO_FALSE; if (ioctl(f,MGA_VID_GET_LUMA,&prev)) { perror("Error in mga_vid_config ioctl()"); mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_MGA_CouldNotGetLumaValuesFromTheKernelModule); return VO_FALSE; } // printf("GET: 0x%4X 0x%4X \n",(prev>>16),(prev&0xffff)); va_start(ap, data); value = va_arg(ap, int); va_end(ap); // printf("value: %d -> ",value); value=((value+100)*255)/200-128; // maps -100=>-128 and +100=>127 // printf("%d \n",value); if(!strcmp(data,"contrast")) luma = (prev&0xFFFF0000)|(value&0xFFFF); else luma = (prev&0xFFFF)|(value<<16); if (ioctl(f,MGA_VID_SET_LUMA,luma)) { perror("Error in mga_vid_config ioctl()"); mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_MGA_CouldNotSetLumaValuesFromTheKernelModule); return VO_FALSE; } return VO_TRUE; } case VOCTRL_GET_EQUALIZER: { va_list ap; int * value; short val; uint32_t luma; if ( strcmp( data,"brightness" ) && strcmp( data,"contrast" ) ) return VO_FALSE; if (ioctl(f,MGA_VID_GET_LUMA,&luma)) { perror("Error in mga_vid_config ioctl()"); mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_MGA_CouldNotGetLumaValuesFromTheKernelModule); return VO_FALSE; } if ( !strcmp( data,"contrast" ) ) val=(luma & 0xFFFF); else val=(luma >> 16); va_start(ap, data); value = va_arg(ap, int*); va_end(ap); *value = (val*200)/255; return VO_TRUE; } #ifndef VO_XMGA case VOCTRL_FULLSCREEN: if (vo_screenwidth && vo_screenheight) mga_fullscreen(); else mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_MGA_ScreenWidthHeightUnknown); return VO_TRUE; case VOCTRL_GET_PANSCAN: if ( !vo_fs ) return VO_FALSE; return VO_TRUE; #endif #if defined(VO_XMGA) && defined(CONFIG_GUI) case VOCTRL_GUISUPPORT: return VO_TRUE; #endif #ifdef VO_XMGA case VOCTRL_ONTOP: vo_x11_ontop(); return VO_TRUE; case VOCTRL_GET_PANSCAN: if ( !initialized || !vo_fs ) return VO_FALSE; return VO_TRUE; case VOCTRL_FULLSCREEN: vo_x11_fullscreen(); vo_panscan_amount=0; /* intended, fallthrough to update panscan on fullscreen/windowed switch */ #endif case VOCTRL_SET_PANSCAN: if ( vo_fs && ( vo_panscan != vo_panscan_amount ) ) // || ( !vo_fs && vo_panscan_amount ) ) { // int old_y = vo_panscan_y; panscan_calc(); // if ( old_y != vo_panscan_y ) set_window(); } return VO_TRUE; case VOCTRL_UPDATE_SCREENINFO: #ifdef VO_XMGA update_xinerama_info(); #else aspect_save_screenres(vo_screenwidth, vo_screenheight); #endif return VO_TRUE; } return VO_NOTIMPL; }