vo_xv.c

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

C
920
字号
/* vo_xv.c, X11 Xv interface */// Number of buffers _FOR_DOUBLEBUFFERING_MODE_// Use option -double to enable double buffering! (default: single buffer)#define NUM_BUFFERS 3/*Buffer allocation:-nodr:  1: TEMP  2: 2*TEMP-dr:  1: TEMP  3: 2*STATIC+TEMP*/#include <mplaylib.h>#include <mplaylib.h>#include <mplaylib.h>#include "config.h"#include "mp_msg.h"#include "help_mp.h"#include "video_out.h"#include "video_out_internal.h"#include <X11/Xlib.h>#include <X11/Xutil.h>#include <errno.h>#include "x11_common.h"#include "fastmemcpy.h"#include "sub.h"#include "aspect.h"#include "subopt-helper.h"#include "input/input.h"#ifdef HAVE_NEW_GUI#include "gui/interface.h"#endif#include "libavutil/common.h"static vo_info_t info = {    "X11/Xv",    "xv",    "Gerd Knorr <kraxel@goldbach.in-berlin.de> and others",    ""};LIBVO_EXTERN(xv)#ifdef HAVE_SHM#include <sys/ipc.h>#include <sys/shm.h>#include <X11/extensions/XShm.h>static XShmSegmentInfo Shminfo[NUM_BUFFERS];static int Shmem_Flag;#endif// Note: depends on the inclusion of X11/extensions/XShm.h#include <X11/extensions/Xv.h>#include <X11/extensions/Xvlib.h>// FIXME: dynamically allocate this stuffstatic void allocate_xvimage(int);static unsigned int ver, rel, req, ev, err;static unsigned int formats, adaptors, xv_format;static XvAdaptorInfo *ai = NULL;static XvImageFormatValues *fo=NULL;static int current_buf = 0;static int current_ip_buf = 0;static int num_buffers = 1;     // defaultstatic int visible_buf = -1;    // -1 means: no buffer was drawn yetstatic XvImage *xvimage[NUM_BUFFERS];static uint32_t image_width;static uint32_t image_height;static uint32_t image_format;static int flip_flag;static int int_pause;static Window mRoot;static uint32_t drwX, drwY, drwBorderWidth, drwDepth;static uint32_t max_width = 0, max_height = 0; // zero means: not setstatic void (*draw_alpha_fnc) (int x0, int y0, int w, int h,                               unsigned char *src, unsigned char *srca,                               int stride);static void draw_alpha_yv12(int x0, int y0, int w, int h,                            unsigned char *src, unsigned char *srca,                            int stride){    x0 += image_width * (vo_panscan_x >> 1) / (vo_dwidth + vo_panscan_x);    vo_draw_alpha_yv12(w, h, src, srca, stride,                       xvimage[current_buf]->data +                       xvimage[current_buf]->offsets[0] +                       xvimage[current_buf]->pitches[0] * y0 + x0,                       xvimage[current_buf]->pitches[0]);}static void draw_alpha_yuy2(int x0, int y0, int w, int h,                            unsigned char *src, unsigned char *srca,                            int stride){    x0 += image_width * (vo_panscan_x >> 1) / (vo_dwidth + vo_panscan_x);    vo_draw_alpha_yuy2(w, h, src, srca, stride,                       xvimage[current_buf]->data +                       xvimage[current_buf]->offsets[0] +                       xvimage[current_buf]->pitches[0] * y0 + 2 * x0,                       xvimage[current_buf]->pitches[0]);}static void draw_alpha_uyvy(int x0, int y0, int w, int h,                            unsigned char *src, unsigned char *srca,                            int stride){    x0 += image_width * (vo_panscan_x >> 1) / (vo_dwidth + vo_panscan_x);    vo_draw_alpha_yuy2(w, h, src, srca, stride,                       xvimage[current_buf]->data +                       xvimage[current_buf]->offsets[0] +                       xvimage[current_buf]->pitches[0] * y0 + 2 * x0 + 1,                       xvimage[current_buf]->pitches[0]);}static void draw_alpha_null(int x0, int y0, int w, int h,                            unsigned char *src, unsigned char *srca,                            int stride){}static void deallocate_xvimage(int foo);static void calc_drwXY(uint32_t *drwX, uint32_t *drwY) {  *drwX = *drwY = 0;  if (vo_fs) {    aspect(&vo_dwidth, &vo_dheight, A_ZOOM);    vo_dwidth = FFMIN(vo_dwidth, vo_screenwidth);    vo_dheight = FFMIN(vo_dheight, vo_screenheight);    *drwX = (vo_screenwidth - vo_dwidth) / 2;    *drwY = (vo_screenheight - vo_dheight) / 2;    mp_msg(MSGT_VO, MSGL_V, "[xv-fs] dx: %d dy: %d dw: %d dh: %d\n",           *drwX, *drwY, vo_dwidth, vo_dheight);  } else if (WinID == 0) {    *drwX = vo_dx;    *drwY = vo_dy;  }}/* * connect to server, create and map window, * allocate colors and (shared) memory */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){    XSizeHints hint;    XVisualInfo vinfo;    XGCValues xgcv;    XSetWindowAttributes xswa;    XWindowAttributes attribs;    unsigned long xswamask;    int depth;#ifdef HAVE_XF86VM    int vm = 0;    unsigned int modeline_width, modeline_height;    static uint32_t vm_width;    static uint32_t vm_height;#endif    image_height = height;    image_width = width;    image_format = format;    if ((max_width != 0 && max_height != 0) &&        (image_width > max_width || image_height > max_height))    {        mp_msg( MSGT_VO, MSGL_ERR, MSGTR_VO_XV_ImagedimTooHigh,                image_width, image_height, max_width, max_height);        return -1;    }    vo_mouse_autohide = 1;    int_pause = 0;    visible_buf = -1;#ifdef HAVE_XF86VM    if (flags & VOFLAG_MODESWITCHING)        vm = 1;#endif    flip_flag = flags & VOFLAG_FLIPPING;    num_buffers =        vo_doublebuffering ? (vo_directrendering ? NUM_BUFFERS : 2) : 1;    /* check image formats */    {        unsigned int i;        xv_format = 0;        for (i = 0; i < formats; i++)        {            mp_msg(MSGT_VO, MSGL_V,                   "Xvideo image format: 0x%x (%4.4s) %s\n", fo[i].id,                   (char *) &fo[i].id,                   (fo[i].format == XvPacked) ? "packed" : "planar");            if (fo[i].id == format)                xv_format = fo[i].id;        }        if (!xv_format)            return -1;    }#ifdef HAVE_NEW_GUI    if (use_gui)        guiGetEvent(guiSetShVideo, 0);  // let the GUI to setup/resize our window    else#endif    {        hint.x = vo_dx;        hint.y = vo_dy;        hint.width = d_width;        hint.height = d_height;#ifdef HAVE_XF86VM        if (vm)        {            if ((d_width == 0) && (d_height == 0))            {                vm_width = image_width;                vm_height = image_height;            } else            {                vm_width = d_width;                vm_height = d_height;            }            vo_vm_switch(vm_width, vm_height, &modeline_width,                         &modeline_height);            hint.x = (vo_screenwidth - modeline_width) / 2;            hint.y = (vo_screenheight - modeline_height) / 2;            hint.width = modeline_width;            hint.height = modeline_height;            aspect_save_screenres(modeline_width, modeline_height);        } else#endif        hint.flags = PPosition | PSize /* | PBaseSize */ ;        hint.base_width = hint.width;        hint.base_height = hint.height;        XGetWindowAttributes(mDisplay, DefaultRootWindow(mDisplay),                             &attribs);        depth = attribs.depth;        if (depth != 15 && depth != 16 && depth != 24 && depth != 32)            depth = 24;        XMatchVisualInfo(mDisplay, mScreen, depth, TrueColor, &vinfo);        xswa.background_pixel = 0;        if (xv_ck_info.method == CK_METHOD_BACKGROUND)        {          xswa.background_pixel = xv_colorkey;        }        xswa.border_pixel = 0;        xswamask = CWBackPixel | CWBorderPixel;        if (WinID >= 0)        {            vo_window = WinID ? ((Window) WinID) : mRootWin;            if (WinID)            {                XUnmapWindow(mDisplay, vo_window);                XChangeWindowAttributes(mDisplay, vo_window, xswamask,                                        &xswa);                vo_x11_selectinput_witherr(mDisplay, vo_window,                                           StructureNotifyMask |                                           KeyPressMask |                                           PropertyChangeMask |                                           PointerMotionMask |                                           ButtonPressMask |                                           ButtonReleaseMask |                                           ExposureMask);                XMapWindow(mDisplay, vo_window);                XGetGeometry(mDisplay, vo_window, &mRoot,                             &drwX, &drwY, &vo_dwidth, &vo_dheight,                             &drwBorderWidth, &drwDepth);                if (vo_dwidth <= 0) vo_dwidth = d_width;                if (vo_dheight <= 0) vo_dheight = d_height;                aspect_save_prescale(vo_dwidth, vo_dheight);            }        } else        {            vo_x11_create_vo_window(&vinfo, vo_dx, vo_dy, d_width, d_height,                   flags, CopyFromParent, "xv", title);            XChangeWindowAttributes(mDisplay, vo_window, xswamask, &xswa);        }        if (vo_gc != None)            XFreeGC(mDisplay, vo_gc);        vo_gc = XCreateGC(mDisplay, vo_window, 0L, &xgcv);        XSync(mDisplay, False);#ifdef HAVE_XF86VM        if (vm)        {            /* Grab the mouse pointer in our window */            if (vo_grabpointer)                XGrabPointer(mDisplay, vo_window, True, 0,                             GrabModeAsync, GrabModeAsync,                             vo_window, None, CurrentTime);            XSetInputFocus(mDisplay, vo_window, RevertToNone, CurrentTime);        }#endif    }    mp_msg(MSGT_VO, MSGL_V, "using Xvideo port %d for hw scaling\n",           xv_port);    switch (xv_format)    {        case IMGFMT_YV12:        case IMGFMT_I420:        case IMGFMT_IYUV:            draw_alpha_fnc = draw_alpha_yv12;            break;        case IMGFMT_YUY2:        case IMGFMT_YVYU:            draw_alpha_fnc = draw_alpha_yuy2;            break;        case IMGFMT_UYVY:            draw_alpha_fnc = draw_alpha_uyvy;            break;        default:            draw_alpha_fnc = draw_alpha_null;    }    if (vo_config_count)        for (current_buf = 0; current_buf < num_buffers; ++current_buf)            deallocate_xvimage(current_buf);    for (current_buf = 0; current_buf < num_buffers; ++current_buf)        allocate_xvimage(current_buf);    current_buf = 0;    current_ip_buf = 0;#if 0    set_gamma_correction();#endif    aspect(&vo_dwidth, &vo_dheight, A_NOZOOM);    if ((flags & VOFLAG_FULLSCREEN) && WinID <= 0) vo_fs = 1;    calc_drwXY(&drwX, &drwY);    panscan_calc();        vo_xv_draw_colorkey(drwX - (vo_panscan_x >> 1),                        drwY - (vo_panscan_y >> 1),                        vo_dwidth + vo_panscan_x - 1,                        vo_dheight + vo_panscan_y - 1);#if 0#ifdef HAVE_SHM    if (Shmem_Flag)    {        XvShmPutImage(mDisplay, xv_port, vo_window, vo_gc,                      xvimage[current_buf], 0, 0, image_width,                      image_height, drwX, drwY, 1, 1, False);        XvShmPutImage(mDisplay, xv_port, vo_window, vo_gc,                      xvimage[current_buf], 0, 0, image_width,                      image_height, drwX, drwY, vo_dwidth,                      (vo_fs ? vo_dheight - 1 : vo_dheight), False);    } else#endif    {        XvPutImage(mDisplay, xv_port, vo_window, vo_gc,                   xvimage[current_buf], 0, 0, image_width, image_height,                   drwX, drwY, 1, 1);        XvPutImage(mDisplay, xv_port, vo_window, vo_gc,                   xvimage[current_buf], 0, 0, image_width, image_height,                   drwX, drwY, vo_dwidth,                   (vo_fs ? vo_dheight - 1 : vo_dheight));    }#endif    mp_msg(MSGT_VO, MSGL_V, "[xv] dx: %d dy: %d dw: %d dh: %d\n", drwX,           drwY, vo_dwidth, vo_dheight);    if (vo_ontop)        vo_x11_setlayer(mDisplay, vo_window, vo_ontop);    return 0;}static void allocate_xvimage(int foo){    /*     * allocate XvImages.  FIXME: no error checking, without     * mit-shm this will bomb... trzing to fix ::atmos     */#ifdef HAVE_SHM    if (mLocalDisplay && XShmQueryExtension(mDisplay))        Shmem_Flag = 1;    else    {        Shmem_Flag = 0;        mp_msg(MSGT_VO, MSGL_INFO,               MSGTR_LIBVO_XV_SharedMemoryNotSupported);    }    if (Shmem_Flag)    {        xvimage[foo] =            (XvImage *) XvShmCreateImage(mDisplay, xv_port, xv_format,                                         NULL, image_width, image_height,                                         &Shminfo[foo]);        Shminfo[foo].shmid =            shmget(IPC_PRIVATE, xvimage[foo]->data_size, IPC_CREAT | 0777);        Shminfo[foo].shmaddr = (char *) shmat(Shminfo[foo].shmid, 0, 0);        Shminfo[foo].readOnly = False;        xvimage[foo]->data = Shminfo[foo].shmaddr;        XShmAttach(mDisplay, &Shminfo[foo]);        XSync(mDisplay, False);        shmctl(Shminfo[foo].shmid, IPC_RMID, 0);    } else#endif    {        xvimage[foo] =            (XvImage *) XvCreateImage(mDisplay, xv_port, xv_format, NULL,                                      image_width, image_height);        xvimage[foo]->data = malloc(xvimage[foo]->data_size);        XSync(mDisplay, False);    }    memset(xvimage[foo]->data, 128, xvimage[foo]->data_size);    return;}static void deallocate_xvimage(int foo){#ifdef HAVE_SHM    if (Shmem_Flag)    {        XShmDetach(mDisplay, &Shminfo[foo]);        shmdt(Shminfo[foo].shmaddr);    } else#endif    {        free(xvimage[foo]->data);    }    XFree(xvimage[foo]);

⌨️ 快捷键说明

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