diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/combined/ffmpeg/ff_video_decoder.c | 54 |
1 files changed, 40 insertions, 14 deletions
diff --git a/src/combined/ffmpeg/ff_video_decoder.c b/src/combined/ffmpeg/ff_video_decoder.c index a1ab3696c..01635e1ab 100644 --- a/src/combined/ffmpeg/ff_video_decoder.c +++ b/src/combined/ffmpeg/ff_video_decoder.c @@ -58,6 +58,12 @@ #define ENABLE_DIRECT_RENDERING +/* reordered_opaque appeared in libavcodec 51.68.0 */ +#define AVCODEC_HAS_REORDERED_OPAQUE +#if LIBAVCODEC_VERSION_INT < 0x334400 +# undef AVCODEC_HAS_REORDERED_OPAQUE +#endif + typedef struct ff_video_decoder_s ff_video_decoder_t; typedef struct ff_video_class_s { @@ -78,9 +84,11 @@ struct ff_video_decoder_s { xine_stream_t *stream; int64_t pts; +#ifdef AVCODEC_HAS_REORDERED_OPAQUE uint64_t pts_tag_mask; uint64_t pts_tag; int pts_tag_counter; +#endif /* AVCODEC_HAS_REORDERED_OPAQUE */ int video_step; uint8_t decoder_ok:1; @@ -609,10 +617,6 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) { su = this->av_frame->data[1]; sv = this->av_frame->data[2]; - /* Some segfaults & heap corruption have been observed with img->height, - * so we use this->bih.biHeight instead (which is the displayed height) - */ - if (this->context->pix_fmt == PIX_FMT_YUV410P) { yuv9_to_yv12( @@ -633,7 +637,7 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) { img->pitches[2], /* width x height */ img->width, - this->bih.biHeight); + img->height); } else if (this->context->pix_fmt == PIX_FMT_YUV411P) { @@ -655,7 +659,7 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) { img->pitches[2], /* width x height */ img->width, - this->bih.biHeight); + img->height); } else if (this->context->pix_fmt == PIX_FMT_RGBA32) { @@ -663,7 +667,7 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) { uint32_t *argb_pixels; uint32_t argb; - for(y = 0; y < this->bih.biHeight; y++) { + for(y = 0; y < img->height; y++) { argb_pixels = (uint32_t *)sy; for(x = 0; x < img->width; x++) { uint8_t r, g, b; @@ -691,7 +695,7 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) { uint8_t *src; uint16_t pixel16; - for(y = 0; y < this->bih.biHeight; y++) { + for(y = 0; y < img->height; y++) { src = sy; for(x = 0; x < img->width; x++) { uint8_t r, g, b; @@ -720,7 +724,7 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) { uint8_t *src; uint16_t pixel16; - for(y = 0; y < this->bih.biHeight; y++) { + for(y = 0; y < img->height; y++) { src = sy; for(x = 0; x < img->width; x++) { uint8_t r, g, b; @@ -748,7 +752,7 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) { int x, plane_ptr = 0; uint8_t *src; - for(y = 0; y < this->bih.biHeight; y++) { + for(y = 0; y < img->height; y++) { src = sy; for(x = 0; x < img->width; x++) { uint8_t r, g, b; @@ -772,7 +776,7 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) { int x, plane_ptr = 0; uint8_t *src; - for(y = 0; y < this->bih.biHeight; y++) { + for(y = 0; y < img->height; y++) { src = sy; for(x = 0; x < img->width; x++) { uint8_t r, g, b; @@ -815,7 +819,7 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) { v_palette[x] = COMPUTE_V(r, g, b); } - for(y = 0; y < this->bih.biHeight; y++) { + for(y = 0; y < img->height; y++) { src = sy; for(x = 0; x < img->width; x++) { pixel = *src++; @@ -832,7 +836,7 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) { } else { - for (y = 0; y < this->bih.biHeight; y++) { + for (y=0; y<img->height; y++) { xine_fast_memcpy (dy, sy, img->width); dy += img->pitches[0]; @@ -840,7 +844,7 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) { sy += this->av_frame->linesize[0]; } - for (y = 0; y < this->bih.biHeight / 2; y++) { + for (y=0; y<(img->height/2); y++) { if (this->context->pix_fmt != PIX_FMT_YUV444P) { @@ -1181,6 +1185,7 @@ static void ff_handle_mpeg12_buffer (ff_video_decoder_t *this, buf_element_t *bu } } +#ifdef AVCODEC_HAS_REORDERED_OPAQUE static uint64_t ff_tag_pts(ff_video_decoder_t *this, uint64_t pts) { return pts | this->pts_tag; @@ -1217,6 +1222,7 @@ static void ff_check_pts_tagging(ff_video_decoder_t *this, uint64_t pts) } } +#endif /* AVCODEC_HAS_REORDERED_OPAQUE */ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) { uint8_t *chunk_buf = this->buf; AVRational avr00 = {0, 1}; @@ -1241,12 +1247,14 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) { this->size = 0; } +#ifdef AVCODEC_HAS_REORDERED_OPAQUE if (this->size == 0) { /* take over pts when we are about to buffer a frame */ this->av_frame->reordered_opaque = ff_tag_pts(this, this->pts); this->context->reordered_opaque = ff_tag_pts(this, this->pts); this->pts = 0; } +#endif /* AVCODEC_HAS_REORDERED_OPAQUE */ /* data accumulation */ if (buf->size > 0) { @@ -1301,8 +1309,10 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) { &got_picture, &chunk_buf[offset], this->size); +#ifdef AVCODEC_HAS_REORDERED_OPAQUE /* reset consumed pts value */ this->context->reordered_opaque = ff_tag_pts(this, 0); +#endif /* AVCODEC_HAS_REORDERED_OPAQUE */ lprintf("consumed size: %d, got_picture: %d\n", len, got_picture); if ((len <= 0) || (len > this->size)) { @@ -1320,10 +1330,12 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) { memmove (this->buf, &chunk_buf[offset], this->size); chunk_buf = this->buf; +#ifdef AVCODEC_HAS_REORDERED_OPAQUE /* take over pts for next access unit */ this->av_frame->reordered_opaque = ff_tag_pts(this, this->pts); this->context->reordered_opaque = ff_tag_pts(this, this->pts); this->pts = 0; +#endif /* AVCODEC_HAS_REORDERED_OPAQUE */ } } } @@ -1418,9 +1430,14 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) { ff_convert_frame(this, img); } +#ifndef AVCODEC_HAS_REORDERED_OPAQUE + img->pts = this->pts; + this->pts = 0; +#else /* AVCODEC_HAS_REORDERED_OPAQUE */ img->pts = ff_untag_pts(this, this->av_frame->reordered_opaque); ff_check_pts_tagging(this, this->av_frame->reordered_opaque); /* only check for valid frames */ this->av_frame->reordered_opaque = 0; +#endif /* AVCODEC_HAS_REORDERED_OPAQUE */ /* workaround for weird 120fps streams */ if( video_step_to_use == 750 ) { @@ -1460,8 +1477,13 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) { this->output_format, VO_BOTH_FIELDS|this->frame_flags); /* set PTS to allow early syncing */ +#ifndef AVCODEC_HAS_REORDERED_OPAQUE + img->pts = this->pts; + this->pts = 0; +#else /* AVCODEC_HAS_REORDERED_OPAQUE */ img->pts = ff_untag_pts(this, this->av_frame->reordered_opaque); this->av_frame->reordered_opaque = 0; +#endif /* AVCODEC_HAS_REORDERED_OPAQUE */ img->duration = video_step_to_use; @@ -1547,9 +1569,11 @@ static void ff_reset (video_decoder_t *this_gen) { if (this->is_mpeg12) mpeg_parser_reset(this->mpeg_parser); +#ifdef AVCODEC_HAS_REORDERED_OPAQUE this->pts_tag_mask = 0; this->pts_tag = 0; this->pts_tag_counter = 0; +#endif /* AVCODEC_HAS_REORDERED_OPAQUE */ } static void ff_discontinuity (video_decoder_t *this_gen) { @@ -1558,6 +1582,7 @@ static void ff_discontinuity (video_decoder_t *this_gen) { lprintf ("ff_discontinuity\n"); this->pts = 0; +#ifdef AVCODEC_HAS_REORDERED_OPAQUE /* * there is currently no way to reset all the pts which are stored in the decoder. * therefore, we add a unique tag (generated from pts_tag_counter) to pts (see @@ -1588,6 +1613,7 @@ static void ff_discontinuity (video_decoder_t *this_gen) { counter_mask <<= 1; } } +#endif /* AVCODEC_HAS_REORDERED_OPAQUE */ } static void ff_dispose (video_decoder_t *this_gen) { |