summaryrefslogtreecommitdiff
path: root/src/video_out
diff options
context:
space:
mode:
authorThomas Hellström <totte67@users.sourceforge.net>2005-05-06 07:42:20 +0000
committerThomas Hellström <totte67@users.sourceforge.net>2005-05-06 07:42:20 +0000
commit143e6ca14ef8d043cc01e922ac6ed03e20b71606 (patch)
tree855efbe1c21374b95cda01984dd53db058f78607 /src/video_out
parente3e426cc9029ba7072bf48a4789ec04c179b63f1 (diff)
downloadxine-lib-143e6ca14ef8d043cc01e922ac6ed03e20b71606.tar.gz
xine-lib-143e6ca14ef8d043cc01e922ac6ed03e20b71606.tar.bz2
**BUGFIX**
improve xxmc cpu-usage for IDCT / MOCOMP acceleration through better locking [bug #1195282] CVS patchset: 7524 CVS date: 2005/05/06 07:42:20
Diffstat (limited to 'src/video_out')
-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
4 files changed, 100 insertions, 61 deletions
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 {