From 0313653928b47c3b0e493c08c66bb1a374695f7c Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 1 Feb 2013 19:58:26 +0100 Subject: [PATCH 01/13] vc1dec: Update destination pointers in context for fields MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This replaces a large number of checks for the second field by fixing the pointers when they are setup. This should also fix I/BI field pictures. Changes checksums for vc1_sa10143, the file becomes slightly closer to what the reference decoder outputs. Based on "vc1dec: the second field is written wrong to the picture" by Sebastian Sandberg . Signed-off-by: Martin Storsjö --- libavcodec/vc1dec.c | 55 +++++++++++++++++--------------------- tests/ref/fate/vc1_sa10143 | 28 +++++++++---------- 2 files changed, 38 insertions(+), 45 deletions(-) diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c index f1dc10aadb..1238da2859 100644 --- a/libavcodec/vc1dec.c +++ b/libavcodec/vc1dec.c @@ -73,6 +73,16 @@ enum Imode { }; /** @} */ //imode defines +static void init_block_index(VC1Context *v) +{ + MpegEncContext *s = &v->s; + ff_init_block_index(s); + if (v->field_mode && v->second_field) { + s->dest[0] += s->current_picture_ptr->f.linesize[0]; + s->dest[1] += s->current_picture_ptr->f.linesize[1]; + s->dest[2] += s->current_picture_ptr->f.linesize[2]; + } +} /** @} */ //Bitplane group @@ -495,13 +505,8 @@ static void vc1_mc_1mv(VC1Context *v, int dir) srcY += s->mspel * (1 + s->linesize); } - if (v->field_mode && v->cur_field_type) { - off = s->current_picture_ptr->f.linesize[0]; - off_uv = s->current_picture_ptr->f.linesize[1]; - } else { - off = 0; - off_uv = 0; - } + off = 0; + off_uv = 0; if (s->mspel) { dxy = ((my & 3) << 2) | (mx & 3); v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + off , srcY , s->linesize, v->rnd); @@ -631,8 +636,6 @@ static void vc1_mc_4mv_luma(VC1Context *v, int n, int dir) off = ((n > 1) ? s->linesize : 0) + (n & 1) * 8; else off = s->linesize * 4 * (n & 2) + (n & 1) * 8; - if (v->field_mode && v->cur_field_type) - off += s->current_picture_ptr->f.linesize[0]; src_x = s->mb_x * 16 + (n & 1) * 8 + (mx >> 2); if (!fieldmv) @@ -863,7 +866,7 @@ static void vc1_mc_4mv_chroma(VC1Context *v, int dir) srcU += s->current_picture_ptr->f.linesize[1]; srcV += s->current_picture_ptr->f.linesize[2]; } - off = v->cur_field_type ? s->current_picture_ptr->f.linesize[1] : 0; + off = 0; } if (v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP) @@ -1930,13 +1933,8 @@ static void vc1_interp_mc(VC1Context *v) srcY += s->mspel * (1 + s->linesize); } - if (v->field_mode && v->cur_field_type) { - off = s->current_picture_ptr->f.linesize[0]; - off_uv = s->current_picture_ptr->f.linesize[1]; - } else { - off = 0; - off_uv = 0; - } + off = 0; + off_uv = 0; if (s->mspel) { dxy = ((my & 3) << 2) | (mx & 3); @@ -3940,7 +3938,6 @@ static int vc1_decode_p_mb_intfi(VC1Context *v) continue; v->vc1dsp.vc1_inv_trans_8x8(s->block[i]); off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize); - off += v->cur_field_type ? ((i & 4) ? s->current_picture_ptr->f.linesize[1] : s->current_picture_ptr->f.linesize[0]) : 0; s->dsp.put_signed_pixels_clamped(s->block[i], s->dest[dst_idx] + off, (i & 4) ? s->uvlinesize : s->linesize); // TODO: loop filter } @@ -3987,8 +3984,6 @@ static int vc1_decode_p_mb_intfi(VC1Context *v) dst_idx += i >> 2; val = ((cbp >> (5 - i)) & 1); off = (i & 4) ? 0 : (i & 1) * 8 + (i & 2) * 4 * s->linesize; - if (v->cur_field_type) - off += (i & 4) ? s->current_picture_ptr->f.linesize[1] : s->current_picture_ptr->f.linesize[0]; if (val) { pat = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, first_block, s->dest[dst_idx] + off, @@ -4217,7 +4212,6 @@ static void vc1_decode_b_mb_intfi(VC1Context *v) for (j = 0; j < 64; j++) s->block[i][j] <<= 1; off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize); - off += v->cur_field_type ? ((i & 4) ? s->current_picture_ptr->f.linesize[1] : s->current_picture_ptr->f.linesize[0]) : 0; s->dsp.put_signed_pixels_clamped(s->block[i], s->dest[dst_idx] + off, (i & 4) ? s->uvlinesize : s->linesize); // TODO: yet to perform loop filter } @@ -4299,8 +4293,6 @@ static void vc1_decode_b_mb_intfi(VC1Context *v) dst_idx += i >> 2; val = ((cbp >> (5 - i)) & 1); off = (i & 4) ? 0 : (i & 1) * 8 + (i & 2) * 4 * s->linesize; - if (v->cur_field_type) - off += (i & 4) ? s->current_picture_ptr->f.linesize[1] : s->current_picture_ptr->f.linesize[0]; if (val) { vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, first_block, s->dest[dst_idx] + off, @@ -4359,7 +4351,7 @@ static void vc1_decode_i_blocks(VC1Context *v) s->first_slice_line = 1; for (s->mb_y = 0; s->mb_y < s->end_mb_y; s->mb_y++) { s->mb_x = 0; - ff_init_block_index(s); + init_block_index(v); for (; s->mb_x < v->end_mb_x; s->mb_x++) { uint8_t *dst[6]; ff_update_block_index(s); @@ -4499,13 +4491,13 @@ static void vc1_decode_i_blocks_adv(VC1Context *v) s->mb_y = s->start_mb_y; if (s->start_mb_y) { s->mb_x = 0; - ff_init_block_index(s); + init_block_index(v); memset(&s->coded_block[s->block_index[0] - s->b8_stride], 0, (1 + s->b8_stride) * sizeof(*s->coded_block)); } for (; s->mb_y < s->end_mb_y; s->mb_y++) { s->mb_x = 0; - ff_init_block_index(s); + init_block_index(v); for (;s->mb_x < s->mb_width; s->mb_x++) { int16_t (*block)[64] = v->block[v->cur_blk_idx]; ff_update_block_index(s); @@ -4576,7 +4568,8 @@ static void vc1_decode_i_blocks_adv(VC1Context *v) /* raw bottom MB row */ s->mb_x = 0; - ff_init_block_index(s); + init_block_index(v); + for (;s->mb_x < s->mb_width; s->mb_x++) { ff_update_block_index(s); vc1_put_signed_blocks_clamped(v); @@ -4625,7 +4618,7 @@ static void vc1_decode_p_blocks(VC1Context *v) memset(v->cbp_base, 0, sizeof(v->cbp_base[0])*2*s->mb_stride); for (s->mb_y = s->start_mb_y; s->mb_y < s->end_mb_y; s->mb_y++) { s->mb_x = 0; - ff_init_block_index(s); + init_block_index(v); for (; s->mb_x < s->mb_width; s->mb_x++) { ff_update_block_index(s); @@ -4653,7 +4646,7 @@ static void vc1_decode_p_blocks(VC1Context *v) } if (apply_loop_filter) { s->mb_x = 0; - ff_init_block_index(s); + init_block_index(v); for (; s->mb_x < s->mb_width; s->mb_x++) { ff_update_block_index(s); vc1_apply_p_loop_filter(v); @@ -4697,7 +4690,7 @@ static void vc1_decode_b_blocks(VC1Context *v) s->first_slice_line = 1; for (s->mb_y = s->start_mb_y; s->mb_y < s->end_mb_y; s->mb_y++) { s->mb_x = 0; - ff_init_block_index(s); + init_block_index(v); for (; s->mb_x < s->mb_width; s->mb_x++) { ff_update_block_index(s); @@ -4734,7 +4727,7 @@ static void vc1_decode_skip_blocks(VC1Context *v) s->first_slice_line = 1; for (s->mb_y = s->start_mb_y; s->mb_y < s->end_mb_y; s->mb_y++) { s->mb_x = 0; - ff_init_block_index(s); + init_block_index(v); ff_update_block_index(s); memcpy(s->dest[0], s->last_picture.f.data[0] + s->mb_y * 16 * s->linesize, s->linesize * 16); memcpy(s->dest[1], s->last_picture.f.data[1] + s->mb_y * 8 * s->uvlinesize, s->uvlinesize * 8); diff --git a/tests/ref/fate/vc1_sa10143 b/tests/ref/fate/vc1_sa10143 index 0d2e697989..6a5137f712 100644 --- a/tests/ref/fate/vc1_sa10143 +++ b/tests/ref/fate/vc1_sa10143 @@ -1,31 +1,31 @@ #tb 0: 1/25 0, 0, 0, 1, 518400, 0x89407f55 -0, 2, 2, 1, 518400, 0x1480849d +0, 2, 2, 1, 518400, 0x8611849c 0, 3, 3, 1, 518400, 0x0e69ff59 -0, 4, 4, 1, 518400, 0x00d6db06 +0, 4, 4, 1, 518400, 0xf31adb03 0, 5, 5, 1, 518400, 0x1a5b6a69 -0, 6, 6, 1, 518400, 0xc1a1232e +0, 6, 6, 1, 518400, 0x6ae6232e 0, 7, 7, 1, 518400, 0x9a4e3c54 -0, 8, 8, 1, 518400, 0x04122b44 +0, 8, 8, 1, 518400, 0xe5852b45 0, 9, 9, 1, 518400, 0x0fcfeebc -0, 10, 10, 1, 518400, 0xc7882dc1 +0, 10, 10, 1, 518400, 0x06e22dc3 0, 11, 11, 1, 518400, 0x9d79df09 -0, 12, 12, 1, 518400, 0xff6b716f +0, 12, 12, 1, 518400, 0xcb2c716f 0, 13, 13, 1, 518400, 0x638a8746 -0, 14, 14, 1, 518400, 0x07572efb +0, 14, 14, 1, 518400, 0xf7032efd 0, 15, 15, 1, 518400, 0x306f6cef -0, 16, 16, 1, 518400, 0xd7602518 +0, 16, 16, 1, 518400, 0xe83d2518 0, 17, 17, 1, 518400, 0x49ab5bf5 -0, 18, 18, 1, 518400, 0x3c736b6c +0, 18, 18, 1, 518400, 0x6b336b6f 0, 19, 19, 1, 518400, 0x95ae00c9 -0, 20, 20, 1, 518400, 0x7b9ab64e +0, 20, 20, 1, 518400, 0x68ddb64f 0, 21, 21, 1, 518400, 0x5205ea68 -0, 22, 22, 1, 518400, 0xb486e618 +0, 22, 22, 1, 518400, 0xb088e617 0, 23, 23, 1, 518400, 0xa3217616 -0, 24, 24, 1, 518400, 0xc66bbc56 +0, 24, 24, 1, 518400, 0x1723bc53 0, 25, 25, 1, 518400, 0xf024872a -0, 26, 26, 1, 518400, 0x97d2a8ba +0, 26, 26, 1, 518400, 0x2e81a8bb 0, 27, 27, 1, 518400, 0xa3a2418e -0, 28, 28, 1, 518400, 0x08460005 +0, 28, 28, 1, 518400, 0xb7beffed 0, 29, 29, 1, 518400, 0x50fb6c94 0, 30, 30, 1, 518400, 0x5584bb40 From 012b319d9147c18e6148003052b147722d11fe6e Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sat, 20 Apr 2013 02:15:13 +0200 Subject: [PATCH 02/13] vc1dec: Fix tff == 0 handling in init_block_index() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes several files from VLC ticket 5887. Signed-off-by: Martin Storsjö --- libavcodec/vc1dec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c index 1238da2859..b07214ad6f 100644 --- a/libavcodec/vc1dec.c +++ b/libavcodec/vc1dec.c @@ -77,7 +77,7 @@ static void init_block_index(VC1Context *v) { MpegEncContext *s = &v->s; ff_init_block_index(s); - if (v->field_mode && v->second_field) { + if (v->field_mode && !(v->second_field ^ v->tff)) { s->dest[0] += s->current_picture_ptr->f.linesize[0]; s->dest[1] += s->current_picture_ptr->f.linesize[1]; s->dest[2] += s->current_picture_ptr->f.linesize[2]; From 19673db34aa0fb014a07cb3e72970c1c0aeeeac1 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Mon, 12 Nov 2012 01:34:44 +0100 Subject: [PATCH 03/13] vc1dec: Factorize srcU/V offseting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavcodec/vc1dec.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c index b07214ad6f..838ebee7a3 100644 --- a/libavcodec/vc1dec.c +++ b/libavcodec/vc1dec.c @@ -846,21 +846,24 @@ static void vc1_mc_4mv_chroma(VC1Context *v, int dir) if (!dir) { if (v->field_mode) { if ((v->cur_field_type != chroma_ref_type) && v->cur_field_type) { - srcU = s->current_picture.f.data[1] + uvsrc_y * s->uvlinesize + uvsrc_x; - srcV = s->current_picture.f.data[2] + uvsrc_y * s->uvlinesize + uvsrc_x; + srcU = s->current_picture.f.data[1]; + srcV = s->current_picture.f.data[2]; } else { - srcU = s->last_picture.f.data[1] + uvsrc_y * s->uvlinesize + uvsrc_x; - srcV = s->last_picture.f.data[2] + uvsrc_y * s->uvlinesize + uvsrc_x; + srcU = s->last_picture.f.data[1]; + srcV = s->last_picture.f.data[2]; } } else { - srcU = s->last_picture.f.data[1] + uvsrc_y * s->uvlinesize + uvsrc_x; - srcV = s->last_picture.f.data[2] + uvsrc_y * s->uvlinesize + uvsrc_x; + srcU = s->last_picture.f.data[1]; + srcV = s->last_picture.f.data[2]; } } else { - srcU = s->next_picture.f.data[1] + uvsrc_y * s->uvlinesize + uvsrc_x; - srcV = s->next_picture.f.data[2] + uvsrc_y * s->uvlinesize + uvsrc_x; + srcU = s->next_picture.f.data[1]; + srcV = s->next_picture.f.data[2]; } + srcU += uvsrc_y * s->uvlinesize + uvsrc_x; + srcV += uvsrc_y * s->uvlinesize + uvsrc_x; + if (v->field_mode) { if (chroma_ref_type) { srcU += s->current_picture_ptr->f.linesize[1]; From 2412ad171716edc57905f9473123a59ebce2ed63 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 24 Apr 2013 14:49:31 +0200 Subject: [PATCH 04/13] vc1dec: Factorize picture pointer selection code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavcodec/vc1dec.c | 37 +++++++++++-------------------------- 1 file changed, 11 insertions(+), 26 deletions(-) diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c index 838ebee7a3..b13e91f924 100644 --- a/libavcodec/vc1dec.c +++ b/libavcodec/vc1dec.c @@ -379,32 +379,20 @@ static void vc1_mc_1mv(VC1Context *v, int dir) uvmx = uvmx + ((uvmx < 0) ? (uvmx & 1) : -(uvmx & 1)); uvmy = uvmy + ((uvmy < 0) ? (uvmy & 1) : -(uvmy & 1)); } - if (v->field_mode) { // interlaced field picture - if (!dir) { - if ((v->cur_field_type != v->ref_field_type[dir]) && v->cur_field_type) { - srcY = s->current_picture.f.data[0]; - srcU = s->current_picture.f.data[1]; - srcV = s->current_picture.f.data[2]; - } else { - srcY = s->last_picture.f.data[0]; - srcU = s->last_picture.f.data[1]; - srcV = s->last_picture.f.data[2]; - } + if (!dir) { + if (v->field_mode && (v->cur_field_type != v->ref_field_type[dir]) && v->cur_field_type) { + srcY = s->current_picture.f.data[0]; + srcU = s->current_picture.f.data[1]; + srcV = s->current_picture.f.data[2]; } else { - srcY = s->next_picture.f.data[0]; - srcU = s->next_picture.f.data[1]; - srcV = s->next_picture.f.data[2]; - } - } else { - if (!dir) { srcY = s->last_picture.f.data[0]; srcU = s->last_picture.f.data[1]; srcV = s->last_picture.f.data[2]; - } else { - srcY = s->next_picture.f.data[0]; - srcU = s->next_picture.f.data[1]; - srcV = s->next_picture.f.data[2]; } + } else { + srcY = s->next_picture.f.data[0]; + srcU = s->next_picture.f.data[1]; + srcV = s->next_picture.f.data[2]; } src_x = s->mb_x * 16 + (mx >> 2); @@ -566,11 +554,8 @@ static void vc1_mc_4mv_luma(VC1Context *v, int n, int dir) my = s->mv[dir][n][1]; if (!dir) { - if (v->field_mode) { - if ((v->cur_field_type != v->ref_field_type[dir]) && v->cur_field_type) - srcY = s->current_picture.f.data[0]; - else - srcY = s->last_picture.f.data[0]; + if (v->field_mode && (v->cur_field_type != v->ref_field_type[dir]) && v->cur_field_type) { + srcY = s->current_picture.f.data[0]; } else srcY = s->last_picture.f.data[0]; } else From 201412ffec044bb064734edb699e91152f7b53b2 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 24 Apr 2013 14:59:49 +0200 Subject: [PATCH 05/13] vc1dec: Factorize picture pointer selection in vc1_mc_4mv_chroma() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavcodec/vc1dec.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c index b13e91f924..f56f074a53 100644 --- a/libavcodec/vc1dec.c +++ b/libavcodec/vc1dec.c @@ -829,14 +829,9 @@ static void vc1_mc_4mv_chroma(VC1Context *v, int dir) } if (!dir) { - if (v->field_mode) { - if ((v->cur_field_type != chroma_ref_type) && v->cur_field_type) { - srcU = s->current_picture.f.data[1]; - srcV = s->current_picture.f.data[2]; - } else { - srcU = s->last_picture.f.data[1]; - srcV = s->last_picture.f.data[2]; - } + if (v->field_mode && (v->cur_field_type != chroma_ref_type) && v->cur_field_type) { + srcU = s->current_picture.f.data[1]; + srcV = s->current_picture.f.data[2]; } else { srcU = s->last_picture.f.data[1]; srcV = s->last_picture.f.data[2]; From ccb148e4780e63f71967272b746e02bf5a24da66 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 24 Apr 2013 15:01:08 +0200 Subject: [PATCH 06/13] vc1dec: Fix current ptr selection in vc1_mc_4mv_chroma() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No sample tried shows a difference. Signed-off-by: Martin Storsjö --- libavcodec/vc1dec.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c index f56f074a53..a3b6031752 100644 --- a/libavcodec/vc1dec.c +++ b/libavcodec/vc1dec.c @@ -380,7 +380,7 @@ static void vc1_mc_1mv(VC1Context *v, int dir) uvmy = uvmy + ((uvmy < 0) ? (uvmy & 1) : -(uvmy & 1)); } if (!dir) { - if (v->field_mode && (v->cur_field_type != v->ref_field_type[dir]) && v->cur_field_type) { + if (v->field_mode && (v->cur_field_type != v->ref_field_type[dir]) && v->second_field) { srcY = s->current_picture.f.data[0]; srcU = s->current_picture.f.data[1]; srcV = s->current_picture.f.data[2]; @@ -554,7 +554,7 @@ static void vc1_mc_4mv_luma(VC1Context *v, int n, int dir) my = s->mv[dir][n][1]; if (!dir) { - if (v->field_mode && (v->cur_field_type != v->ref_field_type[dir]) && v->cur_field_type) { + if (v->field_mode && (v->cur_field_type != v->ref_field_type[dir]) && v->second_field) { srcY = s->current_picture.f.data[0]; } else srcY = s->last_picture.f.data[0]; @@ -829,7 +829,7 @@ static void vc1_mc_4mv_chroma(VC1Context *v, int dir) } if (!dir) { - if (v->field_mode && (v->cur_field_type != chroma_ref_type) && v->cur_field_type) { + if (v->field_mode && (v->cur_field_type != chroma_ref_type) && v->second_field) { srcU = s->current_picture.f.data[1]; srcV = s->current_picture.f.data[2]; } else { From ec7d002e55590bf9e2c2745065ec3463364a5273 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Wed, 15 May 2013 11:51:03 +0300 Subject: [PATCH 07/13] vc1, mss2: Check for any negative return value from ff_vc1_parse_frame_header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is required if we return other error codes than explicitly -1, which so far has been the only other possible return value besides 0. Signed-off-by: Martin Storsjö --- libavcodec/mss2.c | 2 +- libavcodec/vc1dec.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libavcodec/mss2.c b/libavcodec/mss2.c index 44b6f1f62c..2562209324 100644 --- a/libavcodec/mss2.c +++ b/libavcodec/mss2.c @@ -388,7 +388,7 @@ static int decode_wmv9(AVCodecContext *avctx, const uint8_t *buf, int buf_size, s->loop_filter = avctx->skip_loop_filter < AVDISCARD_ALL; - if (ff_vc1_parse_frame_header(v, &s->gb) == -1) { + if (ff_vc1_parse_frame_header(v, &s->gb) < 0) { av_log(v->s.avctx, AV_LOG_ERROR, "header error\n"); return AVERROR_INVALIDDATA; } diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c index a3b6031752..86806b1d21 100644 --- a/libavcodec/vc1dec.c +++ b/libavcodec/vc1dec.c @@ -5464,11 +5464,11 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, // do parse frame header v->pic_header_flag = 0; if (v->profile < PROFILE_ADVANCED) { - if (ff_vc1_parse_frame_header(v, &s->gb) == -1) { + if (ff_vc1_parse_frame_header(v, &s->gb) < 0) { goto err; } } else { - if (ff_vc1_parse_frame_header_adv(v, &s->gb) == -1) { + if (ff_vc1_parse_frame_header_adv(v, &s->gb) < 0) { goto err; } } From 4162fc62b30d5b57910c17e46f2a9319a09cdae0 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 16 Nov 2012 00:48:15 +0100 Subject: [PATCH 08/13] vc1dec: Do not allow field_mode to change after the first header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes out of array accesses. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind Signed-off-by: Martin Storsjö --- libavcodec/vc1.c | 17 +++++++++++------ libavcodec/vc1.h | 1 + libavcodec/vc1dec.c | 2 ++ 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/libavcodec/vc1.c b/libavcodec/vc1.c index 25e3579d5c..86651fecd8 100644 --- a/libavcodec/vc1.c +++ b/libavcodec/vc1.c @@ -825,6 +825,7 @@ int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) int status; int mbmodetab, imvtab, icbptab, twomvbptab, fourmvbptab; /* useful only for debugging */ int scale, shift, i; /* for initializing LUT for intensity compensation */ + int field_mode, fcm; v->p_frame_skipped = 0; if (v->second_field) { @@ -836,19 +837,23 @@ int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) goto parse_common_info; } - v->field_mode = 0; + field_mode = 0; if (v->interlace) { - v->fcm = decode012(gb); - if (v->fcm) { - if (v->fcm == ILACE_FIELD) - v->field_mode = 1; + fcm = decode012(gb); + if (fcm) { + if (fcm == ILACE_FIELD) + field_mode = 1; if (!v->warn_interlaced++) av_log(v->s.avctx, AV_LOG_ERROR, "Interlaced frames/fields support is incomplete\n"); } } else { - v->fcm = PROGRESSIVE; + fcm = PROGRESSIVE; } + if (!v->first_pic_header_flag && v->field_mode != field_mode) + return AVERROR_INVALIDDATA; + v->field_mode = field_mode; + v->fcm = fcm; if (v->field_mode) { v->fptype = get_bits(gb, 3); diff --git a/libavcodec/vc1.h b/libavcodec/vc1.h index 6f24c0e4af..88980d49a6 100644 --- a/libavcodec/vc1.h +++ b/libavcodec/vc1.h @@ -372,6 +372,7 @@ typedef struct VC1Context{ int qs_last; ///< if qpel has been used in the previous (tr.) picture int bmvtype; int frfd, brfd; ///< reference frame distance (forward or backward) + int first_pic_header_flag; int pic_header_flag; /** Frame decoding info for sprite modes */ diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c index 86806b1d21..7345d5322b 100644 --- a/libavcodec/vc1dec.c +++ b/libavcodec/vc1dec.c @@ -5463,6 +5463,7 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, // do parse frame header v->pic_header_flag = 0; + v->first_pic_header_flag = 1; if (v->profile < PROFILE_ADVANCED) { if (ff_vc1_parse_frame_header(v, &s->gb) < 0) { goto err; @@ -5472,6 +5473,7 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, goto err; } } + v->first_pic_header_flag = 0; if ((avctx->codec_id == AV_CODEC_ID_WMV3IMAGE || avctx->codec_id == AV_CODEC_ID_VC1IMAGE) && s->pict_type != AV_PICTURE_TYPE_I) { From 3ca3709ad450dffb2bef73b9f65bf023d589b2fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Wed, 15 May 2013 10:32:49 +0300 Subject: [PATCH 09/13] vc1dec: Remove some now unused variables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavcodec/vc1dec.c | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c index 7345d5322b..ea08bdd59d 100644 --- a/libavcodec/vc1dec.c +++ b/libavcodec/vc1dec.c @@ -346,7 +346,6 @@ static void vc1_mc_1mv(VC1Context *v, int dir) H264ChromaContext *h264chroma = &v->h264chroma; uint8_t *srcY, *srcU, *srcV; int dxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y; - int off, off_uv; int v_edge_pos = s->v_edge_pos >> v->field_mode; if ((!v->field_mode || @@ -493,21 +492,19 @@ static void vc1_mc_1mv(VC1Context *v, int dir) srcY += s->mspel * (1 + s->linesize); } - off = 0; - off_uv = 0; if (s->mspel) { dxy = ((my & 3) << 2) | (mx & 3); - v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + off , srcY , s->linesize, v->rnd); - v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + off + 8, srcY + 8, s->linesize, v->rnd); + v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] , srcY , s->linesize, v->rnd); + v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + 8, srcY + 8, s->linesize, v->rnd); srcY += s->linesize * 8; - v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + off + 8 * s->linesize , srcY , s->linesize, v->rnd); - v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + off + 8 * s->linesize + 8, srcY + 8, s->linesize, v->rnd); + v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + 8 * s->linesize , srcY , s->linesize, v->rnd); + v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + 8 * s->linesize + 8, srcY + 8, s->linesize, v->rnd); } else { // hpel mc - always used for luma dxy = (my & 2) | ((mx & 2) >> 1); if (!v->rnd) - s->hdsp.put_pixels_tab[0][dxy](s->dest[0] + off, srcY, s->linesize, 16); + s->hdsp.put_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16); else - s->hdsp.put_no_rnd_pixels_tab[0][dxy](s->dest[0] + off, srcY, s->linesize, 16); + s->hdsp.put_no_rnd_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16); } if (s->flags & CODEC_FLAG_GRAY) return; @@ -515,11 +512,11 @@ static void vc1_mc_1mv(VC1Context *v, int dir) uvmx = (uvmx & 3) << 1; uvmy = (uvmy & 3) << 1; if (!v->rnd) { - h264chroma->put_h264_chroma_pixels_tab[0](s->dest[1] + off_uv, srcU, s->uvlinesize, 8, uvmx, uvmy); - h264chroma->put_h264_chroma_pixels_tab[0](s->dest[2] + off_uv, srcV, s->uvlinesize, 8, uvmx, uvmy); + h264chroma->put_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy); + h264chroma->put_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy); } else { - v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1] + off_uv, srcU, s->uvlinesize, 8, uvmx, uvmy); - v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2] + off_uv, srcV, s->uvlinesize, 8, uvmx, uvmy); + v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy); + v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy); } } @@ -765,7 +762,7 @@ static void vc1_mc_4mv_chroma(VC1Context *v, int dir) int k, tx = 0, ty = 0; int mvx[4], mvy[4], intra[4], mv_f[4]; int valid_count; - int chroma_ref_type = v->cur_field_type, off = 0; + int chroma_ref_type = v->cur_field_type; int v_edge_pos = s->v_edge_pos >> v->field_mode; if (!v->field_mode && !v->s.last_picture.f.data[0]) @@ -849,7 +846,6 @@ static void vc1_mc_4mv_chroma(VC1Context *v, int dir) srcU += s->current_picture_ptr->f.linesize[1]; srcV += s->current_picture_ptr->f.linesize[2]; } - off = 0; } if (v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP) @@ -903,11 +899,11 @@ static void vc1_mc_4mv_chroma(VC1Context *v, int dir) uvmx = (uvmx & 3) << 1; uvmy = (uvmy & 3) << 1; if (!v->rnd) { - h264chroma->put_h264_chroma_pixels_tab[0](s->dest[1] + off, srcU, s->uvlinesize, 8, uvmx, uvmy); - h264chroma->put_h264_chroma_pixels_tab[0](s->dest[2] + off, srcV, s->uvlinesize, 8, uvmx, uvmy); + h264chroma->put_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy); + h264chroma->put_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy); } else { - v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1] + off, srcU, s->uvlinesize, 8, uvmx, uvmy); - v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2] + off, srcV, s->uvlinesize, 8, uvmx, uvmy); + v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy); + v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy); } } From 0379fc1487d46445796903ab9cd4732cb7197bd2 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 24 Apr 2013 12:51:28 +0200 Subject: [PATCH 10/13] vc1: Move INIT_LUT() further up to allow using it in more places MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavcodec/vc1.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/libavcodec/vc1.c b/libavcodec/vc1.c index 86651fecd8..f94d52a428 100644 --- a/libavcodec/vc1.c +++ b/libavcodec/vc1.c @@ -570,6 +570,25 @@ int ff_vc1_decode_entry_point(AVCodecContext *avctx, VC1Context *v, GetBitContex return 0; } +/* fill lookup tables for intensity compensation */ +#define INIT_LUT(lumscale, lumshift, luty, lutuv) \ + if (!lumscale) { \ + scale = -64; \ + shift = (255 - lumshift * 2) << 6; \ + if (lumshift > 31) \ + shift += 128 << 6; \ + } else { \ + scale = lumscale + 32; \ + if (lumshift > 31) \ + shift = (lumshift - 64) << 6; \ + else \ + shift = lumshift << 6; \ + } \ + for (i = 0; i < 256; i++) { \ + luty[i] = av_clip_uint8((scale * i + shift + 32) >> 6); \ + lutuv[i] = av_clip_uint8((scale * (i - 128) + 128*64 + 32) >> 6); \ + } + int ff_vc1_parse_frame_header(VC1Context *v, GetBitContext* gb) { int pqindex, lowquant, status; @@ -800,25 +819,6 @@ int ff_vc1_parse_frame_header(VC1Context *v, GetBitContext* gb) return 0; } -/* fill lookup tables for intensity compensation */ -#define INIT_LUT(lumscale, lumshift, luty, lutuv) \ - if (!lumscale) { \ - scale = -64; \ - shift = (255 - lumshift * 2) << 6; \ - if (lumshift > 31) \ - shift += 128 << 6; \ - } else { \ - scale = lumscale + 32; \ - if (lumshift > 31) \ - shift = (lumshift - 64) << 6; \ - else \ - shift = lumshift << 6; \ - } \ - for (i = 0; i < 256; i++) { \ - luty[i] = av_clip_uint8((scale * i + shift + 32) >> 6); \ - lutuv[i] = av_clip_uint8((scale * (i - 128) + 128*64 + 32) >> 6); \ - } - int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) { int pqindex, lowquant; From 37f2ac36a9099b3489500ba79bb3831c8698feea Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 24 Apr 2013 12:51:28 +0200 Subject: [PATCH 11/13] vc1: Simplify code by using INIT_LUT() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavcodec/vc1.c | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/libavcodec/vc1.c b/libavcodec/vc1.c index f94d52a428..b490165644 100644 --- a/libavcodec/vc1.c +++ b/libavcodec/vc1.c @@ -693,22 +693,7 @@ int ff_vc1_parse_frame_header(VC1Context *v, GetBitContext* gb) v->lumshift = get_bits(gb, 6); v->use_ic = 1; /* fill lookup tables for intensity compensation */ - if (!v->lumscale) { - scale = -64; - shift = (255 - v->lumshift * 2) << 6; - if (v->lumshift > 31) - shift += 128 << 6; - } else { - scale = v->lumscale + 32; - if (v->lumshift > 31) - shift = (v->lumshift - 64) << 6; - else - shift = v->lumshift << 6; - } - for (i = 0; i < 256; i++) { - v->luty[i] = av_clip_uint8((scale * i + shift + 32) >> 6); - v->lutuv[i] = av_clip_uint8((scale * (i - 128) + 128*64 + 32) >> 6); - } + INIT_LUT(v->lumscale, v->lumshift, v->luty, v->lutuv); } v->qs_last = v->s.quarter_sample; if (v->mv_mode == MV_PMODE_1MV_HPEL || v->mv_mode == MV_PMODE_1MV_HPEL_BILIN) From 6ce2c3106d78994d2b5d23ea5d23a393f8296657 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 24 Apr 2013 15:33:11 +0200 Subject: [PATCH 12/13] vc1: Make INIT_LUT() self contained MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the local variables it uses into the macro, enclosing them in a do {} while (0) scope. Signed-off-by: Martin Storsjö --- libavcodec/vc1.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavcodec/vc1.c b/libavcodec/vc1.c index b490165644..df8f30afbf 100644 --- a/libavcodec/vc1.c +++ b/libavcodec/vc1.c @@ -571,7 +571,8 @@ int ff_vc1_decode_entry_point(AVCodecContext *avctx, VC1Context *v, GetBitContex } /* fill lookup tables for intensity compensation */ -#define INIT_LUT(lumscale, lumshift, luty, lutuv) \ +#define INIT_LUT(lumscale, lumshift, luty, lutuv) do { \ + int scale, shift, i; \ if (!lumscale) { \ scale = -64; \ shift = (255 - lumshift * 2) << 6; \ @@ -587,7 +588,8 @@ int ff_vc1_decode_entry_point(AVCodecContext *avctx, VC1Context *v, GetBitContex for (i = 0; i < 256; i++) { \ luty[i] = av_clip_uint8((scale * i + shift + 32) >> 6); \ lutuv[i] = av_clip_uint8((scale * (i - 128) + 128*64 + 32) >> 6); \ - } + } \ + } while(0) int ff_vc1_parse_frame_header(VC1Context *v, GetBitContext* gb) { @@ -687,7 +689,6 @@ int ff_vc1_parse_frame_header(VC1Context *v, GetBitContext* gb) lowquant = (v->pq > 12) ? 0 : 1; v->mv_mode = ff_vc1_mv_pmode_table[lowquant][get_unary(gb, 1, 4)]; if (v->mv_mode == MV_PMODE_INTENSITY_COMP) { - int scale, shift, i; v->mv_mode2 = ff_vc1_mv_pmode_table2[lowquant][get_unary(gb, 1, 3)]; v->lumscale = get_bits(gb, 6); v->lumshift = get_bits(gb, 6); @@ -809,7 +810,6 @@ int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) int pqindex, lowquant; int status; int mbmodetab, imvtab, icbptab, twomvbptab, fourmvbptab; /* useful only for debugging */ - int scale, shift, i; /* for initializing LUT for intensity compensation */ int field_mode, fcm; v->p_frame_skipped = 0; From 225a5f91cc83f684e948d3c23ce5e5de0c041ecb Mon Sep 17 00:00:00 2001 From: Alex Smith Date: Tue, 14 May 2013 10:05:52 -0400 Subject: [PATCH 13/13] configure: Use linker hardening flags on mingw MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes it consistent with the msvc builds which automatically set the DEP and ASLR flags by default. There really is no good reason why they shouldn't be set. The fact that binutils does not set them on by default boggles the mind. Signed-off-by: Martin Storsjö --- configure | 2 ++ 1 file changed, 2 insertions(+) diff --git a/configure b/configure index c84050c662..7bcaac3fcc 100755 --- a/configure +++ b/configure @@ -3029,6 +3029,8 @@ case $target_os in elif enabled arm; then LIBTARGET=arm-wince fi + check_ldflags -Wl,--nxcompat + check_ldflags -Wl,--dynamicbase shlibdir_default="$bindir_default" SLIBPREF="" SLIBSUF=".dll"