summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog3
-rw-r--r--src/video_out/video_out_xxmc.c250
-rw-r--r--src/video_out/xxmc.h7
3 files changed, 140 insertions, 120 deletions
diff --git a/ChangeLog b/ChangeLog
index 9c0a538eb..8879429de 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -5,6 +5,9 @@ xine-lib (1-xxx)
* fix playback of MMS streams with the new input cache layer [bug #1066926]
* fixed builds without X11 [bug #1067705]
* added support for 24-bit LPCM from DVDs
+ * Fixed segfault in xxmc plugin when switch from software decoding to
+ accelerated decoding occured while software surfaces still needed to be
+ duplicated.
xine-lib (1-rc7)
* Build system improvements: replacement functions, better work with headers
diff --git a/src/video_out/video_out_xxmc.c b/src/video_out/video_out_xxmc.c
index 988671df0..95e80cec4 100644
--- a/src/video_out/video_out_xxmc.c
+++ b/src/video_out/video_out_xxmc.c
@@ -18,7 +18,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_xxmc.c,v 1.8 2004/11/14 20:38:28 totte67 Exp $
+ * $Id: video_out_xxmc.c,v 1.9 2004/11/19 08:56:30 totte67 Exp $
*
* video_out_xxmc.c, X11 decoding accelerated video extension interface for xine
*
@@ -914,41 +914,9 @@ static void xvmc_check_colorkey_properties(xxmc_driver_t *driver)
}
XFree(xvmc_attributes);
XVMCUNLOCKDISPLAY( driver->display );
-
- /*
- * If we have a shape X11OSD, switch to colorkey X11OSD since we have a
- * colorkey XvMC surface.
- */
-
- if ( driver->xoverlay ) {
- if ( !driver->xoverlay_ck) {
- XLockDisplay( driver->display );
- x11osd_destroy( driver->xoverlay );
- driver->xoverlay = x11osd_create( driver->xine, driver->display,
- driver->screen, driver->drawable,
- X11OSD_COLORKEY);
- if ( driver->xoverlay ) {
- x11osd_colorkey( driver->xoverlay, driver->colorkey, &driver->sc);
- driver->xoverlay_ck = 1;
- }
- }
- }
+ driver->xvmc_xoverlay_type = X11OSD_COLORKEY;
} else {
-
- /*
- * Not a colorkey XvMC surface. Switch to shape X11OSD
- */
-
- if ( driver->xoverlay ) {
- if ( driver->xoverlay_ck ) {
- XLockDisplay( driver->display );
- x11osd_destroy( driver->xoverlay );
- driver->xoverlay = x11osd_create( driver->xine, driver->display,
- driver->screen, driver->drawable,
- X11OSD_SHAPED);
- driver->xoverlay_ck = 0;
- }
- }
+ driver->xvmc_xoverlay_type = X11OSD_SHAPED;
}
}
@@ -1096,46 +1064,14 @@ static void dispose_ximage (xxmc_driver_t *this,
}
-static void xxmc_do_update_frame(vo_driver_t *this_gen,
- vo_frame_t *frame_gen,
- uint32_t width, uint32_t height,
- double ratio, int format, int flags) {
-
+static void xxmc_do_update_frame_xv(vo_driver_t *this_gen,
+ vo_frame_t *frame_gen,
+ uint32_t width, uint32_t height,
+ double ratio, int format, int flags)
+{
xxmc_driver_t *this = (xxmc_driver_t *) this_gen;
xxmc_frame_t *frame = (xxmc_frame_t *) frame_gen;
- if ( XINE_IMGFMT_XXMC == format ) {
- xine_xxmc_t *xxmc = &frame->xxmc_data;
-
- xvmc_context_writer_lock( &this->xvmc_lock);
- if ((this->last_accel_request != xxmc->acceleration) ||
- (this->xvmc_mpeg != xxmc->mpeg) ||
- (this->xvmc_width != width) ||
- (this->xvmc_height != height)) {
- this->last_accel_request = xxmc->acceleration;
- xxmc_xvmc_update_context(this, frame, width, height);
- this->fallback_used = 0;
- }
-
- if (this->contextActive)
- xxmc_frame_updates(this, frame);
-
- format = xxmc->fallback_format;
-
- if (!this->contextActive) {
- this->fallback_used = 1;
- xxmc->acceleration = 0;
- xxmc->xvmc.macroblocks = 0;
- frame->vo_frame.proc_duplicate_frame_data = NULL;
- }
- xvmc_context_writer_unlock( &this->xvmc_lock);
-
- } else {
- frame->vo_frame.proc_duplicate_frame_data = NULL;
- if (!this->fallback_used) this->last_accel_request = 0;
- xxmc_dispose_context( this );
- }
-
if (this->use_pitch_alignment) {
width = (width + 7) & ~0x7;
}
@@ -1173,13 +1109,59 @@ static void xxmc_do_update_frame(vo_driver_t *this_gen,
XUnlockDisplay (this->display);
}
+
frame->ratio = ratio;
frame->width = width;
frame->height = height;
- frame->format = (this->contextActive) ? XINE_IMGFMT_XXMC : format;
+ frame->format = format;
frame->vo_frame.format = frame->format;
}
+
+static void xxmc_do_update_frame(vo_driver_t *this_gen,
+ vo_frame_t *frame_gen,
+ uint32_t width, uint32_t height,
+ double ratio, int format, int flags) {
+
+ xxmc_driver_t *this = (xxmc_driver_t *) this_gen;
+ xxmc_frame_t *frame = (xxmc_frame_t *) frame_gen;
+
+ if ( XINE_IMGFMT_XXMC == format ) {
+ xine_xxmc_t *xxmc = &frame->xxmc_data;
+
+ xvmc_context_writer_lock( &this->xvmc_lock);
+ if ((this->last_accel_request != xxmc->acceleration) ||
+ (this->xvmc_mpeg != xxmc->mpeg) ||
+ (this->xvmc_width != width) ||
+ (this->xvmc_height != height)) {
+ this->last_accel_request = xxmc->acceleration;
+ xxmc_xvmc_update_context(this, frame, width, height);
+ }
+
+ if (this->contextActive)
+ xxmc_frame_updates(this, frame);
+
+ xxmc_do_update_frame_xv(this_gen, frame_gen, width, height, ratio,
+ xxmc->fallback_format, flags);
+
+ if (!this->contextActive) {
+ xxmc->acceleration = 0;
+ xxmc->xvmc.macroblocks = 0;
+ frame->vo_frame.proc_duplicate_frame_data = NULL;
+ } else {
+ frame->format = format;
+ frame->vo_frame.format = format;
+ }
+
+ xvmc_context_writer_unlock( &this->xvmc_lock);
+
+ } else {
+ frame->vo_frame.proc_duplicate_frame_data = NULL;
+ xxmc_do_update_frame_xv(this_gen, frame_gen, width, height, ratio,
+ format, flags);
+ }
+}
+
static void xxmc_update_frame_format(vo_driver_t *this_gen,
vo_frame_t *frame_gen,
uint32_t width, uint32_t height,
@@ -1209,8 +1191,8 @@ static void xxmc_update_frame_format(vo_driver_t *this_gen,
* From Xv.
*/
-static void xxmc_clean_output_area (xxmc_driver_t *this) {
- int i, autopainting;
+static int xxmc_clean_output_area (xxmc_driver_t *this, int xvmc_active) {
+ int i, autopainting, ret;
XLockDisplay (this->display);
@@ -1232,15 +1214,18 @@ static void xxmc_clean_output_area (xxmc_driver_t *this) {
*/
autopainting = (this->props[VO_PROP_AUTOPAINT_COLORKEY].value == 1);
- if ((this->contextActive &&
+ if ((xvmc_active &&
(this->context_flags & XVMC_OVERLAID_SURFACE) &&
(! this->have_xvmc_autopaint ||
! autopainting)) ||
- (! this->contextActive && !autopainting)) {
+ (! xvmc_active && !autopainting)) {
XSetForeground (this->display, this->gc, this->colorkey);
XFillRectangle (this->display, this->drawable, this->gc,
this->sc.output_xoffset, this->sc.output_yoffset,
this->sc.output_width, this->sc.output_height);
+ ret = 1;
+ } else {
+ ret = 0;
}
if (this->xoverlay) {
@@ -1249,6 +1234,7 @@ static void xxmc_clean_output_area (xxmc_driver_t *this) {
}
XUnlockDisplay (this->display);
+ return ret;
}
/*
@@ -1271,21 +1257,49 @@ static void xxmc_compute_output_size (xxmc_driver_t *this) {
}
+
+static void xxmc_check_xoverlay_type(xxmc_driver_t *driver, xxmc_frame_t *frame)
+
+{
+ int
+ new_overlay_type = (frame->format == XINE_IMGFMT_XXMC) ?
+ driver->xvmc_xoverlay_type : driver->xv_xoverlay_type;
+ if (driver->xoverlay_type != new_overlay_type) {
+ printf("Warning! Changing xoverlay\n");
+ x11osd_destroy( driver->xoverlay );
+ driver->xoverlay = x11osd_create( driver->xine, driver->display,
+ driver->screen, driver->drawable,
+ new_overlay_type);
+ driver->xoverlay_type = new_overlay_type;
+ }
+}
+
+
static void xxmc_overlay_begin (vo_driver_t *this_gen,
vo_frame_t *frame_gen, int changed) {
xxmc_driver_t *this = (xxmc_driver_t *) this_gen;
+ xxmc_frame_t *frame = (xxmc_frame_t *) frame_gen;
+
this->ovl_changed += changed;
+ xvmc_context_reader_lock( &this->xvmc_lock );
+ if ((frame->format == XINE_IMGFMT_XXMC) &&
+ !xxmc_xvmc_surface_valid(this, frame->xvmc_surf)) {
+ xvmc_context_reader_unlock( &this->xvmc_lock );
+ return;
+ }
+
if( this->ovl_changed && this->xoverlay ) {
+
XLockDisplay (this->display);
+ xxmc_check_xoverlay_type(this, frame);
x11osd_clear(this->xoverlay);
XUnlockDisplay (this->display);
}
- if (this->ovl_changed && this->hwSubpictures ) {
- xxmc_frame_t *frame = (xxmc_frame_t *) frame_gen;
+ if (this->ovl_changed && (frame->format == XINE_IMGFMT_XXMC) &&
+ this->hwSubpictures ) {
- LOCK_AND_SURFACE_VALID( this, frame->xvmc_surf );
this->new_subpic = xxmc_xvmc_alloc_subpicture
( this, &this->context, this->xvmc_width,
this->xvmc_height,
@@ -1300,8 +1314,8 @@ static void xxmc_overlay_begin (vo_driver_t *this_gen,
XVMCUNLOCKDISPLAY( this->display );
clear_xx44_palette(&this->palette);
}
- xvmc_context_reader_unlock( &this->xvmc_lock );
- }
+ }
+ xvmc_context_reader_unlock( &this->xvmc_lock );
}
static void xxmc_overlay_end (vo_driver_t *this_gen, vo_frame_t *vo_img)
@@ -1315,7 +1329,7 @@ static void xxmc_overlay_end (vo_driver_t *this_gen, vo_frame_t *vo_img)
x11osd_expose(this->xoverlay);
XUnlockDisplay (this->display);
}
- if (this->hwSubpictures) {
+ if ((frame->format == XINE_IMGFMT_XXMC) && this->hwSubpictures) {
LOCK_AND_SURFACE_VALID( this, frame->xvmc_surf );
if (this->ovl_changed) {
if (this->old_subpic) {
@@ -1373,8 +1387,8 @@ static void xxmc_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen,
x11osd_blend(this->xoverlay, overlay);
XUnlockDisplay (this->display);
}
- } else if (this->hwSubpictures) {
- if (this->ovl_changed) {
+ } else if (frame->format == XINE_IMGFMT_XXMC) {
+ if (this->ovl_changed && this->hwSubpictures) {
if (this->new_subpic) {
LOCK_AND_SURFACE_VALID( this, frame->xvmc_surf );
if (this->first_overlay) {
@@ -1442,7 +1456,9 @@ static int xxmc_redraw_needed (vo_driver_t *this_gen)
if( _x_vo_scale_redraw_needed( &this->sc ) ) {
xxmc_compute_output_size (this);
- xxmc_clean_output_area (this);
+
+ xxmc_clean_output_area
+ (this, (this->cur_frame->format == XINE_IMGFMT_XXMC));
ret = 1;
}
@@ -1495,15 +1511,15 @@ static void xxmc_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen)
xxmc_redraw_needed (this_gen);
if (frame->format == XINE_IMGFMT_XXMC) {
- XVMCLOCKDISPLAY( this->display );
- XvMCPutSurface( this->display, frame->xvmc_surf , this->drawable,
- this->sc.displayed_xoffset, this->sc.displayed_yoffset,
- this->sc.displayed_width, this->sc.displayed_height,
- this->sc.output_xoffset, this->sc.output_yoffset,
- this->sc.output_width, this->sc.output_height,
- ((this->deinterlace_enabled) ?
- XVMC_TOP_FIELD : XVMC_FRAME_PICTURE));
- XVMCUNLOCKDISPLAY( this->display );
+ XVMCLOCKDISPLAY( this->display );
+ XvMCPutSurface( this->display, frame->xvmc_surf , this->drawable,
+ this->sc.displayed_xoffset, this->sc.displayed_yoffset,
+ this->sc.displayed_width, this->sc.displayed_height,
+ this->sc.output_xoffset, this->sc.output_yoffset,
+ this->sc.output_width, this->sc.output_height,
+ ((this->deinterlace_enabled) ?
+ XVMC_TOP_FIELD : XVMC_FRAME_PICTURE));
+ XVMCUNLOCKDISPLAY( this->display );
} else {
XLockDisplay (this->display);
if (this->use_shm) {
@@ -1525,9 +1541,7 @@ static void xxmc_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen)
XSync(this->display, False);
XUnlockDisplay (this->display);
}
-
xvmc_context_reader_unlock( &this->xvmc_lock );
-
}
static int xxmc_get_property (vo_driver_t *this_gen, int property) {
@@ -1666,7 +1680,7 @@ static void xxmc_get_property_min_max (vo_driver_t *this_gen,
static int xxmc_gui_data_exchange (vo_driver_t *this_gen,
int data_type, void *data) {
- xxmc_driver_t *this = (xxmc_driver_t *) this_gen;
+ xxmc_driver_t *this = (xxmc_driver_t *) this_gen;
switch (data_type) {
#ifndef XINE_DISABLE_DEPRECATED_FEATURES
@@ -1681,25 +1695,26 @@ static int xxmc_gui_data_exchange (vo_driver_t *this_gen,
xxmc_frame_t *frame = this->cur_frame;
xine_xxmc_t *xxmc = &frame->xxmc_data;
- xxmc_redraw_needed (this_gen);
- xxmc_clean_output_area (this);
-
xvmc_context_reader_lock( &this->xvmc_lock );
if ((frame->format == XINE_IMGFMT_XXMC) &&
(!xxmc->decoded || !xxmc_xvmc_surface_valid(this, frame->xvmc_surf))) {
xvmc_context_reader_unlock( &this->xvmc_lock );
+ if (! xxmc_redraw_needed (this_gen))
+ xxmc_clean_output_area(this, (frame->format == XINE_IMGFMT_XXMC));
break;
}
+ if (!xxmc_redraw_needed (this_gen) && !this->xoverlay)
+ xxmc_clean_output_area(this,(frame->format == XINE_IMGFMT_XXMC));
if (frame->format == XINE_IMGFMT_XXMC) {
- XVMCLOCKDISPLAY( this->display );
- XvMCPutSurface( this->display, frame->xvmc_surf, this->drawable,
- this->sc.displayed_xoffset, this->sc.displayed_yoffset,
- this->sc.displayed_width, this->sc.displayed_height,
- this->sc.output_xoffset, this->sc.output_yoffset,
- this->sc.output_width, this->sc.output_height,
- ((this->deinterlace_enabled) ? XVMC_TOP_FIELD : XVMC_FRAME_PICTURE));
- XVMCUNLOCKDISPLAY( this->display );
+ XVMCLOCKDISPLAY( this->display );
+ XvMCPutSurface( this->display, frame->xvmc_surf, this->drawable,
+ this->sc.displayed_xoffset, this->sc.displayed_yoffset,
+ this->sc.displayed_width, this->sc.displayed_height,
+ this->sc.output_xoffset, this->sc.output_yoffset,
+ this->sc.output_width, this->sc.output_height,
+ ((this->deinterlace_enabled) ? XVMC_TOP_FIELD : XVMC_FRAME_PICTURE));
+ XVMCUNLOCKDISPLAY( this->display );
} else {
XLockDisplay (this->display);
if (this->use_shm) {
@@ -1720,12 +1735,13 @@ static int xxmc_gui_data_exchange (vo_driver_t *this_gen,
XSync(this->display, False);
XUnlockDisplay (this->display);
}
-
- if(this->xoverlay)
- x11osd_expose(this->xoverlay);
xvmc_context_reader_unlock( &this->xvmc_lock );
}
+ if(this->xoverlay)
+ x11osd_expose(this->xoverlay);
+
}
+
break;
case XINE_GUI_SEND_DRAWABLE_CHANGED:
@@ -1777,13 +1793,12 @@ static void xxmc_dispose (vo_driver_t *this_gen) {
this->old_subpic = NULL;
}
if (this->new_subpic) {
- xxmc_xvmc_free_subpicture(this, this->old_subpic);
+ xxmc_xvmc_free_subpicture(this, this->new_subpic);
this->new_subpic = NULL;
}
xvmc_context_writer_unlock( &this->xvmc_lock );
}
-
XLockDisplay (this->display);
if(XvUngrabPort (this->display, this->xv_port, CurrentTime) != Success) {
xprintf (this->xine, XINE_VERBOSITY_DEBUG, "video_out_xxmc: xxmc_exit: XvUngrabPort() failed.\n");
@@ -2090,7 +2105,6 @@ static void checkXvMCCap( xxmc_driver_t *this, XvPortID xv_port)
XVMCUNLOCKDISPLAY( this->display );
init_xx44_palette( &this->palette , 0);
this->last_accel_request = 0xFFFFFFFF;
- this->fallback_used = 0;
xvmc_context_writer_unlock( &this->xvmc_lock );
return;
@@ -2429,13 +2443,15 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi
if( this->use_colorkey ) {
this->xoverlay = x11osd_create (this->xine, this->display, this->screen,
this->drawable, X11OSD_COLORKEY);
+ this->xv_xoverlay_type = X11OSD_COLORKEY;
if(this->xoverlay)
x11osd_colorkey(this->xoverlay, this->colorkey, &this->sc);
- this->xoverlay_ck = 1;
+ this->xoverlay_type = X11OSD_COLORKEY;
} else {
this->xoverlay = x11osd_create (this->xine, this->display, this->screen,
this->drawable, X11OSD_SHAPED);
- this->xoverlay_ck = 0;
+ this->xv_xoverlay_type = X11OSD_SHAPED;
+ this->xoverlay_type = X11OSD_SHAPED;
}
XUnlockDisplay (this->display);
}
diff --git a/src/video_out/xxmc.h b/src/video_out/xxmc.h
index 234cd2fdb..bf1bddebf 100644
--- a/src/video_out/xxmc.h
+++ b/src/video_out/xxmc.h
@@ -18,7 +18,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: xxmc.h,v 1.4 2004/10/30 15:12:49 totte67 Exp $
+ * $Id: xxmc.h,v 1.5 2004/11/19 08:56:30 totte67 Exp $
*
* video_out_xxmc.c, X11 decoding accelerated video extension interface for xine
*
@@ -205,6 +205,8 @@ struct xxmc_driver_s {
xxmc_frame_t *recent_frames[VO_NUM_RECENT_FRAMES];
xxmc_frame_t *cur_frame;
x11osd *xoverlay;
+ int xv_xoverlay_type;
+ int xoverlay_type;
int ovl_changed;
/* all scaling information goes here */
@@ -244,11 +246,10 @@ struct xxmc_driver_s {
unsigned xvmc_mpeg;
unsigned xvmc_accel;
unsigned last_accel_request;
- unsigned fallback_used;
unsigned xvmc_width;
unsigned xvmc_height;
int have_xvmc_autopaint;
- int xoverlay_ck;
+ int xvmc_xoverlay_type;
int unsigned_intra;
/*