summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libw32dll/wine/Makefile.am2
-rw-r--r--src/video_out/video_out_xshm.c22
-rw-r--r--src/video_out/video_out_xv.c319
-rw-r--r--src/xine-engine/metronom.c4
-rw-r--r--src/xine-engine/video_decoder.c4
-rw-r--r--src/xine-engine/video_out.c34
6 files changed, 277 insertions, 108 deletions
diff --git a/src/libw32dll/wine/Makefile.am b/src/libw32dll/wine/Makefile.am
index 711758b16..9c32a5bdc 100644
--- a/src/libw32dll/wine/Makefile.am
+++ b/src/libw32dll/wine/Makefile.am
@@ -28,7 +28,7 @@ noinst_HEADERS = avifmt.h elfdll.h msacm.h pshpack1.h winbase.h \
pshpack4.h windows.h winuser.h debugtools.h mmreg.h \
pe_image.h pshpack8.h winerror.h driver.h module.h \
poppack.h vfw.h loader.h registry.h win32.h \
- wineacm.h winestring.h
+ wineacm.h winestring.h config.h
stubs.lo: stubs.s
$(CC) -c $(top_srcdir)/src/libw32dll/wine/stubs.s -o stubs.lo
diff --git a/src/video_out/video_out_xshm.c b/src/video_out/video_out_xshm.c
index 3fac1dad7..7c52d9745 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.10 2001/06/21 17:34:24 guenter Exp $
+ * $Id: video_out_xshm.c,v 1.11 2001/06/24 22:20:26 guenter Exp $
*
* video_out_xshm.c, X11 shared memory extension interface for xine
*
@@ -188,7 +188,7 @@ static XImage *create_ximage (xshm_driver_t *this, XShmSegmentInfo *shminfo,
if (myimage == NULL ) {
printf ("video_out_xshm: shared memory error when allocating image\n");
- printf ("=> not using MIT Shared Memory extension.\n");
+ printf ("video_out_xshm: => not using MIT Shared Memory extension.\n");
this->use_shm = 0;
goto finishShmTesting;
}
@@ -573,8 +573,6 @@ static void xshm_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) {
xshm_driver_t *this = (xshm_driver_t *) this_gen;
xshm_frame_t *frame = (xshm_frame_t *) frame_gen;
- /* printf ("video_out_xshm: display frame %d\n", frame); */
-
if (this->expecting_event) {
this->expecting_event--;
@@ -608,16 +606,20 @@ static void xshm_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) {
this->expecting_event = 10;
+ XFlush(this->display);
+
} else {
+
XPutImage(this->display,
this->drawable, this->gc, frame->image,
0, 0, 0, 0,
frame->rgb_width, frame->rgb_height);
+
+ XFlush(this->display);
+
frame->vo_frame.displayed (&frame->vo_frame);
}
- XFlush(this->display);
-
XUnlockDisplay (this->display);
}
@@ -703,6 +705,8 @@ static int xshm_gui_data_exchange (vo_driver_t *this_gen,
if (xev->count == 0) {
+ XLockDisplay (this->display);
+
if (this->use_shm) {
XShmPutImage(this->display,
@@ -712,11 +716,15 @@ static int xshm_gui_data_exchange (vo_driver_t *this_gen,
False);
} else {
+
XPutImage(this->display,
this->drawable, this->gc, this->cur_frame->image,
0, 0, this->output_xoffset, this->output_yoffset,
this->cur_frame->rgb_width, this->cur_frame->rgb_height);
}
+ XFlush (this->display);
+
+ XUnlockDisplay (this->display);
}
}
@@ -835,7 +843,7 @@ vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual_gen) {
}
/*
- * try to create shared image
+ * try to create a shared image
* to find out if MIT shm really works
* and what bpp it uses
*/
diff --git a/src/video_out/video_out_xv.c b/src/video_out/video_out_xv.c
index eb9d0bb5c..7c77a53cc 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.44 2001/06/18 15:43:00 richwareham Exp $
+ * $Id: video_out_xv.c,v 1.45 2001/06/24 22:20:26 guenter Exp $
*
* video_out_xv.c, X11 video extension interface for xine
*
@@ -50,6 +50,7 @@
#include <string.h>
#include "monitor.h"
+#include "utils.h"
#include "video_out.h"
#include "video_out_x11.h"
#include "xine_internal.h"
@@ -95,6 +96,7 @@ typedef struct {
XvPortID xv_port;
XColor black;
int expecting_event; /* completion event handling */
+ int use_shm;
xv_property_t props[VO_NUM_PROPERTIES];
uint32_t capabilities;
@@ -127,9 +129,8 @@ typedef struct {
} xv_driver_t;
-/*
- *
- */
+int gX11Fail;
+
static uint32_t xv_get_capabilities (vo_driver_t *this_gen) {
xv_driver_t *this = (xv_driver_t *) this_gen;
@@ -186,9 +187,174 @@ static vo_frame_t *xv_alloc_frame (vo_driver_t *this_gen) {
return (vo_frame_t *) frame;
}
-/*
- *
- */
+int HandleXError (Display *display, XErrorEvent *xevent) {
+
+ char str [1024];
+
+ XGetErrorText (display, xevent->error_code, str, 1024);
+
+ printf ("received X error event: %s\n", str);
+
+ gX11Fail = 1;
+ return 0;
+
+}
+
+static void x11_InstallXErrorHandler (xv_driver_t *this)
+{
+ XSetErrorHandler (HandleXError);
+ XFlush (this->display);
+}
+
+static void x11_DeInstallXErrorHandler (xv_driver_t *this)
+{
+ XSetErrorHandler (NULL);
+ XFlush (this->display);
+}
+
+static XvImage *create_ximage (xv_driver_t *this, XShmSegmentInfo *shminfo,
+ int width, int height, int format) {
+
+ unsigned int xv_format;
+ XvImage *image;
+
+ switch (format) {
+ case IMGFMT_YV12:
+ xv_format = this->xv_format_yv12;
+ break;
+ case IMGFMT_RGB:
+ xv_format = this->xv_format_rgb;
+ break;
+ case IMGFMT_YUY2:
+ xv_format = this->xv_format_yuy2;
+ break;
+ default:
+ fprintf (stderr, "create_ximage: unknown format %08x\n",format);
+ exit (1);
+ }
+
+ if (this->use_shm) {
+
+ /*
+ * try shm
+ */
+
+ gX11Fail = 0;
+ x11_InstallXErrorHandler (this);
+
+ image = XvShmCreateImage(this->display, this->xv_port, xv_format, 0,
+ width, height, shminfo);
+
+ if (image == NULL ) {
+ printf("video_out_xv: XvShmCreateImage failed\n");
+ printf("video_out_xv: => not using MIT Shared Memory extension.\n");
+ this->use_shm = 0;
+ goto finishShmTesting;
+ }
+
+ shminfo->shmid=shmget(IPC_PRIVATE,
+ image->data_size,
+ IPC_CREAT | 0777);
+
+ if (image->data_size==0) {
+ printf("video_out_xv: XvShmCreateImage returned a zero size\n");
+ printf("video_out_xv: => not using MIT Shared Memory extension.\n");
+ this->use_shm = 0;
+ goto finishShmTesting;
+ }
+
+ if (shminfo->shmid < 0 ) {
+ perror("video_out_xv: shared memory error in shmget: ");
+ printf("video_out_xv: => not using MIT Shared Memory extension.\n");
+ this->use_shm = 0;
+ goto finishShmTesting;
+ }
+
+ shminfo->shmaddr = (char *) shmat(shminfo->shmid, 0, 0);
+
+ if (shminfo->shmaddr == NULL) {
+ printf("video_out_xv: shared memory error (address error NULL)\n");
+ this->use_shm = 0;
+ goto finishShmTesting;
+ }
+
+ if (shminfo->shmaddr == ((char *) -1)) {
+ printf("video_out_xv: shared memory error (address error)\n");
+ this->use_shm = 0;
+ goto finishShmTesting;
+ }
+
+ shminfo->readOnly = False;
+ image->data = shminfo->shmaddr;
+
+ XShmAttach(this->display, shminfo);
+
+ XSync(this->display, False);
+ shmctl(shminfo->shmid, IPC_RMID, 0);
+
+ if (gX11Fail) {
+ printf ("video_out_xv: x11 error during shared memory XImage creation\n");
+ printf ("video_out_xv: => not using MIT Shared Memory extension.\n");
+ shmdt (shminfo->shmaddr);
+ shmctl (shminfo->shmid, IPC_RMID, 0);
+ shminfo->shmid = -1;
+ this->use_shm = 0;
+ goto finishShmTesting;
+ }
+
+ /*
+ * Now that the Xserver has learned about and attached to the
+ * shared memory segment, delete it. It's actually deleted by
+ * the kernel when all users of that segment have detached from
+ * it. Gives an automatic shared memory cleanup in case we crash.
+ */
+ shmctl (shminfo->shmid, IPC_RMID, 0);
+ shminfo->shmid = -1;
+
+ finishShmTesting:
+ x11_DeInstallXErrorHandler(this);
+ }
+
+
+ /*
+ * fall back to plain Xv if necessary
+ */
+
+ if (!this->use_shm) {
+
+ char *data;
+
+ data = xmalloc (width * height * 3/2);
+
+ image = XvCreateImage (this->display, this->xv_port,
+ xv_format, data, width, height);
+
+
+ }
+ return image;
+}
+
+static void dispose_ximage (xv_driver_t *this,
+ XShmSegmentInfo *shminfo,
+ XvImage *myimage) {
+
+ if (this->use_shm) {
+
+ XShmDetach (this->display, shminfo);
+ XFree (myimage);
+ shmdt (shminfo->shmaddr);
+ if (shminfo->shmid >= 0) {
+ shmctl (shminfo->shmid, IPC_RMID, 0);
+ shminfo->shmid = -1;
+ }
+
+ } else {
+
+ XFree (myimage);
+
+ }
+}
+
static void xv_update_frame_format (vo_driver_t *this_gen,
vo_frame_t *frame_gen,
uint32_t width, uint32_t height,
@@ -196,7 +362,6 @@ static void xv_update_frame_format (vo_driver_t *this_gen,
xv_driver_t *this = (xv_driver_t *) this_gen;
xv_frame_t *frame = (xv_frame_t *) frame_gen;
- unsigned int xv_format;
if ((frame->width != width)
|| (frame->height != height)
@@ -211,77 +376,12 @@ static void xv_update_frame_format (vo_driver_t *this_gen,
*/
if (frame->image) {
- XShmDetach (this->display, &frame->shminfo);
-
- XFree (frame->image);
- shmdt (frame->shminfo.shmaddr);
- shmctl (frame->shminfo.shmid, IPC_RMID,NULL);
-
+ dispose_ximage (this, &frame->shminfo, frame->image);
frame->image = NULL;
}
- switch (format) {
- case IMGFMT_YV12:
- xv_format = this->xv_format_yv12;
- break;
- case IMGFMT_RGB:
- xv_format = this->xv_format_rgb;
- break;
- case IMGFMT_YUY2:
- xv_format = this->xv_format_yuy2;
- break;
- default:
- fprintf (stderr, "xv_update_frame_format: unknown format %08x\n",format);
- exit (1);
- }
-
- frame->image = XvShmCreateImage(this->display, this->xv_port, xv_format, 0,
- width, height, &frame->shminfo);
-
- if (frame->image == NULL ) {
- fprintf(stderr, "xv_image_format: XvShmCreateImage failed.\n");
- exit (1);
- }
-
- frame->shminfo.shmid=shmget(IPC_PRIVATE,
- frame->image->data_size,
- IPC_CREAT | 0777);
-
- if (frame->image->data_size==0) {
- fprintf(stderr, "xv_update_frame_format: XvShmCreateImage "
- "returned a zero size\n");
- exit (1);
- }
-
- if (frame->shminfo.shmid < 0 ) {
- perror("xv_update_frame_format: shared memory error in shmget: ");
- exit (1);
- }
+ frame->image = create_ximage (this, &frame->shminfo, width, height, format);
- frame->shminfo.shmaddr = (char *) shmat(frame->shminfo.shmid, 0, 0);
-
- if (frame->shminfo.shmaddr == NULL) {
- fprintf(stderr, "xv_update_frame_format: shared memory "
- "error (address error NULL)\n");
- exit (1);
- }
-
- if (frame->shminfo.shmaddr == ((char *) -1)) {
- fprintf(stderr, "xv_update_frame_format: shared memory "
- "error (address error)\n");
- exit (1);
- }
-
- frame->shminfo.readOnly = False;
- frame->image->data = frame->shminfo.shmaddr;
-
- /* memset (frame->image->data,0,frame->image->data_size); */
-
- XShmAttach(this->display, &frame->shminfo);
-
- XSync(this->display, False);
- shmctl(frame->shminfo.shmid, IPC_RMID, 0);
-
frame->vo_frame.base[0] = frame->image->data;
frame->vo_frame.base[1] = frame->image->data + width * height * 5 / 4;
frame->vo_frame.base[2] = frame->image->data + width * height;
@@ -326,6 +426,7 @@ static void xv_adapt_to_output_area (xv_driver_t *this,
* clear unused output area
*/
+ XLockDisplay (this->display);
XSetForeground (this->display, this->gc, this->black.pixel);
XFillRectangle(this->display, this->drawable, this->gc,
@@ -343,7 +444,7 @@ static void xv_adapt_to_output_area (xv_driver_t *this,
this->output_xoffset+this->output_width, dest_y,
dest_width - this->output_xoffset - this->output_width,
dest_height);
-
+ XUnlockDisplay (this->display);
}
/*
@@ -470,13 +571,22 @@ static void xv_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) {
XLockDisplay (this->display);
this->cur_frame = frame;
- XvShmPutImage(this->display, this->xv_port,
- this->drawable, this->gc, frame->image,
- 0, 0, frame->width, frame->height-5,
- this->output_xoffset, this->output_yoffset,
- this->output_width, this->output_height, True);
-
- this->expecting_event = 10;
+
+ if (this->use_shm) {
+ XvShmPutImage(this->display, this->xv_port,
+ this->drawable, this->gc, frame->image,
+ 0, 0, frame->width, frame->height-5,
+ this->output_xoffset, this->output_yoffset,
+ this->output_width, this->output_height, True);
+
+ this->expecting_event = 10;
+ } else {
+ XvPutImage(this->display, this->xv_port,
+ this->drawable, this->gc, frame->image,
+ 0, 0, frame->width, frame->height-5,
+ this->output_xoffset, this->output_yoffset,
+ this->output_width, this->output_height);
+ }
XFlush(this->display);
@@ -587,12 +697,26 @@ static int xv_gui_data_exchange (vo_driver_t *this_gen,
/* FIXME : take care of completion events */
if (xev->count == 0) {
- if (this->cur_frame)
- XvShmPutImage(this->display, this->xv_port,
- this->drawable, this->gc, this->cur_frame->image,
- 0, 0, this->cur_frame->width, this->cur_frame->height-5,
- this->output_xoffset, this->output_yoffset,
- this->output_width, this->output_height, False);
+ if (this->cur_frame) {
+ XLockDisplay (this->display);
+
+ if (this->use_shm) {
+ XvShmPutImage(this->display, this->xv_port,
+ this->drawable, this->gc, this->cur_frame->image,
+ 0, 0, this->cur_frame->width, this->cur_frame->height-5,
+ this->output_xoffset, this->output_yoffset,
+ this->output_width, this->output_height, False);
+ } else {
+ XvPutImage(this->display, this->xv_port,
+ this->drawable, this->gc, this->cur_frame->image,
+ 0, 0, this->cur_frame->width, this->cur_frame->height-5,
+ this->output_xoffset, this->output_yoffset,
+ this->output_width, this->output_height);
+ }
+ XFlush(this->display);
+
+ XUnlockDisplay (this->display);
+ }
}
}
break;
@@ -613,9 +737,11 @@ static void xv_exit (vo_driver_t *this_gen) {
xv_driver_t *this = (xv_driver_t *) this_gen;
+ XLockDisplay (this->display);
if(XvUngrabPort (this->display, this->xv_port, CurrentTime) != Success) {
fprintf(stderr, "xv_exit: XvUngrabPort() failed.\n");
}
+ XUnlockDisplay (this->display);
}
/*
@@ -676,6 +802,8 @@ vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual_gen) {
int nattr;
x11_visual_t *visual = (x11_visual_t *) visual_gen;
XColor dummy;
+ XvImage *myimage;
+ XShmSegmentInfo myshminfo;
display = visual->display;
xine_debug = config->lookup_int (config, "xine_debug", 0);
@@ -685,7 +813,7 @@ vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual_gen) {
*/
if (Success != XvQueryExtension(display,&ver,&rel,&req,&ev,&err)) {
- fprintf (stderr, "video_out_xv: Xv extension not present.\n");
+ printf ("video_out_xv: Xv extension not present.\n");
return NULL;
}
@@ -695,7 +823,7 @@ vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual_gen) {
if (Success != XvQueryAdaptors(display,DefaultRootWindow(display),
&adaptors,&adaptor_info)) {
- fprintf(stderr, "video_out_xv: XvQueryAdaptors failed.\n");
+ printf("video_out_xv: XvQueryAdaptors failed.\n");
return NULL;
}
@@ -869,6 +997,15 @@ vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual_gen) {
}
}
+ /*
+ * try to create a shared image
+ * to find out if MIT shm really works
+ */
+
+ myimage = create_ximage (this, &myshminfo, 100, 100, IMGFMT_YV12);
+ dispose_ximage (this, &myshminfo, myimage);
+
+
return &this->vo_driver;
}
diff --git a/src/xine-engine/metronom.c b/src/xine-engine/metronom.c
index 6dbac7d92..3871ddf68 100644
--- a/src/xine-engine/metronom.c
+++ b/src/xine-engine/metronom.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: metronom.c,v 1.10 2001/06/24 02:19:29 guenter Exp $
+ * $Id: metronom.c,v 1.11 2001/06/24 22:20:26 guenter Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -297,7 +297,7 @@ static uint32_t metronom_got_video_frame (metronom_t *this, uint32_t pts) {
* for too long
*/
- if ( !this->audio_stream_starting
+ if ( !this->audio_stream_starting && this->have_audio
&& (this->video_wrap_offset != this->audio_wrap_offset)) {
this->wrap_diff_counter++;
diff --git a/src/xine-engine/video_decoder.c b/src/xine-engine/video_decoder.c
index 2a6ba6cc6..77cc12e54 100644
--- a/src/xine-engine/video_decoder.c
+++ b/src/xine-engine/video_decoder.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_decoder.c,v 1.27 2001/06/24 04:32:36 guenter Exp $
+ * $Id: video_decoder.c,v 1.28 2001/06/24 22:20:26 guenter Exp $
*
*/
@@ -43,7 +43,7 @@ void *video_decoder_loop (void *this_gen) {
if (buf->input_pos)
this->cur_input_pos = buf->input_pos;
- /* printf ("video_decoder: got buffer %d\n", buf->type); */
+ /* printf ("video_decoder: got buffer %d\n", buf->type); */
switch (buf->type) {
case BUF_CONTROL_START:
diff --git a/src/xine-engine/video_out.c b/src/xine-engine/video_out.c
index b497799ce..80bfd7b83 100644
--- a/src/xine-engine/video_out.c
+++ b/src/xine-engine/video_out.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.c,v 1.25 2001/06/21 17:34:24 guenter Exp $
+ * $Id: video_out.c,v 1.26 2001/06/24 22:20:26 guenter Exp $
*
*/
@@ -93,6 +93,7 @@ static vo_frame_t *vo_remove_from_img_buf_queue (img_buf_fifo_t *queue) {
pthread_mutex_lock (&queue->mutex);
while (!queue->first) {
+ /* printf ("video_out: queue %d empty...\n", queue); */
pthread_cond_wait (&queue->bNotEmpty, &queue->mutex);
}
@@ -235,10 +236,11 @@ static void *video_out_loop (void *this_gen) {
img = vo_remove_from_img_buf_queue (this->display_img_buf_queue);
pthread_mutex_lock (&img->mutex);
+ img->bDisplayLock = 0;
+
if (!img->bDecoderLock)
vo_append_to_img_buf_queue (this->free_img_buf_queue, img);
- img->bDisplayLock = 0;
pthread_mutex_unlock (&img->mutex);
img = this->display_img_buf_queue->first;
@@ -276,9 +278,10 @@ static void *video_out_loop (void *this_gen) {
pthread_mutex_unlock (&img->mutex);
/* Overlay SPU FIXME: Check image format */
+
this->spu_decoder->overlay_yuv (this->spu_decoder, pts,
img->base[0], img->base[1], img->base[2]);
-
+
xprintf (VERBOSE|VIDEO, "video_out : passing to video driver, image with pts = %d\n", pts);
this->driver->display_frame (this->driver, img);
}
@@ -326,6 +329,11 @@ static vo_frame_t *vo_get_frame (vo_instance_t *this,
vo_frame_t *img;
+ /*
+ printf ("video_out: get_frame %d x %d from queue %d\n",
+ width, height, this->free_img_buf_queue);
+ */
+
if (this->pts_per_frame != duration) {
this->pts_per_frame = duration;
this->pts_per_half_frame = duration / 2;
@@ -418,7 +426,10 @@ static int vo_frame_draw (vo_frame_t *img) {
this->num_frames_delivered++;
xprintf (VERBOSE|VIDEO,"video_out: got image. vpts for picture is %d\n", pic_vpts);
-
+ /*
+ printf ("video_out: got image %d. vpts for picture is %d\n",
+ img, pic_vpts);
+ */
cur_vpts = this->metronom->get_current_time(this->metronom);
diff = pic_vpts - cur_vpts;
@@ -433,6 +444,12 @@ static int vo_frame_draw (vo_frame_t *img) {
this->num_frames_discarded++;
xprintf (VERBOSE|VIDEO, "vo_frame_draw: rejected, %d frames to skip\n", frames_to_skip);
+ pthread_mutex_lock (&img->mutex);
+ img->bDisplayLock = 0;
+ pthread_mutex_unlock (&img->mutex);
+
+ vo_frame_displayed (img);
+
return frames_to_skip;
}
@@ -451,9 +468,16 @@ static int vo_frame_draw (vo_frame_t *img) {
vo_append_to_img_buf_queue (this->display_img_buf_queue, img);
- } else
+ } else {
this->num_frames_skipped++;
+ pthread_mutex_lock (&img->mutex);
+ img->bDisplayLock = 0;
+ pthread_mutex_unlock (&img->mutex);
+
+ vo_frame_displayed (img);
+ }
+
/*
* performance measurement
*/