summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog2
-rw-r--r--src/libmpeg2/decode.c4
-rw-r--r--src/libmpeg2/libmpeg2_accel.c17
-rw-r--r--src/libmpeg2/libmpeg2_accel.h4
-rw-r--r--src/libmpeg2/slice_xvmc_vld.c12
-rw-r--r--src/video_out/video_out_xxmc.c126
-rw-r--r--src/video_out/xvmc_mocomp.c6
-rw-r--r--src/video_out/xvmc_vld.c23
-rw-r--r--src/video_out/xxmc.h6
-rw-r--r--src/xine-engine/accel_xvmc.h12
10 files changed, 136 insertions, 76 deletions
diff --git a/ChangeLog b/ChangeLog
index c0030b9f6..abcd28e5b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -12,6 +12,8 @@ xine-lib (1.0.2)
* speed up xx44 alphablending of large transparent areas
* stop libmpeg2 XvMC IDCT / MOCOMP attempting software motion compensation
[bug #1194754]
+ * improve xxmc cpu-usage for IDCT / MOCOMP acceleration through better locking
+ [bug #1195282]
xine-lib (1.0.1)
* Big XvMC quality / correctness / cpu-usage fix. [bug #1114517]
diff --git a/src/libmpeg2/decode.c b/src/libmpeg2/decode.c
index 5d3f78ec5..c4b980f79 100644
--- a/src/libmpeg2/decode.c
+++ b/src/libmpeg2/decode.c
@@ -573,8 +573,8 @@ static inline int parse_chunk (mpeg2dec_t * mpeg2dec, int code,
printf("slice target %08x past %08x future %08x\n",picture->current_frame,picture->forward_reference_frame,picture->backward_reference_frame);
fflush(stdout);
#endif
- libmpeg2_accel_slice(&mpeg2dec->accel, mpeg2dec->frame_format, picture, code, buffer,
- mpeg2dec->chunk_size, mpeg2dec->chunk_buffer);
+ libmpeg2_accel_slice(&mpeg2dec->accel, picture, code, buffer, mpeg2dec->chunk_size,
+ mpeg2dec->chunk_buffer);
if( picture->v_offset > picture->limit_y ) {
picture->current_frame->bad_frame = 0;
}
diff --git a/src/libmpeg2/libmpeg2_accel.c b/src/libmpeg2/libmpeg2_accel.c
index 376ae3979..54bdee549 100644
--- a/src/libmpeg2/libmpeg2_accel.c
+++ b/src/libmpeg2/libmpeg2_accel.c
@@ -147,8 +147,8 @@ libmpeg2_accel_frame_completion(mpeg2dec_accel_t * accel, uint32_t frame_format,
int
-libmpeg2_accel_slice(mpeg2dec_accel_t *accel, uint32_t frame_format, picture_t *picture,
- int code, char * buffer, uint32_t chunk_size, uint8_t *chunk_buffer)
+libmpeg2_accel_slice(mpeg2dec_accel_t *accel, picture_t *picture, int code, char * buffer,
+ uint32_t chunk_size, uint8_t *chunk_buffer)
{
/*
* Don't reference frames of other formats. They are invalid. This may happen if the
@@ -172,13 +172,21 @@ libmpeg2_accel_slice(mpeg2dec_accel_t *accel, uint32_t frame_format, picture_t *
}
}
+ switch( picture->current_frame->format ) {
- switch( frame_format ) {
case XINE_IMGFMT_XXMC:
{
xine_xxmc_t *xxmc = (xine_xxmc_t *)
picture->current_frame->accel_data;
+ if ( xxmc->proc_xxmc_lock_valid( picture->current_frame,
+ picture->forward_reference_frame,
+ picture->backward_reference_frame,
+ picture->current_frame->picture_coding_type)) {
+ picture->v_offset = 0;
+ return 1;
+ }
+
switch(picture->current_frame->format) {
case XINE_IMGFMT_XXMC:
switch(xxmc->acceleration) {
@@ -198,11 +206,14 @@ libmpeg2_accel_slice(mpeg2dec_accel_t *accel, uint32_t frame_format, picture_t *
mpeg2_slice (picture, code, buffer);
break;
}
+ xxmc->proc_xxmc_unlock(picture->current_frame->driver);
break;
}
+
case XINE_IMGFMT_XVMC:
mpeg2_xvmc_slice (accel, picture, code, buffer);
break;
+
default:
mpeg2_slice (picture, code, buffer);
break;
diff --git a/src/libmpeg2/libmpeg2_accel.h b/src/libmpeg2/libmpeg2_accel.h
index 41b081cc5..5d0b37a78 100644
--- a/src/libmpeg2/libmpeg2_accel.h
+++ b/src/libmpeg2/libmpeg2_accel.h
@@ -41,8 +41,8 @@ extern int libmpeg2_accel_new_sequence(mpeg2dec_accel_t *accel, uint32_t frame_f
extern int libmpeg2_accel_new_frame(mpeg2dec_accel_t *accel, uint32_t frame_format, picture_t *picture, double ratio, uint32_t flags);
extern void libmpeg2_accel_frame_completion(mpeg2dec_accel_t *accel, uint32_t frame_format, picture_t *picture, int code);
-extern int libmpeg2_accel_slice(mpeg2dec_accel_t *accel, uint32_t frame_format, picture_t *picture,
- int code, char * buffer, uint32_t chunk_size, uint8_t *chunk_buffer);
+extern int libmpeg2_accel_slice(mpeg2dec_accel_t *accel, picture_t *picture, int code,
+ char * buffer, uint32_t chunk_size, uint8_t *chunk_buffer);
extern void libmpeg2_accel_scan( mpeg2dec_accel_t *accel, uint8_t *scan_norm, uint8_t *scan_alt);
#endif
diff --git a/src/libmpeg2/slice_xvmc_vld.c b/src/libmpeg2/slice_xvmc_vld.c
index 3c177d97a..3647c7386 100644
--- a/src/libmpeg2/slice_xvmc_vld.c
+++ b/src/libmpeg2/slice_xvmc_vld.c
@@ -146,7 +146,6 @@ void mpeg2_xxmc_slice( mpeg2dec_accel_t *accel, picture_t *picture,
vft->backward_reference_frame = picture->backward_reference_frame;
xxmc->proc_xxmc_begin( frame );
if (xxmc->result != 0) {
- xxmc->proc_xxmc_flush( frame );
accel->xvmc_last_slice_code=-1;
}
}
@@ -164,9 +163,9 @@ void mpeg2_xxmc_slice( mpeg2dec_accel_t *accel, picture_t *picture,
xxmc->slice_data = chunk_buffer;
xxmc->slice_code = code;
- xxmc->proc_xxmc_slice( frame );
+ xxmc->proc_xxmc_slice( frame );
+
if (xxmc->result != 0) {
- xxmc->proc_xxmc_flush( frame );
accel->xvmc_last_slice_code=-1;
return;
}
@@ -188,7 +187,6 @@ void mpeg2_xxmc_slice( mpeg2dec_accel_t *accel, picture_t *picture,
lprintf("libmpeg2: VLD XvMC: Slice error.\n");
accel->xvmc_last_slice_code = -1;
- xxmc->proc_xxmc_flush( frame );
return;
}
}
@@ -200,7 +198,11 @@ void mpeg2_xxmc_vld_frame_complete(mpeg2dec_accel_t *accel, picture_t *picture,
xine_xxmc_t
*xxmc = (xine_xxmc_t *) frame->accel_data;
- if (xxmc->decoded || (accel->xvmc_last_slice_code == -1)) return;
+ if (xxmc->decoded) return;
+ if (accel->xvmc_last_slice_code == -1) {
+ xxmc->proc_xxmc_flush( frame );
+ return;
+ }
if ((code != 0xff) || ((accel->xvmc_last_slice_code ==
accel->xxmc_mb_pic_height) &&
diff --git a/src/video_out/video_out_xxmc.c b/src/video_out/video_out_xxmc.c
index d22d80623..ffdba63d9 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.15 2005/05/04 04:27:20 totte67 Exp $
+ * $Id: video_out_xxmc.c,v 1.16 2005/05/06 07:42:21 totte67 Exp $
*
* video_out_xxmc.c, X11 decoding accelerated video extension interface for xine
*
@@ -31,7 +31,7 @@
*
* overlay support by James Courtier-Dutton <James@superbug.demon.co.uk> - July 2001
* X11 unscaled overlay support by Miguel Freitas - Nov 2003
- * XvMC VLD implementation by Thomas Hellström - August-Oct 2004
+ * XvMC VLD implementation by Thomas Hellström - 2004, 2005.
* XvMC merge by Thomas Hellström - Sep 2004
*
*/
@@ -41,6 +41,7 @@
#include "xxmc.h"
#include <unistd.h>
+
static int gX11Fail;
static void xxmc_frame_updates(xxmc_driver_t *driver, xxmc_frame_t *frame,
int init_macroblocks);
@@ -349,10 +350,60 @@ static void xxmc_xvmc_free_subpicture(xxmc_driver_t *this, XvMCSubpicture *sub)
}
+/*
+ * Callback used by decoder to check that surfaces are still valid,
+ * and to lock the context so that it won't get destroyed during
+ * decoding.
+ */
+
+
+static int xxmc_lock_and_validate_surfaces(vo_frame_t *cur_frame,
+ vo_frame_t *fw_frame,
+ vo_frame_t *bw_frame,
+ unsigned pc_type)
+{
+ xxmc_driver_t
+ *driver = (xxmc_driver_t *) cur_frame->driver;
+ xxmc_frame_t
+ *frame;
+ xvmc_context_reader_lock( &driver->xvmc_lock );
+
+ switch(pc_type) {
+ case XINE_PICT_B_TYPE:
+ frame = (xxmc_frame_t *) bw_frame;
+ if (!xxmc_xvmc_surface_valid( driver, frame->xvmc_surf)) break;
+ /* fall through */
+ case XINE_PICT_P_TYPE:
+ frame = (xxmc_frame_t *) fw_frame;
+ if (!xxmc_xvmc_surface_valid( driver, frame->xvmc_surf)) break;
+ /* fall through */
+ default:
+ frame = (xxmc_frame_t *) cur_frame;
+ if (!xxmc_xvmc_surface_valid( driver, frame->xvmc_surf)) break;
+ return 0;
+ }
+
+ xvmc_context_reader_unlock( &driver->xvmc_lock );
+ return -1;
+}
/*
- * Here follows a number of callback function.
+ * Callback for decoder. Decoding temporarily halted. Release the context.
+ */
+
+static void xxmc_unlock_surfaces(vo_driver_t *this_gen)
+{
+ xxmc_driver_t
+ *driver = (xxmc_driver_t *) this_gen;
+
+ xvmc_context_reader_unlock( &driver->xvmc_lock );
+}
+
+/*
+ * Callback for decoder.
+ * Check that the surface is vaid and
+ * flush outstanding rendering requests on this surface.
*/
static void xvmc_flush(vo_frame_t *this_gen)
@@ -380,13 +431,13 @@ static void xvmc_flush(vo_frame_t *this_gen)
}
-
/*
* Callback function for the VO-loop to duplicate frame data.
* YV12 and YUY2 formats are taken care of in the xine-engine.
+ * This one only deals with hardware surfaces and duplicates them
+ * using a call to XvMCBlendSubpicture2 with a blank subpicture.
*/
-
static void xxmc_duplicate_frame_data(vo_frame_t *this_gen,
vo_frame_t *original)
{
@@ -731,6 +782,13 @@ static void xxmc_dispose_context(xxmc_driver_t *driver)
}
}
+/*
+ * Find a suitable XvMC Context according to the acceleration request
+ * passed to us in the xxmc variable, and to the acceleration type
+ * priority set up in this plugin. Result is returned in
+ * driver->xvmc_cur_cap.
+ */
+
static int xxmc_find_context(xxmc_driver_t *driver, xine_xxmc_t *xxmc,
unsigned width, unsigned height)
{
@@ -990,28 +1048,38 @@ static void xxmc_frame_updates(xxmc_driver_t *driver,
if (frame->xvmc_surf == NULL) {
if (NULL == (frame->xvmc_surf =
xxmc_xvmc_alloc_surface( driver, &driver->context))) {
- printf("video_out_xxmc: ERROR: Accelerated surface allocation failed.\n"
- "video_out_xxmc: You are probably out of framebuffer memory.\n"
- "video_out_xxmc: Falling back to software decoding.\n");
+ fprintf(stderr, "video_out_xxmc: ERROR: Accelerated surface allocation failed.\n"
+ "video_out_xxmc: You are probably out of framebuffer memory.\n"
+ "video_out_xxmc: Falling back to software decoding.\n");
driver->xvmc_accel = 0;
xxmc_dispose_context( driver );
return;
}
- }
+ xxmc->xvmc.macroblocks = (xine_macroblocks_t *) &driver->macroblocks;
+ xxmc->xvmc.macroblocks->xvmc_accel = (driver->unsigned_intra) ?
+ 0 : XINE_VO_SIGNED_INTRA;
+ switch(driver->xvmc_accel) {
+ case XINE_XVMC_ACCEL_IDCT:
+ xxmc->xvmc.macroblocks->xvmc_accel |= XINE_VO_IDCT_ACCEL;
+ break;
+ case XINE_XVMC_ACCEL_MOCOMP:
+ xxmc->xvmc.macroblocks->xvmc_accel |= XINE_VO_MOTION_ACCEL;
+ break;
+ default:
+ xxmc->xvmc.macroblocks->xvmc_accel = 0;
+ }
- xxmc->acceleration = driver->xvmc_accel;
- xxmc->xvmc.macroblocks = (xine_macroblocks_t *) &driver->macroblocks;
- xxmc->xvmc.macroblocks->xvmc_accel = (driver->unsigned_intra) ?
- 0 : XINE_VO_SIGNED_INTRA;
- switch(driver->xvmc_accel) {
- case XINE_XVMC_ACCEL_IDCT:
- xxmc->xvmc.macroblocks->xvmc_accel |= XINE_VO_IDCT_ACCEL;
- break;
- case XINE_XVMC_ACCEL_MOCOMP:
- xxmc->xvmc.macroblocks->xvmc_accel |= XINE_VO_MOTION_ACCEL;
- break;
- default:
- xxmc->xvmc.macroblocks->xvmc_accel = 0;
+
+ xxmc->proc_xxmc_flush = xvmc_flush;
+ xxmc->proc_xxmc_lock_valid = xxmc_lock_and_validate_surfaces;
+ xxmc->proc_xxmc_unlock = xxmc_unlock_surfaces;
+
+ xxmc->xvmc.proc_macro_block = xxmc_xvmc_proc_macro_block;
+ frame->vo_frame.proc_duplicate_frame_data = xxmc_duplicate_frame_data;
+#ifdef HAVE_VLDXVMC
+ xxmc->proc_xxmc_begin = xvmc_vld_frame;
+ xxmc->proc_xxmc_slice = xvmc_vld_slice;
+#endif
}
if (init_macroblocks) {
@@ -1020,15 +1088,7 @@ static void xxmc_frame_updates(xxmc_driver_t *driver,
driver->macroblocks.xine_mc.blockptr =
driver->macroblocks.xine_mc.blockbaseptr;
}
-
- xxmc->proc_xxmc_flush = xvmc_flush;
- xxmc->xvmc.proc_macro_block = xxmc_xvmc_proc_macro_block;
- frame->vo_frame.proc_duplicate_frame_data = xxmc_duplicate_frame_data;
-#ifdef HAVE_VLDXVMC
- xxmc->proc_xxmc_begin = xvmc_vld_frame;
- xxmc->proc_xxmc_slice = xvmc_vld_slice;
-#endif
-
+ xxmc->acceleration = driver->xvmc_accel;
}
@@ -1110,7 +1170,7 @@ static void xxmc_do_update_frame_xv(vo_driver_t *this_gen,
}
/*
- * Check if we need to change XvMC context due to a
+ * Check if we need to change XvMC context due to an
* acceleration request change.
*/
@@ -1133,7 +1193,7 @@ static int xxmc_accel_update(xxmc_driver_t *driver,
if ((driver->xvmc_accel & new_request) == 0) return 1;
/*
- * Test for a higher acceleration level.
+ * Test for possible use of a higher acceleration level.
*/
for (k = 0; k < NUM_ACCEL_PRIORITY; ++k) {
diff --git a/src/video_out/xvmc_mocomp.c b/src/video_out/xvmc_mocomp.c
index 75a1aa4d9..970c243dd 100644
--- a/src/video_out/xvmc_mocomp.c
+++ b/src/video_out/xvmc_mocomp.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: xvmc_mocomp.c,v 1.3 2005/02/22 18:31:59 totte67 Exp $
+ * $Id: xvmc_mocomp.c,v 1.4 2005/05/06 07:42:21 totte67 Exp $
*
* XvMC image support by Jack Kelliher
*/
@@ -110,7 +110,6 @@ void xxmc_xvmc_proc_macro_block(int x, int y, int mb_type, int motion_type,
int top_field_first = current_frame->top_field_first;
int picture_coding_type = current_frame->picture_coding_type;
- xvmc_context_reader_lock( &this->xvmc_lock );
mbs->macroblockptr->x = x;
mbs->macroblockptr->y = y;
@@ -253,9 +252,6 @@ void xxmc_xvmc_proc_macro_block(int x, int y, int mb_type, int motion_type,
mbs->macroblockptr = mbs->macroblockbaseptr;
mbs->xine_mc.blockptr = mbs->xine_mc.blockbaseptr;
}
-
- xvmc_context_reader_unlock( &this->xvmc_lock );
-
}
diff --git a/src/video_out/xvmc_vld.c b/src/video_out/xvmc_vld.c
index 93c5f00bd..ba1b51795 100644
--- a/src/video_out/xvmc_vld.c
+++ b/src/video_out/xvmc_vld.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: xvmc_vld.c,v 1.3 2005/05/04 04:27:20 totte67 Exp $
+ * $Id: xvmc_vld.c,v 1.4 2005/05/06 07:42:21 totte67 Exp $
*
* xvmc_vld.c, X11 decoding accelerated video extension interface for xine
*
@@ -92,24 +92,14 @@ void xvmc_vld_frame(struct vo_frame_s *this_gen)
}
qmx.load_chroma_intra_quantiser_matrix = 0;
qmx.load_chroma_non_intra_quantiser_matrix = 0;
- xvmc_context_reader_lock( &driver->xvmc_lock );
- if ( (!xxmc_xvmc_surface_valid( driver, cf->xvmc_surf)) ||
- ((ctl.picture_coding_type == XVMC_P_PICTURE ||
- ctl.picture_coding_type == XVMC_B_PICTURE) &&
- !xxmc_xvmc_surface_valid( driver, fs )) ||
- ((ctl.picture_coding_type == XVMC_B_PICTURE) &&
- !xxmc_xvmc_surface_valid( driver, bs )) ) {
- cf->xxmc_data.result = 128;
- xvmc_context_reader_unlock( &driver->xvmc_lock );
- return;
- }
+
XVMCLOCKDISPLAY( driver->display );
XvMCLoadQMatrix(driver->display, &driver->context, &qmx);
+
while((cf->xxmc_data.result =
XvMCBeginSurface(driver->display, &driver->context, cf->xvmc_surf,
fs, bs, &ctl)));
XVMCUNLOCKDISPLAY( driver->display );
- xvmc_context_reader_unlock( &driver->xvmc_lock );
driver->cpu_saver = 0.;
}
@@ -120,12 +110,6 @@ void xvmc_vld_slice(vo_frame_t *this_gen)
xxmc_driver_t
*driver = (xxmc_driver_t *) cf->vo_frame.driver;
- xvmc_context_reader_lock( &driver->xvmc_lock );
- if ( ! xxmc_xvmc_surface_valid( driver, cf->xvmc_surf)) {
- cf->xxmc_data.result = 128;
- xvmc_context_reader_unlock( &driver->xvmc_lock );
- return;
- }
XVMCLOCKDISPLAY( driver->display );
cf->xxmc_data.result =
XvMCPutSlice2(driver->display,&driver->context,cf->xxmc_data.slice_data,
@@ -138,7 +122,6 @@ void xvmc_vld_slice(vo_frame_t *this_gen)
*/
XVMCUNLOCKDISPLAY( driver->display );
- xvmc_context_reader_unlock( &driver->xvmc_lock );
if (driver->cpu_save_enabled) {
driver->cpu_saver += 1.;
if (driver->cpu_saver >= cf->xxmc_data.sleep) {
diff --git a/src/video_out/xxmc.h b/src/video_out/xxmc.h
index 27103dea7..fcbd082e3 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.7 2005/04/09 11:47:43 totte67 Exp $
+ * $Id: xxmc.h,v 1.8 2005/05/06 07:42:21 totte67 Exp $
*
* video_out_xxmc.c, X11 decoding accelerated video extension interface for xine
*
@@ -178,8 +178,8 @@ typedef struct context_lock_s {
#define XVMCLOCKDISPLAY(display)
#define XVMCUNLOCKDISPLAY(display)
#else
-#define XVMCLOCKDISPLAY(display) XLockDisplay(display);
-#define XVMCUNLOCKDISPLAY(display) XUnlockDisplay(display);
+#define XVMCLOCKDISPLAY(display) XLockDisplay(display)
+#define XVMCUNLOCKDISPLAY(display) XUnlockDisplay(display)
#endif
struct xxmc_driver_s {
diff --git a/src/xine-engine/accel_xvmc.h b/src/xine-engine/accel_xvmc.h
index bccbf9475..46cbfba22 100644
--- a/src/xine-engine/accel_xvmc.h
+++ b/src/xine-engine/accel_xvmc.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: accel_xvmc.h,v 1.2 2004/10/12 07:40:23 totte67 Exp $
+ * $Id: accel_xvmc.h,v 1.3 2005/05/06 07:42:21 totte67 Exp $
*
*
* Common acceleration definitions for XvMC.
@@ -100,6 +100,14 @@ typedef struct xine_xxmc_s {
void (*proc_xxmc_begin) (vo_frame_t *vo_img);
void (*proc_xxmc_slice) (vo_frame_t *vo_img);
void (*proc_xxmc_flush) (vo_frame_t *vo_img);
+
+ /*
+ * For thread-safety only.
+ */
+
+ int (*proc_xxmc_lock_valid) (vo_frame_t *cur_frame, vo_frame_t *fw_frame,
+ vo_frame_t *bw_frame,unsigned pc_type);
+ void (*proc_xxmc_unlock) (vo_driver_t *this_gen);
} xine_xxmc_t;
/*
@@ -144,8 +152,6 @@ typedef struct xine_xxmc_s {
#define XINE_MACROBLOCK_QUANT 16
#define XINE_MACROBLOCK_DCT_TYPE_INTERLACED 32
-
-
#ifdef __cplusplus
}
#endif