summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/demuxers/demux_avi.c9
-rw-r--r--src/video_out/Makefile.am9
-rw-r--r--src/video_out/video_out_xshm.c1264
-rw-r--r--src/video_out/video_out_xv.c17
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),