From 4f00519d9508e07aac58a00a9b514dae8ad95723 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Reimar=20D=C3=B6ffinger?= Date: Sat, 13 Aug 2011 11:32:10 +0200 Subject: [PATCH] Fix VC-1 width/height handling. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit avcodec_set_dimensions should be used for size changes to ensure compatibility with future changes. avctx->width/avctx->height may not be set to display-only dimensions. Even more so since vc1dec.c would later set coded_width/height based on this. coded_width/coded_height should be used instead of width/height for decoder setup. This fixes playback of e.g. zz-mcr-nsqr.vc1 sample (containing display width/height settings) in MPlayer and should fix a crash with MPC: http://forum.doom9.org/showthread.php?t=162221. Signed-off-by: Reimar Döffinger --- libavcodec/vc1.c | 31 +++++++++++++++++-------------- libavcodec/vc1dec.c | 10 ++++------ 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/libavcodec/vc1.c b/libavcodec/vc1.c index 41cc1c8d21..3cb556c3d4 100644 --- a/libavcodec/vc1.c +++ b/libavcodec/vc1.c @@ -388,8 +388,9 @@ int vc1_decode_sequence_header(AVCodecContext *avctx, VC1Context *v, GetBitConte v->finterpflag = get_bits1(gb); //common if (v->res_sprite) { - v->s.avctx->width = v->s.avctx->coded_width = get_bits(gb, 11); - v->s.avctx->height = v->s.avctx->coded_height = get_bits(gb, 11); + int w = get_bits(gb, 11); + int h = get_bits(gb, 11); + avcodec_set_dimensions(v->s.avctx, w, h); skip_bits(gb, 5); //frame rate v->res_x8 = get_bits1(gb); if (get_bits1(gb)) { // something to do with DC VLC selection @@ -426,6 +427,7 @@ int vc1_decode_sequence_header(AVCodecContext *avctx, VC1Context *v, GetBitConte static int decode_sequence_header_adv(VC1Context *v, GetBitContext *gb) { + int w, h; v->res_rtm_flag = 1; v->level = get_bits(gb, 3); if(v->level >= 5) @@ -446,18 +448,17 @@ static int decode_sequence_header_adv(VC1Context *v, GetBitContext *gb) v->bitrtq_postproc = get_bits(gb, 5); //common v->postprocflag = get_bits1(gb); //common - v->s.avctx->coded_width = (get_bits(gb, 12) + 1) << 1; - v->s.avctx->coded_height = (get_bits(gb, 12) + 1) << 1; - v->s.avctx->width = v->s.avctx->coded_width; - v->s.avctx->height = v->s.avctx->coded_height; + w = (get_bits(gb, 12) + 1) << 1; + h = (get_bits(gb, 12) + 1) << 1; + avcodec_set_dimensions(v->s.avctx, w, h); v->broadcast = get_bits1(gb); v->interlace = get_bits1(gb); v->tfcntrflag = get_bits1(gb); v->finterpflag = get_bits1(gb); skip_bits1(gb); // reserved - v->s.h_edge_pos = v->s.avctx->coded_width; - v->s.v_edge_pos = v->s.avctx->coded_height; + v->s.h_edge_pos = w; + v->s.v_edge_pos = h; av_log(v->s.avctx, AV_LOG_DEBUG, "Advanced Profile level %i:\nfrmrtq_postproc=%i, bitrtq_postproc=%i\n" @@ -475,11 +476,12 @@ static int decode_sequence_header_adv(VC1Context *v, GetBitContext *gb) } v->s.max_b_frames = v->s.avctx->max_b_frames = 7; if(get_bits1(gb)) { //Display Info - decoding is not affected by it - int w, h, ar = 0; + int dw, dh, ar = 0; av_log(v->s.avctx, AV_LOG_DEBUG, "Display extended info:\n"); - v->s.avctx->width = w = get_bits(gb, 14) + 1; - v->s.avctx->height = h = get_bits(gb, 14) + 1; - av_log(v->s.avctx, AV_LOG_DEBUG, "Display dimensions: %ix%i\n", w, h); + dw = get_bits(gb, 14) + 1; + dh = get_bits(gb, 14) + 1; + v->s.avctx->sample_aspect_ratio = av_div_q((AVRational){dw, dh}, (AVRational){w, h}); + av_log(v->s.avctx, AV_LOG_DEBUG, "Display dimensions: %ix%i\n", dw, dh); if(get_bits1(gb)) ar = get_bits(gb, 4); if(ar && ar < 14){ @@ -551,8 +553,9 @@ int vc1_decode_entry_point(AVCodecContext *avctx, VC1Context *v, GetBitContext * } if(get_bits1(gb)){ - avctx->coded_width = (get_bits(gb, 12)+1)<<1; - avctx->coded_height = (get_bits(gb, 12)+1)<<1; + int w = (get_bits(gb, 12)+1)<<1; + int h = (get_bits(gb, 12)+1)<<1; + avcodec_set_dimensions(avctx, w, h); } if(v->extended_mv) v->extended_dmv = get_bits1(gb); diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c index 228a02a255..7c5ce62b47 100644 --- a/libavcodec/vc1dec.c +++ b/libavcodec/vc1dec.c @@ -3418,8 +3418,8 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx) if (vc1_init_common(v) < 0) return -1; ff_vc1dsp_init(&v->vc1dsp); - cur_width = avctx->coded_width = avctx->width; - cur_height = avctx->coded_height = avctx->height; + cur_width = avctx->coded_width; + cur_height = avctx->coded_height; if (avctx->codec_id == CODEC_ID_WMV3) { int count = 0; @@ -3494,13 +3494,11 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx) // yet when ff_msmpeg4_decode_init was called the fist time // above. If sequence information changes, we need to call // it again. - if (cur_width != avctx->width || - cur_height != avctx->height) { + if (cur_width != avctx->coded_width || + cur_height != avctx->coded_height) { MPV_common_end(s); if(ff_msmpeg4_decode_init(avctx) < 0) return -1; - avctx->coded_width = avctx->width; - avctx->coded_height = avctx->height; } avctx->profile = v->profile;