From 1daa2c4132617848de05b492beaf05d428f27ccc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Hellstr=C3=B6m?= Date: Tue, 3 May 2005 19:25:10 +0000 Subject: **BUGFIX** Fixed xvmc plugin segfault when it tried software blending on nonexistant xv image. Cleaned up libmpeg2 behaviour on xxmc plugin abrupt software fallback. CVS patchset: 7516 CVS date: 2005/05/03 19:25:10 --- src/libmpeg2/decode.c | 5 +++-- src/libmpeg2/libmpeg2_accel.c | 29 ++++++++++++++++++++++++++--- src/libmpeg2/libmpeg2_accel.h | 2 +- src/video_out/video_out_xvmc.c | 6 ++---- 4 files changed, 32 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/libmpeg2/decode.c b/src/libmpeg2/decode.c index 63e6edbb4..5d3f78ec5 100644 --- a/src/libmpeg2/decode.c +++ b/src/libmpeg2/decode.c @@ -508,7 +508,7 @@ static inline int parse_chunk (mpeg2dec_t * mpeg2dec, int code, mpeg2dec->frame_format, flags); libmpeg2_accel_new_frame( &mpeg2dec->accel, mpeg2dec->frame_format, - picture, ratio); + picture, ratio, flags); } else { ratio = get_aspect_ratio(mpeg2dec); picture->current_frame = @@ -520,7 +520,7 @@ static inline int parse_chunk (mpeg2dec_t * mpeg2dec, int code, flags); libmpeg2_accel_new_frame( &mpeg2dec->accel, mpeg2dec->frame_format, - picture, ratio); + picture, ratio, flags); if (picture->forward_reference_frame && picture->forward_reference_frame != picture->backward_reference_frame) @@ -664,6 +664,7 @@ void mpeg2_discontinuity (mpeg2dec_t * mpeg2dec) { if( !picture ) return; + mpeg2dec->in_slice = 0; mpeg2dec->pts = 0; if ( picture->current_frame ) picture->current_frame->pts = 0; diff --git a/src/libmpeg2/libmpeg2_accel.c b/src/libmpeg2/libmpeg2_accel.c index 9d30e2b75..51e0b8b73 100644 --- a/src/libmpeg2/libmpeg2_accel.c +++ b/src/libmpeg2/libmpeg2_accel.c @@ -75,7 +75,7 @@ libmpeg2_accel_new_sequence(mpeg2dec_accel_t *accel, uint32_t frame_format, pict int libmpeg2_accel_new_frame(mpeg2dec_accel_t *accel, uint32_t frame_format, - picture_t *picture, double ratio) + picture_t *picture, double ratio, uint32_t flags) { if (picture->current_frame) { if (XINE_IMGFMT_XXMC == frame_format) { @@ -98,7 +98,7 @@ libmpeg2_accel_new_frame(mpeg2dec_accel_t *accel, uint32_t frame_format, */ if ( picture->picture_structure != 3 ) { - xxmc->acceleration &= ~( XINE_XVMC_ACCEL_IDCT | XINE_XVMC_ACCEL_MOCOMP ); + xxmc->acceleration &= ~( /* XINE_XVMC_ACCEL_IDCT | */ XINE_XVMC_ACCEL_MOCOMP ); } xxmc->mpeg = (picture->mpeg1) ? XINE_XVMC_MPEG_1:XINE_XVMC_MPEG_2; @@ -107,7 +107,7 @@ libmpeg2_accel_new_frame(mpeg2dec_accel_t *accel, uint32_t frame_format, picture->coded_picture_width, picture->coded_picture_height, ratio, - XINE_IMGFMT_XXMC, picture->picture_structure); + XINE_IMGFMT_XXMC, flags); } } return 0; @@ -150,6 +150,29 @@ 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) { + /* + * Don't reference frames of other formats. They are invalid. This may happen if the + * xxmc plugin suddenly falls back to software decoding. + */ + + if (( picture->current_frame->picture_coding_type == XINE_PICT_P_TYPE ) || + ( picture->current_frame->picture_coding_type == XINE_PICT_B_TYPE )) { + if (! picture->forward_reference_frame) return 1; + if (picture->forward_reference_frame->format != picture->current_frame->format) { + picture->v_offset = 0; + return 1; + } + } + + if ( picture->current_frame->picture_coding_type == XINE_PICT_B_TYPE ) { + if (! picture->backward_reference_frame) return 1; + if (picture->backward_reference_frame->format != picture->current_frame->format) { + picture->v_offset = 0; + return 1; + } + } + + switch( frame_format ) { case XINE_IMGFMT_XXMC: { diff --git a/src/libmpeg2/libmpeg2_accel.h b/src/libmpeg2/libmpeg2_accel.h index 24079e124..41b081cc5 100644 --- a/src/libmpeg2/libmpeg2_accel.h +++ b/src/libmpeg2/libmpeg2_accel.h @@ -38,7 +38,7 @@ typedef struct { 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 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, diff --git a/src/video_out/video_out_xvmc.c b/src/video_out/video_out_xvmc.c index 0b0e3ec24..4400f83f2 100644 --- a/src/video_out/video_out_xvmc.c +++ b/src/video_out/video_out_xvmc.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: video_out_xvmc.c,v 1.22 2005/04/26 09:03:04 totte67 Exp $ + * $Id: video_out_xvmc.c,v 1.23 2005/05/03 19:25:11 totte67 Exp $ * * video_out_xvmc.c, X11 video motion compensation extension interface for xine * @@ -790,8 +790,6 @@ static void xvmc_update_frame_format (vo_driver_t *this_gen, this->macroblocks.macroblockptr = this->macroblocks.macroblockbaseptr; this->macroblocks.xine_mc.blockptr = this->macroblocks.xine_mc.blockbaseptr; - - if( flags & VO_NEW_SEQUENCE_FLAG ) { xvmc_set_context (this, width, height, ratio, format, flags, xvmc->macroblocks); @@ -849,7 +847,7 @@ static void xvmc_overlay_blend (vo_driver_t *this_gen, blend_yuv(frame->vo_frame.base, overlay, frame->width, frame->height, frame->vo_frame.pitches, &this->alphablend_extra_data); - else + else if (frame->format != XINE_IMGFMT_XVMC) blend_yuy2(frame->vo_frame.base[0], overlay, frame->width, frame->height, frame->vo_frame.pitches[0], &this->alphablend_extra_data); -- cgit v1.2.3