vo_dga.c
来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 989 行 · 第 1/3 页
C
989 行
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 dga_depths_init = 0;static int preinit(const char *arg){ if (arg) { mp_msg(MSGT_VO, MSGL_INFO, "vo_dga: Unknown subdevice: %s\n", arg); return ENOSYS; } if (!vo_init()) return -1; // Can't open X11 if (dga_depths_init == 0) { // FIXME!? int i; vo_dga_XServer_mode = vd_ValidateMode(vo_depthonscreen); if (vo_dga_XServer_mode == 0) {#ifndef HAVE_DGA2 mp_msg(MSGT_VO, MSGL_ERR, "vo_dga: Your X-Server is not running in a "); mp_msg(MSGT_VO, MSGL_ERR, "resolution supported by DGA driver!\n");#endif } //else{ // mp_msg(MSGT_VO, MSGL_V, "vo_dga: X running at: %s\n", // vd_GetModeString(vo_dga_XServer_mode)); //} #ifdef HAVE_DGA2 vo_modelines = XDGAQueryModes(mDisplay, mScreen, &vo_modecount); if (vo_modelines) { for (i = 0; i < vo_modecount; i++) { mp_msg(MSGT_VO, MSGL_V, "vo_dga: (%03d) depth=%d, bpp=%d, r=%08lx, g=%08lx, b=%08lx, %d x %d\n", i, vo_modelines[i].depth, vo_modelines[i].bitsPerPixel, vo_modelines[i].redMask, vo_modelines[i].greenMask, vo_modelines[i].blueMask, vo_modelines[i].viewportWidth, vo_modelines[i].viewportHeight); vd_EnableMode(vo_modelines[i].depth, vo_modelines[i].bitsPerPixel, vo_modelines[i].redMask, vo_modelines[i].greenMask, vo_modelines[i].blueMask); } }#endif dga_depths_init = 1; if (!vo_dga_modes[1].vdm_supported && vo_dga_modes[2].vdm_supported) { vo_dga_modes[1].vdm_supported = 1; } if (!vo_dga_modes[3].vdm_supported && vo_dga_modes[4].vdm_supported) { vo_dga_modes[3].vdm_supported = 1; } for (i = 1; i < vo_dga_mode_num; i++) { mp_msg(MSGT_VO, MSGL_INFO, "vo_dga: Mode: %s", vd_GetModeString(i)); if (vo_dbpp && vo_dbpp != vo_dga_modes[i].vdm_mplayer_depth) { vo_dga_modes[i].vdm_supported = 0; mp_msg(MSGT_VO, MSGL_INFO, " ...disabled by -bpp %d", vo_dbpp); } mp_msg(MSGT_VO, MSGL_INFO, "\n"); } } return 0;}static uint32_t get_image(mp_image_t * mpi){ if (!IMGFMT_IS_BGR(mpi->imgfmt) || (IMGFMT_BGR_DEPTH(mpi->imgfmt) != vo_dga_modes[vo_dga_hw_mode].vdm_mplayer_depth) || (mpi->type == MP_IMGTYPE_STATIC && vo_dga_nr_video_buffers > 1) || (mpi->type == MP_IMGTYPE_IP && vo_dga_nr_video_buffers < 2) || (mpi->type == MP_IMGTYPE_IPB)) return (VO_FALSE); if ((mpi->flags & MP_IMGFLAG_ACCEPT_STRIDE) || (mpi->flags & MP_IMGFLAG_ACCEPT_WIDTH && ((vo_dga_bytes_per_line + vo_dga_vp_skip) % (mpi->bpp / 8)) == 0) || (mpi->width * (mpi->bpp / 8) == (vo_dga_bytes_per_line + vo_dga_vp_skip))) { mpi->planes[0] = CURRENT_VIDEO_BUFFER.data + vo_dga_vp_offset; mpi->stride[0] = vo_dga_bytes_per_line + vo_dga_vp_skip; mpi->width = (vo_dga_bytes_per_line + vo_dga_vp_skip) / (mpi->bpp / 8); mpi->flags |= MP_IMGFLAG_DIRECT; return (VO_TRUE); } return (VO_FALSE);}static int control(uint32_t request, void *data, ...){ switch (request) { case VOCTRL_GET_IMAGE: return get_image(data); case VOCTRL_QUERY_FORMAT: return query_format(*((uint32_t *) data)); } return VO_NOTIMPL;}//---------------------------------------------------------
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?