diff options
-rw-r--r-- | configure.ac | 5 | ||||
-rw-r--r-- | src/libmpeg2/Makefile.am | 3 | ||||
-rw-r--r-- | src/libmpeg2/decode.c | 173 | ||||
-rw-r--r-- | src/libmpeg2/libmpeg2_accel.c | 188 | ||||
-rw-r--r-- | src/libmpeg2/libmpeg2_accel.h | 48 | ||||
-rw-r--r-- | src/libmpeg2/mpeg2.h | 6 | ||||
-rw-r--r-- | src/libmpeg2/mpeg2_internal.h | 4 | ||||
-rw-r--r-- | src/libmpeg2/slice_xvmc.c | 12 | ||||
-rw-r--r-- | src/libmpeg2/slice_xvmc_vld.c | 126 | ||||
-rw-r--r-- | src/libmpeg2/xvmc.h | 4 | ||||
-rw-r--r-- | src/libmpeg2/xvmc_vld.h | 10 |
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 |