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 + -
显示快捷键?