⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 video_out_x11.c

📁 比较早的MPEG-2的解码源程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * video_out_x11.c * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org> * Copyright (C) 2003      Regis Duchesne <hpreg@zoy.org> * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include "config.h"#ifdef LIBVO_X11#include <stdio.h>#include <stdlib.h>#include <X11/Xlib.h>#include <X11/Xutil.h>#include <sys/ipc.h>#include <sys/shm.h>#include <X11/extensions/XShm.h>#include <inttypes.h>/* since it doesn't seem to be defined on some platforms */int XShmGetEventBase (Display *);#ifdef LIBVO_XV#include <string.h>	/* strcmp */#include <X11/extensions/Xvlib.h>#define FOURCC_YV12 0x32315659#define FOURCC_UYVY 0x59565955#endif#include "mpeg2.h"#include "video_out.h"#include "mpeg2convert.h"typedef struct {    void * data;    int wait_completion;    XImage * ximage;#ifdef LIBVO_XV    XvImage * xvimage;#endif} x11_frame_t;typedef struct x11_instance_s {    vo_instance_t vo;    x11_frame_t frame[3];    int index;    int width;    int height;    Display * display;    Window window;    GC gc;    XVisualInfo vinfo;    XShmSegmentInfo shminfo;    int completion_type;#ifdef LIBVO_XV    unsigned int adaptors;    XvAdaptorInfo * adaptorInfo;    XvPortID port;    int xv;#endif    void (* teardown) (struct x11_instance_s * instance);} x11_instance_t;static int open_display (x11_instance_t * instance, int width, int height){    int major;    int minor;    Bool pixmaps;    XVisualInfo visualTemplate;    XVisualInfo * XvisualInfoTable;    XVisualInfo * XvisualInfo;    int number;    int i;    XSetWindowAttributes attr;    XGCValues gcValues;    instance->display = XOpenDisplay (NULL);    if (! (instance->display)) {	fprintf (stderr, "Can not open display\n");	return 1;    }    if ((XShmQueryVersion (instance->display, &major, &minor,			   &pixmaps) == 0) ||	(major < 1) || ((major == 1) && (minor < 1))) {	fprintf (stderr, "No xshm extension\n");	return 1;    }    instance->completion_type =	XShmGetEventBase (instance->display) + ShmCompletion;    /* list truecolor visuals for the default screen */#ifdef __cplusplus    visualTemplate.c_class = TrueColor;#else    visualTemplate.class = TrueColor;#endif    visualTemplate.screen = DefaultScreen (instance->display);    XvisualInfoTable = XGetVisualInfo (instance->display,				       VisualScreenMask | VisualClassMask,				       &visualTemplate, &number);    if (XvisualInfoTable == NULL) {	fprintf (stderr, "No truecolor visual\n");	return 1;    }    /* find the visual with the highest depth */    XvisualInfo = XvisualInfoTable;    for (i = 1; i < number; i++)	if (XvisualInfoTable[i].depth > XvisualInfo->depth)	    XvisualInfo = XvisualInfoTable + i;    instance->vinfo = *XvisualInfo;    XFree (XvisualInfoTable);    attr.background_pixmap = None;    attr.backing_store = NotUseful;    attr.border_pixel = 0;    attr.event_mask = 0;    /* fucking sun blows me - you have to create a colormap there... */    attr.colormap = XCreateColormap (instance->display,				     RootWindow (instance->display,						 instance->vinfo.screen),				     instance->vinfo.visual, AllocNone);    instance->window =	XCreateWindow (instance->display,		       DefaultRootWindow (instance->display),		       0 /* x */, 0 /* y */, width, height,		       0 /* border_width */, instance->vinfo.depth,		       InputOutput, instance->vinfo.visual,		       (CWBackPixmap | CWBackingStore | CWBorderPixel |			CWEventMask | CWColormap), &attr);    instance->gc = XCreateGC (instance->display, instance->window, 0,			      &gcValues);#ifdef LIBVO_XV    instance->adaptors = 0;    instance->adaptorInfo = NULL;#endif    return 0;}static int shmerror = 0;static int handle_error (Display * display, XErrorEvent * error){    shmerror = 1;    return 0;}static void * create_shm (x11_instance_t * instance, int size){    instance->shminfo.shmid = shmget (IPC_PRIVATE, size, IPC_CREAT | 0777);    if (instance->shminfo.shmid == -1)	goto error;    instance->shminfo.shmaddr = (char *) shmat (instance->shminfo.shmid, 0, 0);    if (instance->shminfo.shmaddr == (char *)-1)	goto error;    /* on linux the IPC_RMID only kicks off once everyone detaches the shm */    /* doing this early avoids shm leaks when we are interrupted. */    /* this would break the solaris port though :-/ */    /* shmctl (instance->shminfo.shmid, IPC_RMID, 0); */    /* XShmAttach fails on remote displays, so we have to catch this event */    XSync (instance->display, False);    XSetErrorHandler (handle_error);    instance->shminfo.readOnly = True;    if (! (XShmAttach (instance->display, &(instance->shminfo))))	shmerror = 1;    XSync (instance->display, False);    XSetErrorHandler (NULL);    if (shmerror) {    error:	fprintf (stderr, "cannot create shared memory\n");	return NULL;    }    return instance->shminfo.shmaddr;}static void destroy_shm (x11_instance_t * instance){    XShmDetach (instance->display, &(instance->shminfo));    shmdt (instance->shminfo.shmaddr);    shmctl (instance->shminfo.shmid, IPC_RMID, 0);}static void x11_event (x11_instance_t * instance)	/* XXXXXXXXXXX */{    XEvent event;    char * addr;    int i;    XNextEvent (instance->display, &event);    if (event.type == instance->completion_type) {	addr = (instance->shminfo.shmaddr +		((XShmCompletionEvent *)&event)->offset);	for (i = 0; i < 3; i++)	    if (addr == instance->frame[i].data)		instance->frame[i].wait_completion = 0;    }}static void x11_start_fbuf (vo_instance_t * _instance,			    uint8_t * const * buf, void * id){    x11_instance_t * instance = (x11_instance_t *) _instance;    x11_frame_t * frame = (x11_frame_t *) id;    while (frame->wait_completion)	x11_event (instance);}static void x11_setup_fbuf (vo_instance_t * _instance,			    uint8_t ** buf, void ** id){    x11_instance_t * instance = (x11_instance_t *) _instance;    buf[0] = (uint8_t *) instance->frame[instance->index].data;    buf[1] = buf[2] = NULL;    *id = instance->frame + instance->index++;}static void x11_draw_frame (vo_instance_t * _instance,			    uint8_t * const * buf, void * id){    x11_frame_t * frame;    x11_instance_t * instance;    frame = (x11_frame_t *) id;    instance = (x11_instance_t *) _instance;    XShmPutImage (instance->display, instance->window, instance->gc,		  frame->ximage, 0, 0, 0, 0, instance->width, instance->height,		  True);    XFlush (instance->display);    frame->wait_completion = 1;}static int x11_alloc_frames (x11_instance_t * instance){    int size;    char * alloc;    int i;    size = 0;    alloc = NULL;    for (i = 0; i < 3; i++) {	instance->frame[i].wait_completion = 0;	instance->frame[i].ximage =	    XShmCreateImage (instance->display, instance->vinfo.visual,			     instance->vinfo.depth, ZPixmap, NULL /* data */,			     &(instance->shminfo),			     instance->width, instance->height);	if (instance->frame[i].ximage == NULL) {	    fprintf (stderr, "Cannot create ximage\n");	    return 1;	} else if (i == 0) {	    size = (instance->frame[0].ximage->bytes_per_line *		    instance->frame[0].ximage->height);	    alloc = (char *) create_shm (instance, 3 * size);	    if (alloc == NULL) {		XDestroyImage (instance->frame[i].ximage);		return 1;	    }	} else if (size != (instance->frame[i].ximage->bytes_per_line *			    instance->frame[i].ximage->height)) {	    fprintf (stderr, "unexpected ximage data size\n");	    return 1;	}	instance->frame[i].data = instance->frame[i].ximage->data = alloc;

⌨️ 快捷键说明

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