vo_xv.c

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

C
920
字号
    XSync(mDisplay, False);    return;}static inline void put_xvimage( XvImage * xvi ){#ifdef HAVE_SHM    if (Shmem_Flag)    {        XvShmPutImage(mDisplay, xv_port, vo_window, vo_gc,                      xvi, 0, 0, image_width,                      image_height, drwX - (vo_panscan_x >> 1),                      drwY - (vo_panscan_y >> 1), vo_dwidth + vo_panscan_x,                      vo_dheight + vo_panscan_y,                      False);    } else#endif    {        XvPutImage(mDisplay, xv_port, vo_window, vo_gc,                   xvi, 0, 0, image_width, image_height,                   drwX - (vo_panscan_x >> 1), drwY - (vo_panscan_y >> 1),                   vo_dwidth + vo_panscan_x,                   vo_dheight + vo_panscan_y);    }}static void check_events(void){    int e = vo_x11_check_events(mDisplay);    if (e & VO_EVENT_RESIZE)    {        XGetGeometry(mDisplay, vo_window, &mRoot, &drwX, &drwY, &vo_dwidth,                     &vo_dheight, &drwBorderWidth, &drwDepth);        mp_msg(MSGT_VO, MSGL_V, "[xv] dx: %d dy: %d dw: %d dh: %d\n", drwX,               drwY, vo_dwidth, vo_dheight);        calc_drwXY(&drwX, &drwY);    }    if (e & VO_EVENT_EXPOSE || e & VO_EVENT_RESIZE)    {	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 ((e & VO_EVENT_EXPOSE || e & VO_EVENT_RESIZE) && int_pause)    {        /* did we already draw a buffer */        if ( visible_buf != -1 )        {          /* redraw the last visible buffer */          put_xvimage( xvimage[visible_buf] );        }    }}static void draw_osd(void){    vo_draw_text(image_width -                 image_width * vo_panscan_x / (vo_dwidth + vo_panscan_x),                 image_height, draw_alpha_fnc);}static void flip_page(void){    put_xvimage( xvimage[current_buf] );    /* remember the currently visible buffer */    visible_buf = current_buf;    if (num_buffers > 1)    {        current_buf =            vo_directrendering ? 0 : ((current_buf + 1) % num_buffers);        XFlush(mDisplay);    } else        XSync(mDisplay, False);    return;}static int draw_slice(uint8_t * image[], int stride[], int w, int h,                           int x, int y){    uint8_t *dst;    dst = xvimage[current_buf]->data + xvimage[current_buf]->offsets[0] +        xvimage[current_buf]->pitches[0] * y + x;    memcpy_pic(dst, image[0], w, h, xvimage[current_buf]->pitches[0],               stride[0]);    x /= 2;    y /= 2;    w /= 2;    h /= 2;    dst = xvimage[current_buf]->data + xvimage[current_buf]->offsets[1] +        xvimage[current_buf]->pitches[1] * y + x;    if (image_format != IMGFMT_YV12)        memcpy_pic(dst, image[1], w, h, xvimage[current_buf]->pitches[1],                   stride[1]);    else        memcpy_pic(dst, image[2], w, h, xvimage[current_buf]->pitches[1],                   stride[2]);    dst = xvimage[current_buf]->data + xvimage[current_buf]->offsets[2] +        xvimage[current_buf]->pitches[2] * y + x;    if (image_format == IMGFMT_YV12)        memcpy_pic(dst, image[1], w, h, xvimage[current_buf]->pitches[1],                   stride[1]);    else        memcpy_pic(dst, image[2], w, h, xvimage[current_buf]->pitches[1],                   stride[2]);    return 0;}static int draw_frame(uint8_t * src[]){    mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_XV_DrawFrameCalled);    return -1;}static uint32_t draw_image(mp_image_t * mpi){    if (mpi->flags & MP_IMGFLAG_DIRECT)    {        // direct rendering:        current_buf = (int) (mpi->priv);        // hack!        return VO_TRUE;    }    if (mpi->flags & MP_IMGFLAG_DRAW_CALLBACK)        return VO_TRUE;         // done    if (mpi->flags & MP_IMGFLAG_PLANAR)    {        draw_slice(mpi->planes, mpi->stride, mpi->w, mpi->h, 0, 0);        return VO_TRUE;    }    if (mpi->flags & MP_IMGFLAG_YUV)    {        // packed YUV:        memcpy_pic(xvimage[current_buf]->data +                   xvimage[current_buf]->offsets[0], mpi->planes[0],                   mpi->w * (mpi->bpp / 8), mpi->h,                   xvimage[current_buf]->pitches[0], mpi->stride[0]);        return VO_TRUE;    }    return VO_FALSE;            // not (yet) supported}static uint32_t get_image(mp_image_t * mpi){    int buf = current_buf;      // we shouldn't change current_buf unless we do DR!    if (mpi->type == MP_IMGTYPE_STATIC && num_buffers > 1)        return VO_FALSE;        // it is not static    if (mpi->imgfmt != image_format)        return VO_FALSE;        // needs conversion :(//    if(mpi->flags&MP_IMGFLAG_READABLE) return VO_FALSE; // slow video ram    if (mpi->flags & MP_IMGFLAG_READABLE &&        (mpi->type == MP_IMGTYPE_IPB || mpi->type == MP_IMGTYPE_IP))    {        // reference (I/P) frame of IP or IPB:        if (num_buffers < 2)            return VO_FALSE;    // not enough        current_ip_buf ^= 1;        // for IPB with 2 buffers we can DR only one of the 2 P frames:        if (mpi->type == MP_IMGTYPE_IPB && num_buffers < 3            && current_ip_buf)            return VO_FALSE;        buf = current_ip_buf;        if (mpi->type == MP_IMGTYPE_IPB)            ++buf;              // preserve space for B    }    if (mpi->height > xvimage[buf]->height)        return VO_FALSE;        //buffer to small    if (mpi->width * (mpi->bpp / 8) > xvimage[buf]->pitches[0])        return VO_FALSE;        //buffer to small    if ((mpi->flags & (MP_IMGFLAG_ACCEPT_STRIDE | MP_IMGFLAG_ACCEPT_WIDTH))        || (mpi->width * (mpi->bpp / 8) == xvimage[buf]->pitches[0]))    {        current_buf = buf;        mpi->planes[0] =            xvimage[current_buf]->data + xvimage[current_buf]->offsets[0];        mpi->stride[0] = xvimage[current_buf]->pitches[0];        mpi->width = mpi->stride[0] / (mpi->bpp / 8);        if (mpi->flags & MP_IMGFLAG_PLANAR)        {            if (mpi->flags & MP_IMGFLAG_SWAPPED)            {                // I420                mpi->planes[1] =                    xvimage[current_buf]->data +                    xvimage[current_buf]->offsets[1];                mpi->planes[2] =                    xvimage[current_buf]->data +                    xvimage[current_buf]->offsets[2];                mpi->stride[1] = xvimage[current_buf]->pitches[1];                mpi->stride[2] = xvimage[current_buf]->pitches[2];            } else            {                // YV12                mpi->planes[1] =                    xvimage[current_buf]->data +                    xvimage[current_buf]->offsets[2];                mpi->planes[2] =                    xvimage[current_buf]->data +                    xvimage[current_buf]->offsets[1];                mpi->stride[1] = xvimage[current_buf]->pitches[2];                mpi->stride[2] = xvimage[current_buf]->pitches[1];            }        }        mpi->flags |= MP_IMGFLAG_DIRECT;        mpi->priv = (void *) current_buf;//      printf("mga: get_image() SUCCESS -> Direct Rendering ENABLED\n");        return VO_TRUE;    }    return VO_FALSE;}static int query_format(uint32_t format){    uint32_t i;    int flag = VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN | VFCAP_OSD | VFCAP_ACCEPT_STRIDE;       // FIXME! check for DOWN    /* check image formats */    for (i = 0; i < formats; i++)    {        if (fo[i].id == format)            return flag;        //xv_format = fo[i].id;    }    return 0;}static void uninit(void){    int i;    if (!vo_config_count)        return;    visible_buf = -1;    XvFreeAdaptorInfo(ai);    ai = NULL;    if(fo){        XFree(fo);        fo=NULL;    }    for (i = 0; i < num_buffers; i++)        deallocate_xvimage(i);#ifdef HAVE_XF86VM    vo_vm_close(mDisplay);#endif    mp_input_rm_event_fd(ConnectionNumber(mDisplay));    vo_x11_uninit();}static int preinit(const char *arg){    XvPortID xv_p;    int busy_ports = 0;    unsigned int i;    strarg_t ck_src_arg = { 0, NULL };    strarg_t ck_method_arg = { 0, NULL };    opt_t subopts[] =    {        /* name         arg type     arg var         test */      {  "port",      OPT_ARG_INT, &xv_port,       (opt_test_f)int_pos },      {  "ck",        OPT_ARG_STR, &ck_src_arg,    xv_test_ck },      {  "ck-method", OPT_ARG_STR, &ck_method_arg, xv_test_ckm },      {  NULL }    };    xv_port = 0;    /* parse suboptions */    if ( subopt_parse( arg, subopts ) != 0 )    {      return -1;    }    /* modify colorkey settings according to the given options */    xv_setup_colorkeyhandling( ck_method_arg.str, ck_src_arg.str );    if (!vo_init())        return -1;    /* check for Xvideo extension */    if (Success != XvQueryExtension(mDisplay, &ver, &rel, &req, &ev, &err))    {        mp_msg(MSGT_VO, MSGL_ERR,               MSGTR_LIBVO_XV_XvNotSupportedByX11);        return -1;    }    /* check for Xvideo support */    if (Success !=        XvQueryAdaptors(mDisplay, DefaultRootWindow(mDisplay), &adaptors,                        &ai))    {        mp_msg(MSGT_VO, MSGL_ERR, MSGTR_LIBVO_XV_XvQueryAdaptorsFailed);        return -1;    }    /* check adaptors */    if (xv_port)    {        int port_found;        for (port_found = 0, i = 0; !port_found && i < adaptors; i++)        {            if ((ai[i].type & XvInputMask) && (ai[i].type & XvImageMask))            {                for (xv_p = ai[i].base_id;                     xv_p < ai[i].base_id + ai[i].num_ports; ++xv_p)                {                    if (xv_p == xv_port)                    {                        port_found = 1;                        break;                    }                }            }        }        if (port_found)        {            if (XvGrabPort(mDisplay, xv_port, CurrentTime))                xv_port = 0;        } else        {            mp_msg(MSGT_VO, MSGL_WARN,                   MSGTR_LIBVO_XV_InvalidPortParameter);            xv_port = 0;        }    }    for (i = 0; i < adaptors && xv_port == 0; i++)    {        if ((ai[i].type & XvInputMask) && (ai[i].type & XvImageMask))        {            for (xv_p = ai[i].base_id;                 xv_p < ai[i].base_id + ai[i].num_ports; ++xv_p)                if (!XvGrabPort(mDisplay, xv_p, CurrentTime))                {                    xv_port = xv_p;                    break;                } else                {                    mp_msg(MSGT_VO, MSGL_WARN,                           MSGTR_LIBVO_XV_CouldNotGrabPort, (int) xv_p);                    ++busy_ports;                }        }    }    if (!xv_port)    {        if (busy_ports)            mp_msg(MSGT_VO, MSGL_ERR,                   MSGTR_LIBVO_XV_CouldNotFindFreePort);        else            mp_msg(MSGT_VO, MSGL_ERR,                   MSGTR_LIBVO_XV_NoXvideoSupport);        return -1;    }    if ( !vo_xv_init_colorkey() )    {      return -1; // bail out, colorkey setup failed    }    vo_xv_enable_vsync();    vo_xv_get_max_img_dim( &max_width, &max_height );    fo = XvListImageFormats(mDisplay, xv_port, (int *) &formats);    mp_input_add_event_fd(ConnectionNumber(mDisplay), check_events);    return 0;}static int control(uint32_t request, void *data, ...){    switch (request)    {        case VOCTRL_PAUSE:            return (int_pause = 1);        case VOCTRL_RESUME:            return (int_pause = 0);        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_GUISUPPORT:            return VO_TRUE;        case VOCTRL_GET_PANSCAN:            if (!vo_config_count || !vo_fs)                return VO_FALSE;            return VO_TRUE;        case VOCTRL_FULLSCREEN:            vo_x11_fullscreen();            /* indended, fallthrough to update panscan on fullscreen/windowed switch */        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)                {                    vo_x11_clearwindow_part(mDisplay, vo_window,                                            vo_dwidth + vo_panscan_x - 1,                                            vo_dheight + vo_panscan_y - 1,                                            1);		    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);                    flip_page();                }            }            return VO_TRUE;        case VOCTRL_SET_EQUALIZER:            {                va_list ap;                int value;                va_start(ap, data);                value = va_arg(ap, int);                va_end(ap);                return (vo_xv_set_eq(xv_port, data, value));            }        case VOCTRL_GET_EQUALIZER:            {                va_list ap;                int *value;                va_start(ap, data);                value = va_arg(ap, int *);                va_end(ap);                return (vo_xv_get_eq(xv_port, data, value));            }        case VOCTRL_ONTOP:            vo_x11_ontop();            return VO_TRUE;        case VOCTRL_UPDATE_SCREENINFO:            update_xinerama_info();            return VO_TRUE;    }    return VO_NOTIMPL;}

⌨️ 快捷键说明

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