summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac5
-rw-r--r--src/libmpeg2/Makefile.am3
-rw-r--r--src/libmpeg2/decode.c173
-rw-r--r--src/libmpeg2/libmpeg2_accel.c188
-rw-r--r--src/libmpeg2/libmpeg2_accel.h48
-rw-r--r--src/libmpeg2/mpeg2.h6
-rw-r--r--src/libmpeg2/mpeg2_internal.h4
-rw-r--r--src/libmpeg2/slice_xvmc.c12
-rw-r--r--src/libmpeg2/slice_xvmc_vld.c126
-rw-r--r--src/libmpeg2/xvmc.h4
-rw-r--r--src/libmpeg2/xvmc_vld.h10
11 files changed, 329 insertions, 250 deletions
diff --git a/configure.ac b/configure.ac
index 95bc5f88e..0d394a540 100644
--- a/configure.ac
+++ b/configure.ac
@@ -567,6 +567,8 @@ AC_ARG_WITH(xxmc-lib, AC_HELP_STRING([--with-xxmc-lib=XXXX], [The name of the Xv
libXXXX.so for the xxmc plugin.]),xxmc_stub="$withval",
xxmc_stub="XvMCW")
saved_libs="$LIBS"
+saved_CPPFLAGS="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS -I$x_includes"
XXMC_LIB="-L$xxmc_path -l$xxmc_stub"
AC_MSG_CHECKING(whether to enable the xxmc plugin with vld extensions)
AC_MSG_RESULT()
@@ -589,6 +591,7 @@ else
ac_have_xxmc="no",
fi
fi
+
if test x$ac_have_xxmc = "xyes"; then
AC_CHECK_HEADERS($x_includes/X11/extensions/vldXvMC.h,
[ac_have_vldxvmc_h="yes"],
@@ -682,7 +685,7 @@ if test x$ac_have_xvmc = "xyes"; then
else
AC_MSG_RESULT([*** Disabling old xvmc plugin due to above errors.])
fi
-
+CPPFLAGS="$saved_CPPFLAGS"
LIBS="$saved_libs"
fi
AM_CONDITIONAL(HAVE_XVMC, test x$ac_have_xvmc = "xyes")
diff --git a/src/libmpeg2/Makefile.am b/src/libmpeg2/Makefile.am
index 7bec5f8b0..e0d0d37b3 100644
--- a/src/libmpeg2/Makefile.am
+++ b/src/libmpeg2/Makefile.am
@@ -23,7 +23,8 @@ xineplug_decode_mpeg2_la_SOURCES = \
slice_xvmc.c \
slice_xvmc_vld.c \
stats.c \
- xine_decoder.c
+ xine_decoder.c \
+ libmpeg2_accel.c
xineplug_decode_mpeg2_la_LIBADD = $(MLIB_LIBS) $(XINE_LIB)
xineplug_decode_mpeg2_la_LDFLAGS = -avoid-version -module @XINE_PLUGIN_MIN_SYMS@
diff --git a/src/libmpeg2/decode.c b/src/libmpeg2/decode.c
index 6da1e07cf..63e6edbb4 100644
--- a/src/libmpeg2/decode.c
+++ b/src/libmpeg2/decode.c
@@ -41,7 +41,7 @@
#include "mpeg2.h"
#include "mpeg2_internal.h"
#include "xineutils.h"
-#include "xvmc_vld.h"
+#include "libmpeg2_accel.h"
/*
#define LOG_PAN_SCAN
@@ -64,7 +64,7 @@ void mpeg2_init (mpeg2dec_t * mpeg2dec,
mpeg2_cpu_state_init (mm_accel);
mpeg2_idct_init (mm_accel);
mpeg2_mc_init (mm_accel);
- xvmc_setup_scan_ptable();
+ libmpeg2_accel_scan(&mpeg2dec->accel, mpeg2_scan_norm, mpeg2_scan_alt);
}
if( !mpeg2dec->chunk_buffer )
@@ -250,7 +250,6 @@ static void remember_metainfo (mpeg2dec_t *mpeg2dec) {
_x_meta_info_set_utf8(mpeg2dec->stream, XINE_META_INFO_VIDEOCODEC, "MPEG (libmpeg2)");
}
-
static inline int parse_chunk (mpeg2dec_t * mpeg2dec, int code,
uint8_t * buffer)
{
@@ -282,40 +281,9 @@ static inline int parse_chunk (mpeg2dec_t * mpeg2dec, int code,
mpeg2dec->in_slice = 0;
if (is_frame_done && picture->current_frame != NULL) {
-
- /*
- * This frame completion code will move to a separate libmpeg2_accel.c file?
- * int libmpeg2_accel_frame_completion(mpeg2dec_t *, picture_t *, int);
- */
-
- if (mpeg2dec->frame_format == XINE_IMGFMT_XXMC) {
- xine_xxmc_t *xxmc = (xine_xxmc_t *)
- picture->current_frame->accel_data;
- if (!xxmc->decoded) {
- switch(picture->current_frame->format) {
- case XINE_IMGFMT_XXMC:
- switch(xxmc->acceleration) {
- case XINE_XVMC_ACCEL_VLD:
- mpeg2_xxmc_vld_frame_complete(mpeg2dec, picture, code);
- break;
- case XINE_XVMC_ACCEL_IDCT:
- case XINE_XVMC_ACCEL_MOCOMP:
- xxmc->decoded = !picture->current_frame->bad_frame;
- xxmc->proc_xxmc_flush( picture->current_frame );
- break;
- default:
- break;
- }
- default:
- break;
- }
- }
- }
-
- /*
- * End of frame completion code.
- */
-
+
+ libmpeg2_accel_frame_completion(&mpeg2dec->accel, mpeg2dec->frame_format,
+ picture, code);
if (((picture->picture_structure == FRAME_PICTURE) ||
(picture->second_field)) ) {
@@ -503,9 +471,9 @@ static inline int parse_chunk (mpeg2dec_t * mpeg2dec, int code,
abort();
}
default:
- if (code >= 0xb9)
- printf ("libmpeg2: stream not demultiplexed ?\n");
-
+ if ((code >= 0xb9) && (code != 0xe4)) {
+ printf("Not multiplexed? 0x%x\n",code);
+ }
if (code >= 0xb0)
break;
@@ -539,14 +507,8 @@ static inline int parse_chunk (mpeg2dec_t * mpeg2dec, int code,
ratio,
mpeg2dec->frame_format,
flags);
- /*
- * Move to libmpeg2_accel.c
- * int libmpeg2_accel_new_frame(mpeg2dec_t *, picture_t *)
- */
- mpeg2_xxmc_choose_coding(mpeg2dec, picture, ratio, flags);
- /*
- * End of new frame accel code.
- */
+ libmpeg2_accel_new_frame( &mpeg2dec->accel, mpeg2dec->frame_format,
+ picture, ratio);
} else {
ratio = get_aspect_ratio(mpeg2dec);
picture->current_frame =
@@ -556,14 +518,10 @@ static inline int parse_chunk (mpeg2dec_t * mpeg2dec, int code,
ratio,
mpeg2dec->frame_format,
flags);
- /*
- * Move to libmpeg2_accel.c
- * int libmpeg2_accel_new_frame(mpeg2dec_t *, picture_t *)
- */
- mpeg2_xxmc_choose_coding(mpeg2dec, picture, ratio, flags);
- /*
- * End of new frame accel code.
- */
+
+ libmpeg2_accel_new_frame( &mpeg2dec->accel, mpeg2dec->frame_format,
+ picture, ratio);
+
if (picture->forward_reference_frame &&
picture->forward_reference_frame != picture->backward_reference_frame)
picture->forward_reference_frame->free (picture->forward_reference_frame);
@@ -573,28 +531,10 @@ static inline int parse_chunk (mpeg2dec_t * mpeg2dec, int code,
picture->backward_reference_frame = picture->current_frame;
}
- /*
- * Move to libmpeg2_accel.c
- * int libmpeg2_accel_new_sequence(mpeg2dec_t *, picture_t *)
- */
-
- if(mpeg2dec->new_sequence) {
- switch(mpeg2dec->frame_format) {
- case XINE_IMGFMT_XXMC:
- case XINE_IMGFMT_XVMC: {
- xine_xvmc_t *xvmc = (xine_xvmc_t *)
- picture->current_frame->accel_data;
- picture->mc = xvmc->macroblocks;
- mpeg2dec->new_sequence = 0;
- break;
- }
- default:
- break;
- }
- }
- /*
- * End of new sequence accel code.
- */
+ if(mpeg2dec->new_sequence)
+ mpeg2dec->new_sequence =
+ libmpeg2_accel_new_sequence(&mpeg2dec->accel, mpeg2dec->frame_format,
+ picture);
picture->current_frame->bad_frame = 1;
picture->current_frame->drawn = 0;
@@ -633,48 +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
- /*
- * The below accelerated slice function choice will move to libmpeg2_accel.c ?
- * int libmpeg2_accel_slice(mpeg2dec_t *, picture_t *, int , char *)
- */
-
- switch( mpeg2dec->frame_format ) {
- case XINE_IMGFMT_XXMC:
- {
- xine_xxmc_t *xxmc = (xine_xxmc_t *)
- picture->current_frame->accel_data;
- switch(picture->current_frame->format) {
- case XINE_IMGFMT_XXMC:
- switch(xxmc->acceleration) {
- case XINE_XVMC_ACCEL_VLD:
- mpeg2_xxmc_slice(mpeg2dec, picture, code, buffer);
- break;
- case XINE_XVMC_ACCEL_IDCT:
- case XINE_XVMC_ACCEL_MOCOMP:
- mpeg2_xvmc_slice (mpeg2dec, picture, code, buffer);
- break;
- default:
- mpeg2_slice (picture, code, buffer);
- break;
- }
- break;
- default:
- mpeg2_slice (picture, code, buffer);
- break;
- }
- break;
- }
- case XINE_IMGFMT_XVMC:
- mpeg2_xvmc_slice (mpeg2dec, picture, code, buffer);
- break;
- default:
- mpeg2_slice (picture, code, buffer);
- break;
- }
- /*
- * End of acceleration code.
- */
-
+ libmpeg2_accel_slice(&mpeg2dec->accel, mpeg2dec->frame_format, picture, code, buffer,
+ mpeg2dec->chunk_size, mpeg2dec->chunk_buffer);
if( picture->v_offset > picture->limit_y ) {
picture->current_frame->bad_frame = 0;
}
@@ -747,11 +647,14 @@ int mpeg2_decode_data (mpeg2dec_t * mpeg2dec, uint8_t * current, uint8_t * end,
while (current != end) {
code = mpeg2dec->code;
current = copy_chunk (mpeg2dec, current, end);
- if (current == NULL)
- return ret;
+ if (current == NULL)
+ break;
ret += parse_chunk (mpeg2dec, code, mpeg2dec->chunk_buffer);
}
+ libmpeg2_accel_frame_completion(&mpeg2dec->accel, mpeg2dec->frame_format,
+ mpeg2dec->picture, 0xff);
+
return ret;
}
@@ -768,30 +671,8 @@ void mpeg2_discontinuity (mpeg2dec_t * mpeg2dec) {
picture->forward_reference_frame->pts = 0;
if ( picture->backward_reference_frame )
picture->backward_reference_frame->pts = 0;
-
- /*
- * Move to libmpeg2_accel.c
- * int libmpeg2_accel_discontinuity(mpeg2dec_t *);
- */
- mpeg2dec->xvmc_last_slice_code=-1;
- if ( !picture->current_frame )
- return;
- if (mpeg2dec->frame_format == XINE_IMGFMT_XXMC) {
- xine_xxmc_t *xxmc = (xine_xxmc_t *)
- picture->current_frame->accel_data;
- switch(xxmc->acceleration) {
- case XINE_XVMC_ACCEL_VLD:
- case XINE_XVMC_ACCEL_IDCT:
- case XINE_XVMC_ACCEL_MOCOMP:
- xxmc->proc_xxmc_flush( picture->current_frame );
- break;
- default:
- break;
- }
- }
- /*
- * End of discontinuity accel code.
- */
+
+ libmpeg2_accel_discontinuity(&mpeg2dec->accel, mpeg2dec->frame_format, picture);
}
void mpeg2_reset (mpeg2dec_t * mpeg2dec) {
diff --git a/src/libmpeg2/libmpeg2_accel.c b/src/libmpeg2/libmpeg2_accel.c
new file mode 100644
index 000000000..9d30e2b75
--- /dev/null
+++ b/src/libmpeg2/libmpeg2_accel.c
@@ -0,0 +1,188 @@
+/*
+ * libmpeg2_accel.c
+ * Copyright (C) 2004 The Unichrome Project.
+ * Copyright (C) 2005 Thomas Hellstrom.
+ *
+ * This file is part of xine, a free video player.
+ *
+ * xine is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "xine_internal.h"
+#include "mpeg2.h"
+#include "mpeg2_internal.h"
+#include "xvmc_vld.h"
+#include "libmpeg2_accel.h"
+
+
+void
+libmpeg2_accel_scan( mpeg2dec_accel_t *accel, uint8_t *scan_norm, uint8_t *scan_alt)
+{
+ xvmc_setup_scan_ptable();
+}
+
+
+int
+libmpeg2_accel_discontinuity(mpeg2dec_accel_t *accel, uint32_t frame_format, picture_t *picture)
+{
+ accel->xvmc_last_slice_code=-1;
+ if ( !picture->current_frame )
+ return 0;
+ if (frame_format == XINE_IMGFMT_XXMC) {
+ xine_xxmc_t *xxmc = (xine_xxmc_t *)
+ picture->current_frame->accel_data;
+ switch(xxmc->acceleration) {
+ case XINE_XVMC_ACCEL_VLD:
+ case XINE_XVMC_ACCEL_IDCT:
+ case XINE_XVMC_ACCEL_MOCOMP:
+ xxmc->proc_xxmc_flush( picture->current_frame );
+ break;
+ default:
+ break;
+ }
+ }
+ return 0;
+}
+
+int
+libmpeg2_accel_new_sequence(mpeg2dec_accel_t *accel, uint32_t frame_format, picture_t *picture)
+{
+ switch(frame_format) {
+ case XINE_IMGFMT_XXMC:
+ case XINE_IMGFMT_XVMC: {
+ xine_xvmc_t *xvmc = (xine_xvmc_t *)
+ picture->current_frame->accel_data;
+ picture->mc = xvmc->macroblocks;
+ return 0;
+ }
+ default:
+ break;
+ }
+ return 1;
+}
+
+int
+libmpeg2_accel_new_frame(mpeg2dec_accel_t *accel, uint32_t frame_format,
+ picture_t *picture, double ratio)
+{
+ if (picture->current_frame) {
+ if (XINE_IMGFMT_XXMC == frame_format) {
+ xine_xxmc_t *xxmc = (xine_xxmc_t *)
+ picture->current_frame->accel_data;
+
+ /*
+ * Make a request for acceleration type and mpeg coding from
+ * the output plugin.
+ */
+
+ xxmc->fallback_format = XINE_IMGFMT_YV12;
+ xxmc->acceleration = XINE_XVMC_ACCEL_VLD| XINE_XVMC_ACCEL_IDCT
+ | XINE_XVMC_ACCEL_MOCOMP ;
+
+ /*
+ * Standard MOCOMP / IDCT XvMC implementation for interlaced streams
+ * is buggy. The bug is inherited from the old XvMC driver. Don't use it until
+ * it has been fixed. (A volunteer ?)
+ */
+
+ if ( picture->picture_structure != 3 ) {
+ xxmc->acceleration &= ~( XINE_XVMC_ACCEL_IDCT | XINE_XVMC_ACCEL_MOCOMP );
+ }
+
+ xxmc->mpeg = (picture->mpeg1) ? XINE_XVMC_MPEG_1:XINE_XVMC_MPEG_2;
+ xxmc->proc_xxmc_update_frame (picture->current_frame->driver,
+ picture->current_frame,
+ picture->coded_picture_width,
+ picture->coded_picture_height,
+ ratio,
+ XINE_IMGFMT_XXMC, picture->picture_structure);
+ }
+ }
+ return 0;
+}
+
+void
+libmpeg2_accel_frame_completion(mpeg2dec_accel_t * accel, uint32_t frame_format, picture_t *picture,
+ int code)
+{
+
+ if ( !picture->current_frame ) return;
+
+ if (frame_format == XINE_IMGFMT_XXMC) {
+ xine_xxmc_t *xxmc = (xine_xxmc_t *)
+ picture->current_frame->accel_data;
+ if (!xxmc->decoded) {
+ switch(picture->current_frame->format) {
+ case XINE_IMGFMT_XXMC:
+ switch(xxmc->acceleration) {
+ case XINE_XVMC_ACCEL_VLD:
+ mpeg2_xxmc_vld_frame_complete(accel, picture, code);
+ break;
+ case XINE_XVMC_ACCEL_IDCT:
+ case XINE_XVMC_ACCEL_MOCOMP:
+ xxmc->decoded = !picture->current_frame->bad_frame;
+ xxmc->proc_xxmc_flush( picture->current_frame );
+ break;
+ default:
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ }
+}
+
+
+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)
+{
+ switch( frame_format ) {
+ case XINE_IMGFMT_XXMC:
+ {
+ xine_xxmc_t *xxmc = (xine_xxmc_t *)
+ picture->current_frame->accel_data;
+
+ switch(picture->current_frame->format) {
+ case XINE_IMGFMT_XXMC:
+ switch(xxmc->acceleration) {
+ case XINE_XVMC_ACCEL_VLD:
+ mpeg2_xxmc_slice(accel, picture, code, buffer, chunk_size, chunk_buffer);
+ break;
+ case XINE_XVMC_ACCEL_IDCT:
+ case XINE_XVMC_ACCEL_MOCOMP:
+ mpeg2_xvmc_slice (accel, picture, code, buffer);
+ break;
+ default:
+ mpeg2_slice (picture, code, buffer);
+ break;
+ }
+ break;
+ default:
+ mpeg2_slice (picture, code, buffer);
+ break;
+ }
+ break;
+ }
+ case XINE_IMGFMT_XVMC:
+ mpeg2_xvmc_slice (accel, picture, code, buffer);
+ break;
+ default:
+ mpeg2_slice (picture, code, buffer);
+ break;
+ }
+ return 0;
+}
diff --git a/src/libmpeg2/libmpeg2_accel.h b/src/libmpeg2/libmpeg2_accel.h
new file mode 100644
index 000000000..24079e124
--- /dev/null
+++ b/src/libmpeg2/libmpeg2_accel.h
@@ -0,0 +1,48 @@
+/*
+ * libmpeg2_accel.h
+ * Copyright (C) 2004 The Unichrome Project.
+ * Copyright (C) 2005 Thomas Hellstrom.
+ *
+ * This file is part of xine, a free video player.
+ *
+ * xine is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifndef LIBMPEG2_ACCEL_H
+#define LIBMPEG2_ACCEL_H
+
+#include "mpeg2_internal.h"
+
+/*
+ * Internal context data type.
+ */
+
+typedef struct {
+ int xvmc_last_slice_code;
+ int slices_per_row;
+ int row_slice_count;
+ unsigned xxmc_mb_pic_height;
+} mpeg2dec_accel_t;
+
+extern int libmpeg2_accel_discontinuity(mpeg2dec_accel_t *accel, uint32_t frame_format, picture_t *picture);
+extern int libmpeg2_accel_new_sequence(mpeg2dec_accel_t *accel, uint32_t frame_format, picture_t *picture);
+extern int libmpeg2_accel_new_frame(mpeg2dec_accel_t *accel, uint32_t frame_format, picture_t *picture, double ratio);
+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 void libmpeg2_accel_scan( mpeg2dec_accel_t *accel, uint8_t *scan_norm, uint8_t *scan_alt);
+
+#endif
diff --git a/src/libmpeg2/mpeg2.h b/src/libmpeg2/mpeg2.h
index 679400d3e..788fa823c 100644
--- a/src/libmpeg2/mpeg2.h
+++ b/src/libmpeg2/mpeg2.h
@@ -24,6 +24,8 @@
#ifndef MPEG2_H
#define MPEG2_H
+#include "libmpeg2_accel.h"
+
typedef struct mpeg2dec_s {
xine_video_port_t * output;
uint32_t frame_format;
@@ -59,8 +61,8 @@ typedef struct mpeg2dec_s {
/* a spu decoder for possible closed captions */
spu_decoder_t *cc_dec;
- int xvmc_last_slice_code;
- unsigned xxmc_mb_pic_height;
+ mpeg2dec_accel_t accel;
+
} mpeg2dec_t ;
diff --git a/src/libmpeg2/mpeg2_internal.h b/src/libmpeg2/mpeg2_internal.h
index 6a9c9a775..64c6a2149 100644
--- a/src/libmpeg2/mpeg2_internal.h
+++ b/src/libmpeg2/mpeg2_internal.h
@@ -21,6 +21,9 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#ifndef MPEG2_INTERNAL_H
+#define MPEG2_INTERNAL_H
+
#include "video_out.h"
#include "accel_xvmc.h"
@@ -288,3 +291,4 @@ void mpeg2_slice (picture_t * picture, int code, uint8_t * buffer);
void mpeg2_stats (int code, uint8_t * buffer);
+#endif
diff --git a/src/libmpeg2/slice_xvmc.c b/src/libmpeg2/slice_xvmc.c
index f38a74b88..f3ce5fb74 100644
--- a/src/libmpeg2/slice_xvmc.c
+++ b/src/libmpeg2/slice_xvmc.c
@@ -1728,7 +1728,7 @@ static inline int slice_xvmc_init (picture_t * picture, int code)
#undef bit_ptr
}
-void mpeg2_xvmc_slice (mpeg2dec_t *mpeg2dec, picture_t * picture, int code, uint8_t * buffer)
+void mpeg2_xvmc_slice (mpeg2dec_accel_t *accel, picture_t * picture, int code, uint8_t * buffer)
{
#define bit_buf (picture->bitstream_buf)
#define bits (picture->bitstream_bits)
@@ -1737,10 +1737,10 @@ void mpeg2_xvmc_slice (mpeg2dec_t *mpeg2dec, picture_t * picture, int code, uint
xine_xvmc_t *xvmc = (xine_xvmc_t *) picture->current_frame->accel_data;
if (1 == code) {
- mpeg2dec->xvmc_last_slice_code = 0;
+ accel->xvmc_last_slice_code = 0;
}
- if ((code != mpeg2dec->xvmc_last_slice_code + 1) &&
- (code != mpeg2dec->xvmc_last_slice_code))
+ if ((code != accel->xvmc_last_slice_code + 1) &&
+ (code != accel->xvmc_last_slice_code))
return;
bitstream_init (picture, buffer);
@@ -1969,7 +1969,7 @@ void mpeg2_xvmc_slice (mpeg2dec_t *mpeg2dec, picture_t * picture, int code, uint
default: /* end of slice, or error */
if (mpeg2_cpu_state_restore)
mpeg2_cpu_state_restore (&cpu_state);
- mpeg2dec->xvmc_last_slice_code = code;
+ accel->xvmc_last_slice_code = code;
return;
}
}
@@ -2068,7 +2068,7 @@ void mpeg2_xvmc_slice (mpeg2dec_t *mpeg2dec, picture_t * picture, int code, uint
}
}
}
- mpeg2dec->xvmc_last_slice_code = code;
+ accel->xvmc_last_slice_code = code;
#undef bit_buf
#undef bits
#undef bit_ptr
diff --git a/src/libmpeg2/slice_xvmc_vld.c b/src/libmpeg2/slice_xvmc_vld.c
index 1159fd90e..3c177d97a 100644
--- a/src/libmpeg2/slice_xvmc_vld.c
+++ b/src/libmpeg2/slice_xvmc_vld.c
@@ -45,53 +45,10 @@ static uint8_t alternate_scan [64] ATTR_ALIGN(16) =
53,61,22,30,7,15,23,31,38,46,54,62,39,47,55,63
};
+void mpeg2_xxmc_slice( mpeg2dec_accel_t *accel, picture_t *picture,
+ int code, uint8_t *buffer, uint32_t chunk_size,
+ uint8_t *chunk_buffer)
-
-
-void mpeg2_xxmc_choose_coding(mpeg2dec_t *mpeg2dec, picture_t *picture,
- double aspect_ratio, int flags)
-{
- int
- decoder_format = mpeg2dec->frame_format;
-
- if (picture->current_frame) {
- if (XINE_IMGFMT_XXMC == decoder_format) {
- xine_xxmc_t *xxmc = (xine_xxmc_t *)
- picture->current_frame->accel_data;
-
- /*
- * Make a request for acceleration type and mpeg coding from
- * the output plugin.
- */
-
- xxmc->fallback_format = XINE_IMGFMT_YV12;
- xxmc->acceleration = XINE_XVMC_ACCEL_VLD| XINE_XVMC_ACCEL_IDCT
- | XINE_XVMC_ACCEL_MOCOMP ;
-
- /*
- * Standard MOCOMP / IDCT XvMC implementation for interlaced streams
- * is buggy. The bug is inherited from the old XvMC driver. Don't use it until
- * it has been fixed. (A volunteer ?)
- */
-
- if ( picture->picture_structure != 3 ) {
- xxmc->acceleration &= ~( XINE_XVMC_ACCEL_IDCT | XINE_XVMC_ACCEL_MOCOMP );
- }
-
- xxmc->mpeg = (picture->mpeg1) ? XINE_XVMC_MPEG_1:XINE_XVMC_MPEG_2;
- xxmc->proc_xxmc_update_frame (picture->current_frame->driver,
- picture->current_frame,
- picture->coded_picture_width,
- picture->coded_picture_height,
- aspect_ratio,
- XINE_IMGFMT_XXMC,flags);
- }
- }
-}
-
-
-void mpeg2_xxmc_slice( mpeg2dec_t *mpeg2dec, picture_t *picture, int code,
- uint8_t *buffer)
{
vo_frame_t
*frame = picture->current_frame;
@@ -108,8 +65,10 @@ void mpeg2_xxmc_slice( mpeg2dec_t *mpeg2dec, picture_t *picture, int code,
float
ms_per_slice;
- if (1 == code) {
+ if (1 == code && accel->xvmc_last_slice_code != 1) {
frame->bad_frame = 1;
+ accel->slices_per_row = 1;
+ accel->row_slice_count = 1;
/*
* Check that first field went through OK. Otherwise,
@@ -117,17 +76,17 @@ void mpeg2_xxmc_slice( mpeg2dec_t *mpeg2dec, picture_t *picture, int code,
*/
if (picture->second_field) {
- mpeg2dec->xvmc_last_slice_code = (xxmc->decoded) ? 0 : -1;
+ accel->xvmc_last_slice_code = (xxmc->decoded) ? 0 : -1;
xxmc->decoded = 0;
} else {
- mpeg2dec->xvmc_last_slice_code = 0;
+ accel->xvmc_last_slice_code = 0;
}
mb_frame_height =
(!(picture->mpeg1) && (picture->progressive_sequence)) ?
2*((picture->coded_picture_height+31) >> 5) :
(picture->coded_picture_height+15) >> 4;
- mpeg2dec->xxmc_mb_pic_height = (picture->picture_structure == FRAME_PICTURE ) ?
+ accel->xxmc_mb_pic_height = (picture->picture_structure == FRAME_PICTURE ) ?
mb_frame_height : mb_frame_height >> 1;
ms_per_slice = 1000. / (90000. * mb_frame_height) * frame->duration;
@@ -188,13 +147,12 @@ void mpeg2_xxmc_slice( mpeg2dec_t *mpeg2dec, picture_t *picture, int code,
xxmc->proc_xxmc_begin( frame );
if (xxmc->result != 0) {
xxmc->proc_xxmc_flush( frame );
- mpeg2dec->xvmc_last_slice_code=-1;
+ accel->xvmc_last_slice_code=-1;
}
}
- if (((code == mpeg2dec->xvmc_last_slice_code + 1) ||
- (code == mpeg2dec->xvmc_last_slice_code)) &&
- code <= mpeg2dec->xxmc_mb_pic_height) {
+ if (((code == accel->xvmc_last_slice_code + 1) ||
+ (code == accel->xvmc_last_slice_code))) {
/*
* Send this slice to the output plugin. May stall for a long
@@ -202,65 +160,61 @@ void mpeg2_xxmc_slice( mpeg2dec_t *mpeg2dec, picture_t *picture, int code,
*/
frame->bad_frame = 1;
- xxmc->slice_data_size = mpeg2dec->chunk_size;
- xxmc->slice_data = mpeg2dec->chunk_buffer;
+ xxmc->slice_data_size = chunk_size;
+ xxmc->slice_data = chunk_buffer;
xxmc->slice_code = code;
xxmc->proc_xxmc_slice( frame );
if (xxmc->result != 0) {
xxmc->proc_xxmc_flush( frame );
- mpeg2dec->xvmc_last_slice_code=-1;
+ accel->xvmc_last_slice_code=-1;
return;
}
-
- if (code == mpeg2dec->xxmc_mb_pic_height) {
-
- /*
- * We've encountered the last slice of this frame.
- * Release the decoder for a new frame and, if all
- * went well, tell libmpeg2 that we are ready.
- */
-
- mpeg2dec->xvmc_last_slice_code = code;
- mpeg2_xxmc_vld_frame_complete(mpeg2dec,picture,code);
- return;
- } else {
-
- /*
- * Keep track of slices.
- */
+ /*
+ * Keep track of slices.
+ */
- mpeg2dec->xvmc_last_slice_code = code;
- }
+ accel->row_slice_count = (accel->xvmc_last_slice_code == code) ?
+ accel->row_slice_count + 1 : 1;
+ accel->slices_per_row = (accel->row_slice_count > accel->slices_per_row) ?
+ accel->row_slice_count:accel->slices_per_row;
+ accel->xvmc_last_slice_code = code;
- } else {
+ } else {
/*
* An error has occured.
*/
lprintf("libmpeg2: VLD XvMC: Slice error.\n");
- mpeg2dec->xvmc_last_slice_code = -1;
+ accel->xvmc_last_slice_code = -1;
xxmc->proc_xxmc_flush( frame );
return;
}
}
-void mpeg2_xxmc_vld_frame_complete(mpeg2dec_t *mpeg2dec, picture_t *picture, int code)
+void mpeg2_xxmc_vld_frame_complete(mpeg2dec_accel_t *accel, picture_t *picture, int code)
{
vo_frame_t
*frame = picture->current_frame;
xine_xxmc_t
*xxmc = (xine_xxmc_t *) frame->accel_data;
- if (xxmc->decoded) return;
- xxmc->proc_xxmc_flush( frame );
- if (xxmc->result) {
- mpeg2dec->xvmc_last_slice_code=-1;
- return;
- }
- if (mpeg2dec->xvmc_last_slice_code >= 1) {
+ if (xxmc->decoded || (accel->xvmc_last_slice_code == -1)) return;
+
+ if ((code != 0xff) || ((accel->xvmc_last_slice_code ==
+ accel->xxmc_mb_pic_height) &&
+ accel->slices_per_row == accel->row_slice_count)) {
+
+ xxmc->proc_xxmc_flush( frame );
+
+ if (xxmc->result) {
+ accel->xvmc_last_slice_code=-1;
+ frame->bad_frame = 1;
+ return;
+ }
xxmc->decoded = 1;
+ accel->xvmc_last_slice_code = 0;
if (picture->picture_structure == 3 || picture->second_field) {
if (xxmc->result == 0)
frame->bad_frame = 0;
diff --git a/src/libmpeg2/xvmc.h b/src/libmpeg2/xvmc.h
index 5caa74297..e6204395d 100644
--- a/src/libmpeg2/xvmc.h
+++ b/src/libmpeg2/xvmc.h
@@ -22,7 +22,7 @@
*/
#ifndef _XVMC_H
-#include "mpeg2.h"
+#include "libmpeg2_accel.h"
/* slice_xvmc.c */
@@ -30,7 +30,7 @@ extern uint8_t mpeg2_scan_alt_ptable[64] ATTR_ALIGN(16);
extern uint8_t mpeg2_scan_norm_ptable[64] ATTR_ALIGN(16);
extern uint8_t mpeg2_scan_orig_ptable[64] ATTR_ALIGN(16);
-void mpeg2_xvmc_slice (mpeg2dec_t *mpeg2dec, picture_t * picture, int code, uint8_t * buffer);
+void mpeg2_xvmc_slice (mpeg2dec_accel_t *accel, picture_t * picture, int code, uint8_t * buffer);
void xvmc_setup_scan_ptable( void );
#endif
diff --git a/src/libmpeg2/xvmc_vld.h b/src/libmpeg2/xvmc_vld.h
index adc4a7a04..561d1789d 100644
--- a/src/libmpeg2/xvmc_vld.h
+++ b/src/libmpeg2/xvmc_vld.h
@@ -23,12 +23,10 @@
#include "accel_xvmc.h"
#include "xvmc.h"
-extern void mpeg2_xxmc_slice( mpeg2dec_t *mpeg2dec, picture_t *picture,
- int code, uint8_t *buffer);
-extern void mpeg2_xxmc_choose_coding(mpeg2dec_t *mpeg2dec, picture_t *picture,
- double aspect_ratio, int flags);
-
-extern void mpeg2_xxmc_vld_frame_complete(mpeg2dec_t *mpeg2dec, picture_t *picture, int code);
+extern void mpeg2_xxmc_slice( mpeg2dec_accel_t *accel, picture_t *picture,
+ int code, uint8_t *buffer, uint32_t chunk_size,
+ uint8_t *chunk_buffer);
+extern void mpeg2_xxmc_vld_frame_complete(mpeg2dec_accel_t *accel, picture_t *picture, int code);
#endif