mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-01-13 21:28:01 +02:00
Fix VC-1 width/height handling.
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 <Reimar.Doeffinger@gmx.de>
This commit is contained in:
parent
86ca51acb0
commit
4f00519d95
@ -388,8 +388,9 @@ int vc1_decode_sequence_header(AVCodecContext *avctx, VC1Context *v, GetBitConte
|
|||||||
v->finterpflag = get_bits1(gb); //common
|
v->finterpflag = get_bits1(gb); //common
|
||||||
|
|
||||||
if (v->res_sprite) {
|
if (v->res_sprite) {
|
||||||
v->s.avctx->width = v->s.avctx->coded_width = get_bits(gb, 11);
|
int w = get_bits(gb, 11);
|
||||||
v->s.avctx->height = v->s.avctx->coded_height = get_bits(gb, 11);
|
int h = get_bits(gb, 11);
|
||||||
|
avcodec_set_dimensions(v->s.avctx, w, h);
|
||||||
skip_bits(gb, 5); //frame rate
|
skip_bits(gb, 5); //frame rate
|
||||||
v->res_x8 = get_bits1(gb);
|
v->res_x8 = get_bits1(gb);
|
||||||
if (get_bits1(gb)) { // something to do with DC VLC selection
|
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)
|
static int decode_sequence_header_adv(VC1Context *v, GetBitContext *gb)
|
||||||
{
|
{
|
||||||
|
int w, h;
|
||||||
v->res_rtm_flag = 1;
|
v->res_rtm_flag = 1;
|
||||||
v->level = get_bits(gb, 3);
|
v->level = get_bits(gb, 3);
|
||||||
if(v->level >= 5)
|
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->bitrtq_postproc = get_bits(gb, 5); //common
|
||||||
v->postprocflag = get_bits1(gb); //common
|
v->postprocflag = get_bits1(gb); //common
|
||||||
|
|
||||||
v->s.avctx->coded_width = (get_bits(gb, 12) + 1) << 1;
|
w = (get_bits(gb, 12) + 1) << 1;
|
||||||
v->s.avctx->coded_height = (get_bits(gb, 12) + 1) << 1;
|
h = (get_bits(gb, 12) + 1) << 1;
|
||||||
v->s.avctx->width = v->s.avctx->coded_width;
|
avcodec_set_dimensions(v->s.avctx, w, h);
|
||||||
v->s.avctx->height = v->s.avctx->coded_height;
|
|
||||||
v->broadcast = get_bits1(gb);
|
v->broadcast = get_bits1(gb);
|
||||||
v->interlace = get_bits1(gb);
|
v->interlace = get_bits1(gb);
|
||||||
v->tfcntrflag = get_bits1(gb);
|
v->tfcntrflag = get_bits1(gb);
|
||||||
v->finterpflag = get_bits1(gb);
|
v->finterpflag = get_bits1(gb);
|
||||||
skip_bits1(gb); // reserved
|
skip_bits1(gb); // reserved
|
||||||
|
|
||||||
v->s.h_edge_pos = v->s.avctx->coded_width;
|
v->s.h_edge_pos = w;
|
||||||
v->s.v_edge_pos = v->s.avctx->coded_height;
|
v->s.v_edge_pos = h;
|
||||||
|
|
||||||
av_log(v->s.avctx, AV_LOG_DEBUG,
|
av_log(v->s.avctx, AV_LOG_DEBUG,
|
||||||
"Advanced Profile level %i:\nfrmrtq_postproc=%i, bitrtq_postproc=%i\n"
|
"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;
|
v->s.max_b_frames = v->s.avctx->max_b_frames = 7;
|
||||||
if(get_bits1(gb)) { //Display Info - decoding is not affected by it
|
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");
|
av_log(v->s.avctx, AV_LOG_DEBUG, "Display extended info:\n");
|
||||||
v->s.avctx->width = w = get_bits(gb, 14) + 1;
|
dw = get_bits(gb, 14) + 1;
|
||||||
v->s.avctx->height = h = get_bits(gb, 14) + 1;
|
dh = get_bits(gb, 14) + 1;
|
||||||
av_log(v->s.avctx, AV_LOG_DEBUG, "Display dimensions: %ix%i\n", w, h);
|
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))
|
if(get_bits1(gb))
|
||||||
ar = get_bits(gb, 4);
|
ar = get_bits(gb, 4);
|
||||||
if(ar && ar < 14){
|
if(ar && ar < 14){
|
||||||
@ -551,8 +553,9 @@ int vc1_decode_entry_point(AVCodecContext *avctx, VC1Context *v, GetBitContext *
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(get_bits1(gb)){
|
if(get_bits1(gb)){
|
||||||
avctx->coded_width = (get_bits(gb, 12)+1)<<1;
|
int w = (get_bits(gb, 12)+1)<<1;
|
||||||
avctx->coded_height = (get_bits(gb, 12)+1)<<1;
|
int h = (get_bits(gb, 12)+1)<<1;
|
||||||
|
avcodec_set_dimensions(avctx, w, h);
|
||||||
}
|
}
|
||||||
if(v->extended_mv)
|
if(v->extended_mv)
|
||||||
v->extended_dmv = get_bits1(gb);
|
v->extended_dmv = get_bits1(gb);
|
||||||
|
@ -3418,8 +3418,8 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx)
|
|||||||
if (vc1_init_common(v) < 0) return -1;
|
if (vc1_init_common(v) < 0) return -1;
|
||||||
ff_vc1dsp_init(&v->vc1dsp);
|
ff_vc1dsp_init(&v->vc1dsp);
|
||||||
|
|
||||||
cur_width = avctx->coded_width = avctx->width;
|
cur_width = avctx->coded_width;
|
||||||
cur_height = avctx->coded_height = avctx->height;
|
cur_height = avctx->coded_height;
|
||||||
if (avctx->codec_id == CODEC_ID_WMV3)
|
if (avctx->codec_id == CODEC_ID_WMV3)
|
||||||
{
|
{
|
||||||
int count = 0;
|
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
|
// yet when ff_msmpeg4_decode_init was called the fist time
|
||||||
// above. If sequence information changes, we need to call
|
// above. If sequence information changes, we need to call
|
||||||
// it again.
|
// it again.
|
||||||
if (cur_width != avctx->width ||
|
if (cur_width != avctx->coded_width ||
|
||||||
cur_height != avctx->height) {
|
cur_height != avctx->coded_height) {
|
||||||
MPV_common_end(s);
|
MPV_common_end(s);
|
||||||
if(ff_msmpeg4_decode_init(avctx) < 0)
|
if(ff_msmpeg4_decode_init(avctx) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
avctx->coded_width = avctx->width;
|
|
||||||
avctx->coded_height = avctx->height;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
avctx->profile = v->profile;
|
avctx->profile = v->profile;
|
||||||
|
Loading…
Reference in New Issue
Block a user