diff options
-rw-r--r-- | src/demuxers/demux_avi.c | 9 | ||||
-rw-r--r-- | src/video_out/Makefile.am | 9 | ||||
-rw-r--r-- | src/video_out/video_out_xshm.c | 1264 | ||||
-rw-r--r-- | src/video_out/video_out_xv.c | 17 |
4 files changed, 459 insertions, 840 deletions
diff --git a/src/demuxers/demux_avi.c b/src/demuxers/demux_avi.c index 11d010bd5..6b7956901 100644 --- a/src/demuxers/demux_avi.c +++ b/src/demuxers/demux_avi.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: demux_avi.c,v 1.13 2001/06/03 12:39:40 guenter Exp $ + * $Id: demux_avi.c,v 1.14 2001/06/04 15:04:11 guenter Exp $ * * demultiplexer for avi streams * @@ -937,9 +937,12 @@ static int demux_avi_open(demux_plugin_t *this_gen, this->input = input; this->avi = AVI_init (this); - if (this->avi) + if (this->avi) { + + printf ("demux_avi: %d frames\n", this->avi->video_frames); + return DEMUX_CAN_HANDLE; - else + } else printf ("demux_avi: AVI_init failed (AVI_errno: %d)\n",this->AVI_errno); return DEMUX_CANNOT_HANDLE; diff --git a/src/video_out/Makefile.am b/src/video_out/Makefile.am index af1830e87..ba7769edd 100644 --- a/src/video_out/Makefile.am +++ b/src/video_out/Makefile.am @@ -5,8 +5,7 @@ CFLAGS = @GLOBAL_CFLAGS@ @X_CFLAGS@ -DXINE_COMPILE libdir = $(XINE_PLUGINDIR) if HAVE_X11 -## xshm and syncfb should be fixed first ;-) -## xshm_module = xineplug_vo_out_xshm.la +xshm_module = xineplug_vo_out_xshm.la syncfb_module = xineplug_vo_out_syncfb.la if HAVE_XV xv_module = xineplug_vo_out_xv.la @@ -19,14 +18,14 @@ endif # All of xine video out plugins should be named like the # scheme "xineplug_vo_out_" # -lib_LTLIBRARIES = $(xv_module) $(syncfb_module) ## $(xshm_module) +lib_LTLIBRARIES = $(xv_module) $(syncfb_module) $(xshm_module) xineplug_vo_out_xv_la_SOURCES = video_out_xv.c xineplug_vo_out_xv_la_LIBADD = $(X_LIBS) xineplug_vo_out_xv_la_LDFLAGS = -avoid-version -module -## xineplug_vo_out_xshm_la_SOURCES = yuv2rgb.c yuv2rgb_mmx.c video_out_xshm.c -## xineplug_vo_out_xshm_la_LDFLAGS = -avoid-version -module +xineplug_vo_out_xshm_la_SOURCES = yuv2rgb.c yuv2rgb_mmx.c video_out_xshm.c +xineplug_vo_out_xshm_la_LDFLAGS = -avoid-version -module xineplug_vo_out_syncfb_la_SOURCES = video_out_syncfb.c xineplug_vo_out_syncfb_la_LDFLAGS = -avoid-version -module diff --git a/src/video_out/video_out_xshm.c b/src/video_out/video_out_xshm.c index d2f2c6bc0..a68944048 100644 --- a/src/video_out/video_out_xshm.c +++ b/src/video_out/video_out_xshm.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: video_out_xshm.c,v 1.2 2001/05/28 12:35:54 guenter Exp $ + * $Id: video_out_xshm.c,v 1.3 2001/06/04 15:04:13 guenter Exp $ * * video_out_xshm.c, X11 shared memory extension interface for xine * @@ -52,6 +52,7 @@ #include "xine_internal.h" #include "monitor.h" +#include "utils.h" #include "video_out_x11.h" #include "yuv2rgb.h" @@ -59,18 +60,11 @@ uint32_t xine_debug; extern int XShmGetEventBase(Display *); -typedef struct xshm_property_s { - int value; - int min; - int max; - Atom atom; - char *key; -} xshm_property_t; - typedef struct xshm_frame_s { vo_frame_t vo_frame; - int width, height, ratio_code, format; + int width, height; + int rgb_width, rgb_height; XImage *image; XShmSegmentInfo shminfo; @@ -90,9 +84,11 @@ typedef struct xshm_driver_s { XVisualInfo vinfo; GC gc; XColor black; + int use_shm; + int depth, bpp, bytes_per_pixel; + int expecting_event; - xshm_property_t props[VO_NUM_PROPERTIES]; - uint32_t capabilities; + yuv2rgb_t *yuv2rgb; xshm_frame_t *cur_frame; @@ -106,897 +102,562 @@ typedef struct xshm_driver_s { int output_xoffset; int output_yoffset; + int user_ratio; + + int dest_width; /* size of image gui has most recently adopted to */ + int dest_height; + int dest_x; + int dest_y; + /* display anatomy */ double display_ratio; /* given by visual parameter from init function */ - /* gui callback */ + /* gui callbacks */ void (*request_dest_size) (int video_width, int video_height, int *dest_x, int *dest_y, int *dest_height, int *dest_width); + void (*calc_dest_size) (int video_width, int video_height, + int *dest_width, int *dest_height); + } xshm_driver_t; -int HandleXError (Display *gDisplay, XErrorEvent *xevent) { +int gX11Fail; + +/* + * first, some utility functions + */ + +int HandleXError (Display *display, XErrorEvent *xevent) { - xprintf (VERBOSE|VIDEO, "\n\n*** X ERROR *** \n\n\n"); + char str [1024]; + + XGetErrorText (display, xevent->error_code, str, 1024); - gXshm.bFail = 1; + printf ("received X error event: %s\n", str); + + gX11Fail = 1; return 0; } -static void x11_InstallXErrorHandler () +static void x11_InstallXErrorHandler (xshm_driver_t *this) { XSetErrorHandler (HandleXError); - XFlush (gDisplay); + XFlush (this->display); } -static void x11_DeInstallXErrorHandler () +static void x11_DeInstallXErrorHandler (xshm_driver_t *this) { XSetErrorHandler (NULL); - XFlush (gDisplay); + XFlush (this->display); } -static int get_capabilities_xshm () { - return VO_CAP_COPIES_IMAGE | VO_CAP_YV12; -} - -static void setup_window_xshm () { - char *hello = "xine video output"; - Colormap theCmap = 0; - XSizeHints hint; - XWMHints *wm_hint; - XEvent xev; - XGCValues xgcv; - XColor background, ignored; - XSetWindowAttributes attr; - int ww, wh; - float aspect; - Atom WM_DELETE_WINDOW; - XClassHint *xshm_xclasshint; - - XLOCK (); - - - if((xshm_xclasshint = XAllocClassHint()) != NULL) { - xshm_xclasshint->res_name = "Xine Xshm Video"; - xshm_xclasshint->res_class = "Xine"; - } - - if (gXshm.bFullscreen) { - - ww = DisplayWidth (gDisplay, gXshm.screen); - wh = DisplayHeight (gDisplay, gXshm.screen); - - /* - * zoom to fullscreen - */ - - if (gXshm.dest_width < ww) { - aspect = (float) gXshm.dest_width / (float) gXshm.dest_height ; - - gXshm.dest_width = ww; - gXshm.dest_height = ww / aspect; - } - - gXshm.image_xoff = ( ww - gXshm.dest_width) / 2; - gXshm.image_yoff = ( wh - gXshm.dest_height) / 2; - +/* + * allocate an XImage, try XShm first but fall back to + * plain X11 if XShm should fail + */ - if (gXshm.window) { +static XImage *create_ximage (xshm_driver_t *this, XShmSegmentInfo *shminfo, + int width, int height) { - if (gXshm.bIsFullscreen) { - XUNLOCK (); - return; - } + XImage *myimage = NULL; - XDestroyWindow(gDisplay, gXshm.window); - gXshm.window = 0; - - } - - gXshm.bIsFullscreen = 1; + if (this->use_shm) { /* - * open fullscreen window + * try shm */ - - if (XAllocNamedColor (gDisplay, DefaultColormap (gDisplay, gXshm.screen), - "black", - &background, &ignored) == 0) { - fprintf (stderr, "Cannot allocate color black\n"); - exit(1); - } - - attr.background_pixel = background.pixel; - attr.override_redirect = True; - - gXshm.window = - XCreateWindow (gDisplay, RootWindow (gDisplay, gXshm.screen), 0, 0, - ww, wh, 0, gXshm.depth, - CopyFromParent, DefaultVisual (gDisplay, gXshm.screen), - CWBackPixel|CWOverrideRedirect, &attr); - - if(xshm_xclasshint != NULL) - XSetClassHint(gDisplay, gXshm.window, xshm_xclasshint); - - gVideoWin = gXshm.window; - - } else { - - if (gXshm.window) { - - if (gXshm.bIsFullscreen) { - XDestroyWindow(gDisplay, gXshm.window); - gXshm.window = 0; - } else { - - XResizeWindow (gDisplay, gXshm.window, gXshm.dest_width, - gXshm.dest_height); - - XFlush(gDisplay); - XSync(gDisplay, False); - XUNLOCK (); - return; - - } - } - - gXshm.bIsFullscreen = 0; - - - hint.x = 0; - hint.y = 0; - hint.width = gXshm.dest_width; - hint.height = gXshm.dest_height; - hint.flags = PPosition | PSize; - theCmap = XCreateColormap(gDisplay, RootWindow(gDisplay,gXshm.screen), - gXshm.vinfo.visual, AllocNone); + gX11Fail = 0; + x11_InstallXErrorHandler (this); + + myimage = XShmCreateImage(this->display, + this->vinfo.visual, + this->vinfo.depth, + ZPixmap, NULL, + shminfo, + width, + height); + + if (myimage == NULL ) { + printf ("video_out_xshm: shared memory error when allocating image\n"); + printf ("=> not using MIT Shared Memory extension.\n"); + this->use_shm = 0; + goto finishShmTesting; + } - attr.background_pixel = 0; - attr.border_pixel = 1; - attr.colormap = theCmap; - - gXshm.window = XCreateWindow(gDisplay, RootWindow(gDisplay, gXshm.screen), - hint.x, hint.y, hint.width, hint.height, 4, - gXshm.depth,CopyFromParent,gXshm.vinfo.visual, - CWBackPixel | CWBorderPixel |CWColormap,&attr); - - if(xshm_xclasshint != NULL) - XSetClassHint(gDisplay, gXshm.window, xshm_xclasshint); - - gVideoWin = gXshm.window; + this->bpp = myimage->bits_per_pixel; + this->bytes_per_pixel = this->bpp / 8; - /* Tell other applications about this window */ - - XSetStandardProperties(gDisplay, gXshm.window, hello, hello, - None, NULL, 0, &hint); - - gXshm.image_xoff = 0; - gXshm.image_yoff = 0; - } - - XSelectInput(gDisplay, gXshm.window, StructureNotifyMask | ExposureMask | KeyPressMask | ButtonPressMask | StructureNotifyMask); - - wm_hint = XAllocWMHints(); - if (wm_hint != NULL) { - wm_hint->input = True; - wm_hint->initial_state = NormalState; - wm_hint->flags = InputHint | StateHint; - XSetWMHints(gDisplay, gXshm.window, wm_hint); - XFree(wm_hint); - } - - WM_DELETE_WINDOW = XInternAtom(gDisplay, "WM_DELETE_WINDOW", False); - XSetWMProtocols(gDisplay, gXshm.window, &WM_DELETE_WINDOW, 1); - - /* Map window. */ - - XMapWindow(gDisplay, gXshm.window); + shminfo->shmid=shmget(IPC_PRIVATE, + myimage->bytes_per_line * myimage->height, + IPC_CREAT | 0777); + + if (shminfo->shmid < 0 ) { + printf ("video_out_xshm: %s: allocating image\n",strerror(errno)); + printf ("video_out_xshm: => not using MIT Shared Memory extension.\n"); + this->use_shm = 0; + goto finishShmTesting; + } - /* Wait for map. */ - do { - XMaskEvent(gDisplay, - StructureNotifyMask, - &xev) ; - } while (xev.type != MapNotify || xev.xmap.event != gXshm.window); - - XFlush(gDisplay); - XSync(gDisplay, False); + shminfo->shmaddr = (char *) shmat(shminfo->shmid, 0, 0); - gXshm.gc = XCreateGC(gDisplay, gXshm.window, 0L, &xgcv); - - if (gXshm.bFullscreen) - XSetInputFocus (gDisplay, gXshm.window, RevertToNone, CurrentTime); - - if (gXshm.bFullscreen) { - if (!gXshm.mcursor[0]) { - create_cursor_xshm (theCmap); + if (shminfo->shmaddr == ((char *) -1)) { + printf ("video_out_xshm: shared memory error (address error) when allocating image \n"); + printf ("video_out_xshm: => not using MIT Shared Memory extension.\n"); + this->use_shm = 0; + goto finishShmTesting; } - - //display_cursor_xshm(HIDE_CURSOR); - } - /* drag and drop */ - - XUNLOCK (); - if(!gXshm.xdnd) - gXshm.xdnd = (DND_struct_t *) malloc(sizeof(DND_struct_t)); + shminfo->readOnly = False; + myimage->data = shminfo->shmaddr; - gui_init_dnd(gXshm.xdnd); - gui_dnd_set_callback (gXshm.xdnd, gui_dndcallback); - gui_make_window_dnd_aware (gXshm.xdnd, gXshm.window); + XShmAttach(this->display, shminfo); -} - -/* allocates ximages if necessary */ -static int set_image_format_xshm (uint32_t width, uint32_t height, uint32_t ratio, int format) { - - /* FIXME: handle format argument */ + XSync(this->display, False); - if ( (gXshm.image_width == width) - && (gXshm.image_height == height) - && (gXshm.ratio == ratio) - && (gXshm.bFullscreen == gXshm.bIsFullscreen) - && !gXshm.user_ratio_changed ) - return 0; + if (gX11Fail) { + printf ("video_out_xshm: x11 error during shared memory XImage creation\n"); + printf ("video_out_xshm: => not using MIT Shared Memory extension.\n"); + this->use_shm = 0; + } + finishShmTesting: + x11_DeInstallXErrorHandler(this); - gXshm.image_width = width; - gXshm.image_height = height; - gXshm.hstride_rgb = gXshm.dest_width * gXshm.bytes_per_pixel; - gXshm.hstride_y = gXshm.image_width; - gXshm.hstride_uv = gXshm.image_width / 2; - gXshm.ratio = ratio; - gXshm.user_ratio_changed = 0; + } /* - * calculate dest size from ratio + * fall back to plain X11 if necessary */ - /* - * Mpeg-2: - */ + if (!this->use_shm) { - if (gXshm.user_ratio == ASPECT_AUTO) { - switch (gXshm.ratio) { - case 0: /* forbidden */ - fprintf (stderr, "invalid ratio\n"); - exit (1); - break; - case 1: /* square */ - gXshm.dest_width = width; - gXshm.dest_height = height; - gXshm.anamorphic = 0; - break; - case 2: /* 4:3 */ - gXshm.dest_width = width ; - gXshm.dest_height = height; - gXshm.anamorphic = 0; + char *data; + + switch (this->vinfo.depth) { + case 15: + case 16: + this->bpp = 16; break; - case 3: /* 16:9 */ - gXshm.dest_width = width * 5/4; - gXshm.dest_height = height; - gXshm.anamorphic = 1; + case 24: + this->bpp = 24; break; + case 32: + this->bpp = 32; default: - gXshm.dest_width = width; - gXshm.dest_height = height; - xprintf (VERBOSE|VIDEO, "invalid ratio\n"); - /*exit (1); */ - break; - } - } else if (gXshm.user_ratio == ASPECT_ANAMORPHIC) { - gXshm.dest_width = width *5/4 ; - gXshm.dest_height = height; - gXshm.anamorphic = 1; - } else { - gXshm.dest_width = width; - gXshm.dest_height = height; - gXshm.anamorphic = 0; - } - - - xprintf (VERBOSE|VIDEO, "picture size : %d x %d (Ratio: %d)\n", - width, height, ratio); - - setup_window_xshm () ; + printf ("video_out_xshm: !!!!!!! unknown depth : %d\n",this->vinfo.depth); + this->bpp = 16; + } - return 1; -} - -static void dispose_image_buffer_xshm (vo_image_buffer_t *vo_img) { - - xshm_image_buffer_t *img = (xshm_image_buffer_t *) vo_img; - XLOCK (); + this->bytes_per_pixel = this->bpp / 8; - if (gXshm.bUseShm) { - - XShmDetach(gDisplay, &img->mShminfo); - XDestroyImage(img->mImage); - shmdt(img->mShminfo.shmaddr); - shmctl (img->mShminfo.shmid, IPC_RMID,NULL); - - } else { - - XDestroyImage(img->mImage); + data = xmalloc (width * this->bytes_per_pixel * height); + myimage = XCreateImage (this->display, + this->vinfo.visual, + this->vinfo.depth, + ZPixmap, 0, + data, + width, + height, + 8, width * this->bytes_per_pixel); } - free (img); + return myimage; - XUNLOCK (); } +static void dispose_ximage (xshm_driver_t *this, + XShmSegmentInfo *shminfo, + XImage *myimage) { -static vo_image_buffer_t *alloc_image_buffer_xshm () { - - uint32_t image_size; - xshm_image_buffer_t *img ; + if (this->use_shm) { - XLOCK (); + XShmDetach (this->display, shminfo); + XDestroyImage (myimage); + shmdt (shminfo->shmaddr); + shmctl (shminfo->shmid, IPC_RMID, 0); - img = (xshm_image_buffer_t *) malloc (sizeof (xshm_image_buffer_t)); - - if (img==NULL) { - printf ("out of memory while allocating image buffer\n"); - exit (1); - } - - if (gXshm.bUseShm) { - img->mImage = XShmCreateImage(gDisplay, - gXshm.vinfo.visual, - gXshm.vinfo.depth, - ZPixmap, NULL, - &img->mShminfo, - gXshm.dest_width, - gXshm.dest_height); - - if (img->mImage == NULL ) { - fprintf(stderr, "Shared memory error when allocating image => exit (Ximage error)\n"); - exit (1); - } - - gXshm.bpp = img->mImage->bits_per_pixel; - gXshm.bytes_per_pixel = gXshm.bpp / 8; - gXshm.hstride_rgb = gXshm.dest_width * gXshm.bytes_per_pixel; - img->mShminfo.shmid=shmget(IPC_PRIVATE, - img->mImage->bytes_per_line * img->mImage->height, - IPC_CREAT | 0777); - - if (img->mShminfo.shmid < 0 ) { - printf("%s: allocating image \n",strerror(errno)); - exit (1); - } - - img->mShminfo.shmaddr = (char *) shmat(img->mShminfo.shmid, 0, 0); - - if (img->mShminfo.shmaddr == ((char *) -1)) { - fprintf(stderr, "Shared memory error (address error) when allocating image \n"); - exit (1); - } - - img->mShminfo.readOnly = False; - img->mImage->data = img->mShminfo.shmaddr; - - XShmAttach(gDisplay, &img->mShminfo); - - XSync(gDisplay, False); - /* shmctl(img->mShminfo.shmid, IPC_RMID, 0);*/ - } else { /* no shm */ + } else { - /* - XResizeWindow (gDisplay, gXshm.window, gXshm.dest_width, - gXshm.dest_height); - - XSync(gDisplay, False); - */ - img->mImage = XGetImage (gDisplay, gXshm.window, 0, 0, - gXshm.dest_width, gXshm.dest_height, - AllPlanes, ZPixmap); - XSync(gDisplay, False); - } + XDestroyImage (myimage); - - image_size = gXshm.image_width * gXshm.image_height; - img->mImageBuffer.mem[0] = malloc(image_size); - img->mImageBuffer.mem[1] = malloc(image_size/4); - img->mImageBuffer.mem[2] = malloc(image_size/4); - - if (!gXshm.bYuvInitialized) { - int mode = ((img->mImage->blue_mask & 0x01)) ? MODE_RGB : MODE_BGR; - yuv2rgb_init((gXshm.depth == 24) ? gXshm.bpp : gXshm.depth, mode); - gXshm.bYuvInitialized = 1; } - - XUNLOCK (); - - pthread_mutex_init (&img->mImageBuffer.mutex, NULL); - - return (vo_image_buffer_t *) img; } -static void process_macroblock_xshm (vo_image_buffer_t *img, - uint8_t *py, uint8_t *pu, uint8_t *pv, - int slice_num, - int subslice_num) { - - uint8_t *dst; - int subslice_offset; - xshm_image_buffer_t *xshm_img = (xshm_image_buffer_t *) img; - int slice_offset; - - slice_offset = slice_num * 16 * gXshm.dest_width ; - if (gXshm.anamorphic) - subslice_offset = subslice_num *20 ; - else - subslice_offset = subslice_num *16 ; - - dst = xshm_img->mImage->data + (slice_offset + subslice_offset) * gXshm.bytes_per_pixel ; - - if (gXshm.anamorphic) - yuv2rgb_anamorphic(dst, - py, pu, pv, - gXshm.hstride_rgb, - gXshm.hstride_y, - gXshm.hstride_uv); - else - yuv2rgb(dst, - py, pu, pv, - gXshm.hstride_rgb, - gXshm.hstride_y, - gXshm.hstride_uv); -} +/* + * and now, the driver functions + */ -static int is_fullscreen_xshm () { - return gXshm.bFullscreen; +static uint32_t xshm_get_capabilities (vo_driver_t *this_gen) { + return VO_CAP_COPIES_IMAGE | VO_CAP_YV12; } -static void set_fullscreen_xshm (int bFullscreen) { +static void xshm_frame_copy (vo_frame_t *vo_img, uint8_t **src) { + /* FIXME: implement */ - xprintf(VERBOSE|VIDEO, "(!)Fullscreen not implemented for xshm.\n"); - return ; /* FIXME - not implemented for xshm */ - gXshm.bFullscreen = bFullscreen; - - set_image_format_xshm (gXshm.image_width, gXshm.image_height, gXshm.ratio, IMGFMT_YV12); } -static void display_frame_xshm (vo_image_buffer_t *vo_img) { - - xshm_image_buffer_t *img = (xshm_image_buffer_t *) vo_img; - - XLOCK (); - - if (gXshm.bUseShm) { - - XShmPutImage(gDisplay, gXshm.window, gXshm.gc, img->mImage, - 0, 0, 0, 0, - img->mImage->width, img->mImage->height, True); - } else { - - xprintf (VERBOSE|VIDEO, "display frame\n"); +static void xshm_frame_field (vo_frame_t *vo_img, int which_field) { + /* FIXME: implement */ +} - XPutImage(gDisplay, gXshm.window, gXshm.gc, img->mImage, - 0, 0, 0, 0, - img->mImage->width, img->mImage->height); - } +static void xshm_frame_dispose (vo_frame_t *vo_img) { - XFlush(gDisplay); + xshm_frame_t *frame = (xshm_frame_t *) vo_img ; + xshm_driver_t *this = (xshm_driver_t *) vo_img->instance->driver; - if (gXshm.cur_image) { - vo_image_drawn ( (vo_image_buffer_t *) gXshm.cur_image); + if (frame->image) { + XLockDisplay (this->display); + dispose_ximage (this, &frame->shminfo, frame->image); + XUnlockDisplay (this->display); } - gXshm.cur_image = img; - - XUNLOCK (); + free (frame); } -static void draw_logo_xshm () { - ImlibImage *resized_image; - int xwin, ywin, tmp; - unsigned int wwin, hwin, bwin, dwin; - double ratio = 1; - Window rootwin; - XLOCK ();; +static vo_frame_t *xshm_alloc_frame (vo_driver_t *this_gen) { - XClearWindow (gDisplay, gXshm.window); + xshm_frame_t *frame ; - if(XGetGeometry(gDisplay, gXshm.window, &rootwin, - &xwin, &ywin, &wwin, &hwin, &bwin, &dwin) != BadDrawable) { + frame = (xshm_frame_t *) malloc (sizeof (xshm_frame_t)); + memset (frame, 0, sizeof(xshm_frame_t)); - tmp = (wwin / 100) * 86; - ratio = (tmp < gXineLogoWidth && tmp >= 1) ? - (ratio = (double)tmp / (double)gXineLogoWidth) : 1; + if (frame==NULL) { + printf ("xshm_alloc_frame: out of memory\n"); } + + pthread_mutex_init (&frame->vo_frame.mutex, NULL); + + /* + * supply required functions + */ - resized_image = Imlib_clone_image(gImlib_data, gXineLogoImg); - Imlib_render (gImlib_data, resized_image, - (int)gXineLogoWidth * ratio, - (int)gXineLogoHeight * ratio); + frame->vo_frame.copy = xshm_frame_copy; + frame->vo_frame.field = xshm_frame_field; + frame->vo_frame.dispose = xshm_frame_dispose; + + return (vo_frame_t *) frame; +} - XCopyArea (gDisplay, resized_image->pixmap, gXshm.window, gXshm.gc, 0, 0, - resized_image->width, resized_image->height, - (wwin - resized_image->width) / 2, - (hwin - resized_image->height) / 2); +static void xshm_calc_output_size (xshm_driver_t *this) { - XFlush(gDisplay); + double image_ratio, desired_ratio; + double corr_factor; + int ideal_width, ideal_height; - Imlib_destroy_image(gImlib_data, resized_image); + /* + * aspect ratio calculation + */ - XUNLOCK ();; -} + image_ratio = + (double) this->delivered_width / (double) this->delivered_height; -static void handle_event_xshm (XEvent *event) { - - switch (event->type) { - case Expose: - if (event->xexpose.window == gXshm.window) { - if (gXshm.bLogoMode) { - draw_logo_xshm (); - } else { - XLOCK (); - XClearWindow (gDisplay, gXshm.window); - if (gXshm.cur_image) - XShmPutImage(gDisplay, gXshm.window, gXshm.gc, - gXshm.cur_image->mImage, - 0, 0, 0, 0, - gXshm.cur_image->mImage->width, - gXshm.cur_image->mImage->height, True); - XUNLOCK (); - } + switch (this->user_ratio) { + case ASPECT_AUTO: + switch (this->delivered_ratio_code) { + case 3: /* anamorphic */ + desired_ratio = 16.0 /9.0; + break; + case 42: /* probably non-mpeg stream => don't touch aspect ratio */ + desired_ratio = image_ratio; + break; + case 0: /* forbidden */ + fprintf (stderr, "invalid ratio, using 4:3\n"); + case 1: /* "square" => 4:3 */ + case 2: /* 4:3 */ + default: + xprintf (VIDEO, "unknown aspect ratio (%d) in stream => using 4:3\n", + this->delivered_ratio_code); + desired_ratio = 4.0 / 3.0; + break; } break; - - case ClientMessage: - if(event->xany.window == gXshm.window) - gui_dnd_process_client_message (gXshm.xdnd, event); + case ASPECT_ANAMORPHIC: + desired_ratio = 16.0 / 9.0; + break; + case ASPECT_DVB: + desired_ratio = 2.0 / 1.0; break; + default: + desired_ratio = 4.0 / 3.0; } -} -static void set_logo_mode_xshm (int bLogoMode) { - gXshm.bLogoMode = bLogoMode; + /* this->ratio_factor = display_ratio * desired_ratio / image_ratio ; */ + this->ratio_factor = this->display_ratio * desired_ratio; - if (bLogoMode) - draw_logo_xshm (); -} + /* + * calc ideal output frame size + */ -static void reset_xshm () { + corr_factor = this->ratio_factor / image_ratio ; - if (gXshm.cur_image) { - vo_image_drawn ( (vo_image_buffer_t *) gXshm.cur_image); - gXshm.cur_image = NULL; + if (corr_factor >= 1.0) { + ideal_width = this->delivered_width * corr_factor; + ideal_height = this->delivered_height ; + } + else { + ideal_width = this->delivered_width; + ideal_height = this->delivered_height / corr_factor; } -} + /* little hack to zoom mpeg1 / other small streams by default*/ + if (ideal_width<400) { + ideal_width *=2; + ideal_height *=2; + } -void set_aspect_xshm (int ratio) { + this->calc_dest_size (ideal_width, ideal_height, + &this->output_width, &this->output_height); - ratio %= 3; /* DVB unsupported */ +} - if (ratio != gXshm.user_ratio) { - gXshm.user_ratio = ratio; - gXshm.user_ratio_changed = 1; +static void xshm_update_frame_format (vo_driver_t *this_gen, + vo_frame_t *frame_gen, + uint32_t width, uint32_t height, + int ratio_code, int format) { - set_image_format_xshm (gXshm.image_width, gXshm.image_height, gXshm.ratio, IMGFMT_YV12); - } + xshm_driver_t *this = (xshm_driver_t *) this_gen; + xshm_frame_t *frame = (xshm_frame_t *) frame_gen; - printf ("set_aspect done\n"); -} + if ( (width != this->delivered_width) || (height != this->delivered_width) + || (ratio_code != this->delivered_ratio_code) ) { -int get_aspect_xshm () { - return gXshm.user_ratio; -} + this->delivered_width = width; + this->delivered_height = height; + this->delivered_ratio_code = ratio_code; -void exit_xshm () { -} - -static int get_noop(void) { - return 0; -} + xshm_calc_output_size (this); + /* + yuv2rgb_setup (this->yuv2rgb, + this->delivered_width, + this->delivered_height, + this->delivered_width, + this->delivered_width/2, + this->output_width, + this->output_height, + this->output_width*this->bytes_per_pixel); + */ + } -static int set_noop(int v) { - return v; -} + if ((frame->width != this->output_width) + || (frame->height != this->output_height)) { -static vo_driver_t vo_xshm = { - get_capabilities_xshm, - set_image_format_xshm, - alloc_image_buffer_xshm, - dispose_image_buffer_xshm, - process_macroblock_xshm, - display_frame_xshm, - set_fullscreen_xshm, - is_fullscreen_xshm, - handle_event_xshm, - set_logo_mode_xshm, - reset_xshm, - display_cursor_xshm, - set_aspect_xshm, - get_aspect_xshm, - exit_xshm, - - get_noop, - get_noop, - set_noop, - get_noop, - - get_noop, - get_noop, - set_noop, - get_noop, - - get_noop, - get_noop, - set_noop, - get_noop, - - get_noop, - get_noop, - set_noop, - get_noop, - - get_noop, - get_noop, - set_noop, - - NULL, - NULL -}; + int image_size; -/* - * connect to server, create and map window, - * allocate colors and (shared) memory - */ + /* + printf ("video_out_xshm: updating frame to %d x %d\n", + this->output_width,this->output_height); + */ -vo_driver_t *init_video_out_xshm () { + XLockDisplay (this->display); - int completionType = -1; - XWindowAttributes attribs; - int minor, major; - Bool bPixmaps; - XImage *myimage; - XShmSegmentInfo myshminfo; + /* + * (re-) allocate xvimage + */ - /* XLOCK (); */ + if (frame->image) { - gXshm.image_width=720; - gXshm.image_height=576; + dispose_ximage (this, &frame->shminfo, frame->image); + frame->image = NULL; + } - /* - * ok, X11, prepare for some video! - */ + frame->image = create_ximage (this, &frame->shminfo, + this->output_width, this->output_height); - gXshm.screen = DefaultScreen(gDisplay); + image_size = width * height; + frame->vo_frame.base[0] = xmalloc_aligned(16,image_size); + frame->vo_frame.base[1] = xmalloc_aligned(16,image_size/4); + frame->vo_frame.base[2] = xmalloc_aligned(16,image_size/4); - XGetWindowAttributes(gDisplay, DefaultRootWindow(gDisplay), &attribs); + frame->width = width; + frame->height = height; - /* - * - * depth in X11 terminology land is the number of bits used to - * actually represent the colour. - * - * bpp in X11 land means how many bits in the frame buffer per - * pixel. - * - * ex. 15 bit color is 15 bit depth and 16 bpp. Also 24 bit - * color is 24 bit depth, but can be 24 bpp or 32 bpp. - */ - - gXshm.depth = attribs.depth; + frame->rgb_width = this->output_width; + frame->rgb_height = this->output_height; - if (gXshm.depth != 15 && gXshm.depth != 16 && gXshm.depth != 24 && gXshm.depth != 32) { - /* The root window may be 8bit but there might still be - * visuals with other bit depths. For example this is the - * case on Sun/Solaris machines. - */ - gXshm.depth = 24; + XUnlockDisplay (this->display); } +} - XMatchVisualInfo(gDisplay, gXshm.screen, gXshm.depth, TrueColor, &gXshm.vinfo); +static void xshm_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) { - gXshm.bUseShm = 1; + xshm_driver_t *this = (xshm_driver_t *) this_gen; + xshm_frame_t *frame = (xshm_frame_t *) frame_gen; + + if (this->expecting_event) { + frame->vo_frame.displayed (&frame->vo_frame); + + } else { + + if ( (frame->rgb_width != this->dest_width) + || (frame->rgb_height != this->dest_height) ) { + + int width, height; /* too late for these -> ignored */ + + this->request_dest_size (frame->rgb_width, frame->rgb_height, + &this->dest_x, &this->dest_y, &width, &height); + + this->dest_width = frame->rgb_width; + this->dest_height = frame->rgb_height; - /* - * check for X shared memory support - */ + } + + XLockDisplay (this->display); - if (!XShmQueryExtension(gDisplay)) { - xprintf(VERBOSE|VIDEO, "Shared memory not supported\n\n"); - gXshm.bUseShm = 0; - goto finishShmTesting; - } + if (this->use_shm) { + + XShmPutImage(this->display, + this->drawable, this->gc, frame->image, + 0, 0, frame->rgb_width, frame->rgb_height, + frame->rgb_width, frame->rgb_height, True); + + this->expecting_event = 1; - if (!XShmQueryVersion (gDisplay, &major, &minor, &bPixmaps)){ - xprintf(VERBOSE|VIDEO, "Shared memory not supported\n\n"); - gXshm.bUseShm = 0; - goto finishShmTesting; + } else { + XPutImage(this->display, + this->drawable, this->gc, frame->image, + 0, 0, frame->rgb_width, frame->rgb_height, + frame->rgb_width, frame->rgb_height); + } + + XFlush(this->display); + + XUnlockDisplay (this->display); + + this->cur_frame = frame; } +} - xprintf (VERBOSE|VIDEO, "pixmaps : %d ?= %d\n", bPixmaps, True); +static int xshm_get_property (vo_driver_t *this_gen, int property) { + + xshm_driver_t *this = (xshm_driver_t *) this_gen; - if (!bPixmaps) { - xprintf(VERBOSE|VIDEO, "creation of shared pixmaps not possible\n\n"); - gXshm.bUseShm = 0; - goto finishShmTesting; + if ( property == VO_PROP_ASPECT_RATIO) { + return this->user_ratio ; + } else { + printf ("video_out_xshm: tried to get unsupported property %d\n", property); } + return 0; +} - completionType = XShmGetEventBase(gDisplay) + ShmCompletion; - - /* try to create shared image */ - gXshm.bFail = 0; - x11_InstallXErrorHandler (); +static int xshm_set_property (vo_driver_t *this_gen, + int property, int value) { - myimage = XShmCreateImage(gDisplay, - gXshm.vinfo.visual, - gXshm.vinfo.depth, - ZPixmap, NULL, - &myshminfo, - 100, - 100); + xshm_driver_t *this = (xshm_driver_t *) this_gen; - if (myimage == NULL ) { - xprintf(VERBOSE|VIDEO, "Shared memory error when allocating image => exit (Ximage error)\n"); - gXshm.bUseShm = 0; - x11_DeInstallXErrorHandler(); - goto finishShmTesting; + if ( property == VO_PROP_ASPECT_RATIO) { + if (value>ASPECT_DVB) + value = ASPECT_AUTO; + this->user_ratio = value; + } else { + printf ("video_out_xshm: tried to set unsupported property %d\n", property); } - - gXshm.bpp = myimage->bits_per_pixel; - gXshm.bytes_per_pixel = gXshm.bpp / 8; - myshminfo.shmid=shmget(IPC_PRIVATE, - myimage->bytes_per_line * myimage->height, - IPC_CREAT | 0777); - - if (myshminfo.shmid < 0 ) { - xprintf(VERBOSE|VIDEO, "%s: allocating image \n",strerror(errno)); - gXshm.bUseShm = 0; - x11_DeInstallXErrorHandler(); - goto finishShmTesting; - } - - myshminfo.shmaddr = (char *) shmat(myshminfo.shmid, 0, 0); - - if (myshminfo.shmaddr == ((char *) -1)) { - xprintf(VERBOSE|VIDEO, "Shared memory error (address error) when allocating image \n"); - gXshm.bUseShm = 0; - x11_DeInstallXErrorHandler(); - goto finishShmTesting; - } - - myshminfo.readOnly = False; - myimage->data = myshminfo.shmaddr; - - XShmAttach(gDisplay, &myshminfo); - - XSync(gDisplay, False); + return value; +} - if (gXshm.bFail) { - xprintf (VERBOSE|VIDEO, "Couldn't create shared memory image\n"); - gXshm.bUseShm = 0; - x11_DeInstallXErrorHandler(); - goto finishShmTesting; - } +static void xshm_get_property_min_max (vo_driver_t *this_gen, + int property, int *min, int *max) { - XShmDetach (gDisplay, &myshminfo); - XDestroyImage (myimage); - shmdt (myshminfo.shmaddr); - shmctl (myshminfo.shmid, IPC_RMID, 0); + /* xshm_driver_t *this = (xshm_driver_t *) this_gen; */ - x11_DeInstallXErrorHandler(); + *min = 0; + *max = 0; +} - finishShmTesting: +static int xshm_gui_data_exchange (vo_driver_t *this_gen, + int data_type, void *data) { - if (!gXshm.bUseShm) { - printf ("\n\n!!! failed to initialize X shared memory extension. Fall back to plain X11 functions. This is very slow and mostly untested. Are you sure you're using a local graphics device for output? Remote playing via network is not supported by xine!!!\n\n"); - } + xshm_driver_t *this = (xshm_driver_t *) this_gen; + /* x11_rectangle_t *area; */ + xshm_frame_t *frame; + switch (data_type) { + case GUI_DATA_EX_DEST_POS_SIZE_CHANGED: - /* - * init global variables - */ + /* area = (x11_rectangle_t *) data; */ - gXshm.bFullscreen = 0; - gXshm.bIsFullscreen = 0; - gXshm.ratio = 0; - gXshm.user_ratio = ASPECT_AUTO; - gXshm.user_ratio_changed = 0 ; - gXshm.bLogoMode = 1; - gXshm.bYuvInitialized = 0; - gXshm.cur_image = NULL; + xshm_calc_output_size (this); + break; + case GUI_DATA_EX_COMPLETION_EVENT: { + + XShmCompletionEvent *cev = (XShmCompletionEvent *) data; + + if (cev->drawable == this->drawable) { + this->expecting_event = 0; + + if (this->cur_frame) { + this->cur_frame->vo_frame.displayed (&this->cur_frame->vo_frame); + this->cur_frame = NULL; + } + } + + } + break; - set_image_format_xshm (720,576,1,IMGFMT_YV12); + case GUI_DATA_EX_EXPOSE_EVENT: + + /* FIXME : take care of completion events */ - create_cursor_xshm(DefaultColormap(gDisplay, 0)); - gXshm.current_cursor = SHOW_CURSOR; + if ((frame = this->cur_frame) != NULL) { - /* - * If gVo.depth is 24 then it may either be a 3 or 4 byte per pixel - * format. We can't use bpp because then we would lose the - * distinction between 15/16bit gVo.depth (2 byte formate assumed). - * - * FIXME - change yuv2rgb_init to take both gVo.depth and bpp - * parameters - */ + if (this->use_shm) { + + XShmPutImage(this->display, + this->drawable, this->gc, this->cur_frame->image, + 0, 0, this->cur_frame->width, this->cur_frame->height, + this->cur_frame->width, this->cur_frame->height, True); + + } else { + XPutImage(this->display, + this->drawable, this->gc, frame->image, + 0, 0, this->cur_frame->width, this->cur_frame->height, + this->cur_frame->width, this->cur_frame->height); + } - if (gXshm.depth>16) - printf ("\n\nWARNING: current display depth is %d. For better performance\na depth of 16 bpp is recommended!\n\n", - gXshm.depth); + } + break; - /* yuv2rgb_init((gXshm.depth == 24) ? gXshm.bpp : gXshm.depth,MODE_RGB); */ + case GUI_DATA_EX_DRAWABLE_CHANGED: + this->drawable = (Drawable) data; + this->gc = XCreateGC (this->display, this->drawable, 0, NULL); + break; + } - /* XUNLOCK (); */ + return 0; +} + +static void xshm_exit (vo_driver_t *this_gen) { + + /* xshm_driver_t *this = (xshm_driver_t *) this_gen; */ - return &vo_xshm; } + vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual_gen) { xshm_driver_t *this; + x11_visual_t *visual = (x11_visual_t *) visual_gen; Display *display = NULL; - unsigned int adaptor_num, adaptors, i, j, formats; - unsigned int ver,rel,req,ev,err; - int nattr; - x11_visual_t *visual; XColor dummy; + XWindowAttributes attribs; + XImage *myimage; + XShmSegmentInfo myshminfo; visual = (x11_visual_t *) visual_gen; display = visual->display; xine_debug = config->lookup_int (config, "xine_debug", 0); /* - * check for XShm support - */ - - if (Success != XvQueryExtension(display,&ver,&rel,&req,&ev,&err)) { - printf ("video_out_xv: Xv extension not present.\n"); - return NULL; - } - - /* - * check adaptors, search for one that supports (at least) yuv12 - */ - - if (Success != XvQueryAdaptors(display,DefaultRootWindow(display), - &adaptors,&adaptor_info)) { - printf("video_out_xv: XvQueryAdaptors failed.\n"); - return NULL; - } - - xshm_port = 0; - adaptor_num = 0; - - while ( (adaptor_num < adaptors) && !xshm_port) { - if (adaptor_info[adaptor_num].type & XvImageMask) - for (j = 0; j < adaptor_info[adaptor_num].num_ports; j++) - if (( !(xshm_check_yv12 (display, adaptor_info[adaptor_num].base_id + j))) - && (XvGrabPort (display, adaptor_info[adaptor_num].base_id + j, 0) == Success)) { - xshm_port = adaptor_info[adaptor_num].base_id + j; - break; - } - - adaptor_num++; - } - - - if (!xshm_port) { - printf ("video_out_xv: Xv extension is present but I couldn't find a usable yuv12 port.\n"); - printf (" Looks like your graphics hardware driver doesn't support Xv?!\n"); - XvFreeAdaptorInfo (adaptor_info); - return NULL; - } else - printf ("video_out_xv: using Xv port %d for hardware colorspace conversion and scaling.\n", xshm_port); - - /* - * from this point on, nothing should go wrong anymore; so let's start initializing this driver + * allocate plugin struct */ this = malloc (sizeof (xshm_driver_t)); @@ -1013,20 +674,19 @@ vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual_gen) { this->screen = visual->screen; this->display_ratio = visual->display_ratio; this->request_dest_size = visual->request_dest_size; + this->calc_dest_size = visual->calc_dest_size; this->output_xoffset = 0; this->output_yoffset = 0; this->output_width = 0; this->output_height = 0; this->drawable = visual->d; + this->expecting_event = 0; this->gc = XCreateGC (this->display, this->drawable, 0, NULL); - this->xshm_port = xshm_port; - this->capabilities = 0; XAllocNamedColor(this->display, DefaultColormap(this->display, this->screen), "black", &this->black, &dummy); - this->vo_driver.get_capabilities = xshm_get_capabilities; this->vo_driver.alloc_frame = xshm_alloc_frame; this->vo_driver.update_frame_format = xshm_update_frame_format; @@ -1038,106 +698,60 @@ vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual_gen) { this->vo_driver.exit = xshm_exit; /* - * init properties + * + * depth in X11 terminology land is the number of bits used to + * actually represent the colour. + * + * bpp in X11 land means how many bits in the frame buffer per + * pixel. + * + * ex. 15 bit color is 15 bit depth and 16 bpp. Also 24 bit + * color is 24 bit depth, but can be 24 bpp or 32 bpp. */ - - for (i=0; i<VO_NUM_PROPERTIES; i++) { - this->props[i].value = 0; - this->props[i].min = 0; - this->props[i].max = 0; - this->props[i].atom = None; - this->props[i].key = NULL; + + XGetWindowAttributes(display, DefaultRootWindow(display), &attribs); + this->depth = attribs.depth; + + if (this->depth != 15 && this->depth != 16 && this->depth != 24 && this->depth != 32) { + /* The root window may be 8bit but there might still be + * visuals with other bit depths. For example this is the + * case on Sun/Solaris machines. + */ + this->depth = 24; } - this->props[VO_PROP_INTERLACED].value = 0; - this->props[VO_PROP_ASPECT_RATIO].value = ASPECT_AUTO; + if (this->depth>16) + printf ("\n\nWARNING: current display depth is %d. For better performance\na depth of 16 bpp is recommended!\n\n", + this->depth); - /* - * check this adaptor's capabilities + XMatchVisualInfo(display, this->screen, this->depth, TrueColor, &this->vinfo); + + /* + * check for X shared memory support */ - attr = XvQueryPortAttributes(display, xshm_port, &nattr); - if(attr && nattr) { - int k; - - for(k = 0; k < nattr; k++) { - - if(attr[k].flags & XvSettable) { - if(!strcmp(attr[k].name, "XSHM_HUE")) { - xshm_check_capability (this, VO_CAP_HUE, - VO_PROP_HUE, attr[k], - adaptor_info[i].base_id, "XSHM_HUE"); - printf("XSHM_HUE "); - } - else if(!strcmp(attr[k].name, "XSHM_SATURATION")) { - xshm_check_capability (this, VO_CAP_SATURATION, - VO_PROP_SATURATION, attr[k], - adaptor_info[i].base_id, "XSHM_SATURATION"); - printf("XSHM_SATURATION "); - } - else if(!strcmp(attr[k].name, "XSHM_BRIGHTNESS")) { - xshm_check_capability (this, VO_CAP_BRIGHTNESS, - VO_PROP_BRIGHTNESS, attr[k], - adaptor_info[i].base_id, "XSHM_BRIGHTNESS"); - printf("XSHM_BRIGHTNESS "); - } - else if(!strcmp(attr[k].name, "XSHM_CONTRAST")) { - xshm_check_capability (this, VO_CAP_CONTRAST, - VO_PROP_CONTRAST, attr[k], - adaptor_info[i].base_id, "XSHM_CONTRAST"); - printf("XSHM_CONTRAST "); - } - else if(!strcmp(attr[k].name, "XSHM_COLORKEY")) { - xshm_check_capability (this, VO_CAP_COLORKEY, - VO_PROP_COLORKEY, attr[k], - adaptor_info[i].base_id, "XSHM_COLORKEY"); - printf("XSHM_COLORKEY "); - } - } - } - printf("\n"); - XFree(attr); + if (XShmQueryExtension(display)) { + this->use_shm = 1; } else { - printf("video_out_xv: no port attributes defined.\n"); + printf ("video_out_xshm: MIT shared memory extension not present on display.\n"); + this->use_shm = 0; } - XvFreeAdaptorInfo (adaptor_info); - /* - * check supported image formats + * try to create shared image + * to find out if MIT shm really works + * and what bpp it uses */ - fo = XvListImageFormats(display, this->xshm_port, (int*)&formats); + myimage = create_ximage (this, &myshminfo, 100, 100); + dispose_ximage (this, &myshminfo, myimage); - this->xshm_format_yv12 = 0; - this->xshm_format_yuy2 = 0; - this->xshm_format_rgb = 0; - - for(i = 0; i < formats; i++) { - xprintf(VERBOSE|VIDEO, "video_out_xv: Xv 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 == IMGFMT_YV12) { - this->xshm_format_yv12 = fo[i].id; - this->capabilities |= VO_CAP_YV12; - printf ("video_out_xv: this adaptor supports the yv12 format.\n"); - } else if (fo[i].id == IMGFMT_YUY2) { - this->xshm_format_yuy2 = fo[i].id; - this->capabilities |= VO_CAP_YUY2; - printf ("video_out_xv: this adaptor supports the yuy2 format.\n"); - } else if (fo[i].id == IMGFMT_RGB) { - this->xshm_format_rgb = fo[i].id; - this->capabilities |= VO_CAP_RGB; - printf ("video_out_xv: this adaptor supports the rgb format.\n"); - } - } + this->yuv2rgb = yuv2rgb_init (MODE_16_RGB); /* FIXME mode */ return &this->vo_driver; } - - -static vo_info_t vo_info_xv = { +static vo_info_t vo_info_shm = { VIDEO_OUT_IFACE_VERSION, "XShm", "xine video output plugin using the MIT X shared memory extension", @@ -1146,6 +760,6 @@ static vo_info_t vo_info_xv = { }; vo_info_t *get_video_out_plugin_info() { - return &vo_info_xv; + return &vo_info_shm; } diff --git a/src/video_out/video_out_xv.c b/src/video_out/video_out_xv.c index 9c4121467..1b7b32802 100644 --- a/src/video_out/video_out_xv.c +++ b/src/video_out/video_out_xv.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: video_out_xv.c,v 1.33 2001/06/03 19:41:05 guenter Exp $ + * $Id: video_out_xv.c,v 1.34 2001/06/04 15:04:13 guenter Exp $ * * video_out_xv.c, X11 video extension interface for xine * @@ -146,13 +146,15 @@ static void xv_frame_dispose (vo_frame_t *vo_img) { xv_frame_t *frame = (xv_frame_t *) vo_img ; xv_driver_t *this = (xv_driver_t *) vo_img->instance->driver; - XLockDisplay (this->display); - XShmDetach (this->display, &frame->shminfo); - XFree (frame->image); - XUnlockDisplay (this->display); + if (frame->image) { + XLockDisplay (this->display); + XShmDetach (this->display, &frame->shminfo); + XFree (frame->image); + XUnlockDisplay (this->display); - shmdt (frame->shminfo.shmaddr); - shmctl (frame->shminfo.shmid, IPC_RMID,NULL); + shmdt (frame->shminfo.shmaddr); + shmctl (frame->shminfo.shmid, IPC_RMID,NULL); + } free (frame); } @@ -746,6 +748,7 @@ vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual_gen) { this->gc = XCreateGC (this->display, this->drawable, 0, NULL); this->xv_port = xv_port; this->capabilities = 0; + this->expecting_event = 0; XAllocNamedColor(this->display, DefaultColormap(this->display, this->screen), |