vo_dga.c

来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 989 行 · 第 1/3 页

C
989
字号
static void switch_video_buffers(void){    vo_dga_current_video_buffer =        (vo_dga_current_video_buffer + 1) % vo_dga_nr_video_buffers;}static void flip_page(void){    if (1 < vo_dga_nr_video_buffers)    {#ifdef HAVE_DGA2        XDGASetViewport(mDisplay, mScreen,                        0, CURRENT_VIDEO_BUFFER.y, XDGAFlipRetrace);#else        XF86DGASetViewPort(mDisplay, mScreen, 0, CURRENT_VIDEO_BUFFER.y);#endif        switch_video_buffers();    }}//---------------------------------------------------------static int draw_slice(uint8_t * src[], int stride[],                           int w, int h, int x, int y){    return 0;};//---------------------------------------------------------static int query_format(uint32_t format){    if ((format & IMGFMT_BGR_MASK) == IMGFMT_BGR &&        vd_ModeValid(format & 0xff))    {        return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_OSD;    }    return 0;}//---------------------------------------------------------static void uninit(void){#ifdef HAVE_DGA2    XDGADevice *dgadevice;#endif    if (!vo_config_count)        return;    if (vo_dga_is_running)    {        vo_dga_is_running = 0;        mp_msg(MSGT_VO, MSGL_V, "vo_dga: in uninit\n");        if (vo_grabpointer)            XUngrabPointer(mDisplay, CurrentTime);        XUngrabKeyboard(mDisplay, CurrentTime);#ifdef HAVE_DGA2        XDGACloseFramebuffer(mDisplay, mScreen);        dgadevice = XDGASetMode(mDisplay, mScreen, 0);        if (dgadevice != NULL)        {            XFree(dgadevice);        }#else        XF86DGADirectVideo(mDisplay, mScreen, 0);        // first disable DirectVideo and then switch mode back!     #ifdef HAVE_XF86VM        if (vo_dga_vidmodes != NULL)        {            int screen;            screen = XDefaultScreen(mDisplay);            mp_msg(MSGT_VO, MSGL_V,                   "vo_dga: VidModeExt: Switching back..\n");            // seems some graphics adaptors need this more than once ...            XF86VidModeSwitchToMode(mDisplay, screen, vo_dga_vidmodes[0]);            XF86VidModeSwitchToMode(mDisplay, screen, vo_dga_vidmodes[0]);            XF86VidModeSwitchToMode(mDisplay, screen, vo_dga_vidmodes[0]);            XF86VidModeSwitchToMode(mDisplay, screen, vo_dga_vidmodes[0]);            XFree(vo_dga_vidmodes);        }#endif#endif    }    vo_x11_uninit();}//----------------------------------------------------------// TODO: check for larger maxy value // (useful for double buffering!!!)static int check_res(int num, int x, int y, int bpp,                     int new_x, int new_y, int new_vbi, int new_maxy,                     int *old_x, int *old_y, int *old_vbi, int *old_maxy){    mp_msg(MSGT_VO, MSGL_V,           "vo_dga: (%3d) Trying %4d x %4d @ %3d Hz @ depth %2d ..", num,           new_x, new_y, new_vbi, bpp);    mp_msg(MSGT_VO, MSGL_V, "(old: %dx%d@%d).", *old_x, *old_y, *old_vbi);    if ((new_x >= x) && (new_y >= y) && (                                            // prefer a better resolution either in X or in Y                                            // as long as the other dimension is at least the same                                            //                                             // hmm ... MAYBE it would be more clever to focus on the                                             // x-resolution; I had 712x400 and 640x480 and the movie                                             // was 640x360; 640x480 would be the 'right thing' here                                            // but since 712x400 was queried first I got this one.                                             // I think there should be a cmd-line switch to let the                                            // user choose the mode he likes ...   (acki2)                                            (((new_x < *old_x) &&                                              !(new_y > *old_y)) ||                                             ((new_y < *old_y) &&                                              !(new_x > *old_x)))                                            // but if we get an identical resolution choose                                            // the one with the lower refreshrate (saves bandwidth !!!)                                            // as long as it's above 50 Hz (acki2 on 30/3/2001)                                            ||                                            (((new_x == *old_x) &&                                              (new_y == *old_y) &&                                              ((new_vbi >= *old_vbi                                                && *old_vbi < 50)                                               || (*old_vbi >= 50                                                   && new_vbi < *old_vbi                                                   && new_vbi >= 50))) ||                                             // if everything is equal, then use the mode with the lower                                              // stride                                              ((new_x == *old_x) &&                                              (new_y == *old_y) &&                                              (new_vbi == *old_vbi) &&                                              (new_maxy > *old_maxy)))))    {        *old_x = new_x;        *old_y = new_y;        *old_maxy = new_maxy;        *old_vbi = new_vbi;        mp_msg(MSGT_VO, MSGL_V, ".ok!!\n");        return 1;    } else    {        mp_msg(MSGT_VO, MSGL_V, ".no\n");        return 0;    }}//---------------------------------------------------------static void init_video_buffers(uint8_t * buffer_base,                               int view_port_height,                               int bytes_per_scanline,                               int max_view_port_y,                               int use_multiple_buffers){    int bytes_per_buffer = view_port_height * bytes_per_scanline;    int i;    if (use_multiple_buffers)        vo_dga_nr_video_buffers = max_view_port_y / view_port_height;    else        vo_dga_nr_video_buffers = 1;    if (vo_dga_nr_video_buffers > MAX_NR_VIDEO_BUFFERS)        vo_dga_nr_video_buffers = MAX_NR_VIDEO_BUFFERS;    if (vo_dga_nr_video_buffers <= 0)        vo_dga_nr_video_buffers = 1;    vo_dga_current_video_buffer = 0;    for (i = 0; i < vo_dga_nr_video_buffers; i++)    {        vo_dga_video_buffer[i].y = i * view_port_height;        vo_dga_video_buffer[i].data = buffer_base + i * bytes_per_buffer;        // Clear video buffer.        memset(vo_dga_video_buffer[i].data, 0, bytes_per_buffer);    }}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// mgraffam@idsi.net    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");

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?