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