From 2886f6759f31b192935761544c25d3677d66d24e Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Mon, 10 Oct 2011 13:28:18 +0200 Subject: [PATCH 01/34] avidec: simplify size parameter in memset() --- libavformat/avidec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/avidec.c b/libavformat/avidec.c index 8c0ef13b14..81f72d336f 100644 --- a/libavformat/avidec.c +++ b/libavformat/avidec.c @@ -848,7 +848,7 @@ static int avi_sync(AVFormatContext *s, int exit_early) int64_t i, sync; start_sync: - memset(d, -1, sizeof(int)*8); + memset(d, -1, sizeof(d)); for(i=sync=avio_tell(pb); !pb->eof_reached; i++) { int j; From c2ed91de84b3183a6cf2fe94e12236dd8bf45dc7 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 10 Oct 2011 10:31:31 +0200 Subject: [PATCH 02/34] configure: Add -Wstrict-prototypes to CFLAGS if available. --- configure | 1 + 1 file changed, 1 insertion(+) diff --git a/configure b/configure index 22735e788e..f5a285e6d1 100755 --- a/configure +++ b/configure @@ -2992,6 +2992,7 @@ check_cflags -Wwrite-strings check_cflags -Wtype-limits check_cflags -Wundef check_cflags -Wmissing-prototypes +check_cflags -Wstrict-prototypes enabled extra_warnings && check_cflags -Winline # add some linker flags From 53efb758c045900f512c947074900c0dbc988685 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 10 Oct 2011 13:51:41 +0200 Subject: [PATCH 03/34] vaapi: Fix VC-1 decoding (reconstruct bitstream TTFRM correctly). Signed-off-by: Diego Biurrun --- libavcodec/vaapi_vc1.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/libavcodec/vaapi_vc1.c b/libavcodec/vaapi_vc1.c index 19865dc0e8..452b97d25a 100644 --- a/libavcodec/vaapi_vc1.c +++ b/libavcodec/vaapi_vc1.c @@ -116,6 +116,18 @@ static inline VAMvModeVC1 vc1_get_MVMODE2(VC1Context *v) return 0; } +/** Reconstruct bitstream TTFRM (7.1.1.41, Table-53) */ +static inline int vc1_get_TTFRM(VC1Context *v) +{ + switch (v->ttfrm) { + case TT_8X8: return 0; + case TT_8X4: return 1; + case TT_4X8: return 2; + case TT_4X4: return 3; + } + return 0; +} + /** Pack Libav bitplanes into a VABitPlaneBuffer element */ static inline void vc1_pack_bitplanes(uint8_t *bitplane, int n, const uint8_t *ff_bp[3], int x, int y, int stride) { @@ -239,7 +251,7 @@ static int vaapi_vc1_start_frame(AVCodecContext *avctx, av_unused const uint8_t pic_param->transform_fields.value = 0; /* reset all bits */ pic_param->transform_fields.bits.variable_sized_transform_flag = v->vstransform; pic_param->transform_fields.bits.mb_level_transform_type_flag = v->ttmbf; - pic_param->transform_fields.bits.frame_level_transform_type = v->ttfrm; + pic_param->transform_fields.bits.frame_level_transform_type = vc1_get_TTFRM(v); pic_param->transform_fields.bits.transform_ac_codingset_idx1 = v->c_ac_table_index; pic_param->transform_fields.bits.transform_ac_codingset_idx2 = v->y_ac_table_index; pic_param->transform_fields.bits.intra_transform_dc_table = v->s.dc_table_index; From d5b015e42dc9c1a0f9bcdc44283e6d4cb93e30d6 Mon Sep 17 00:00:00 2001 From: Mashiat Sarker Shakkhar Date: Fri, 7 Oct 2011 00:00:24 +0500 Subject: [PATCH 04/34] vc1dec: interlaced stream decoding support 1/3 Signed-off-by: Anton Khirnov --- libavcodec/vc1.h | 61 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 57 insertions(+), 4 deletions(-) diff --git a/libavcodec/vc1.h b/libavcodec/vc1.h index e1365ab2c2..462252bc66 100644 --- a/libavcodec/vc1.h +++ b/libavcodec/vc1.h @@ -105,12 +105,25 @@ enum MVModes { }; //@} +/** MBMODE for interlaced frame P-picture */ +//@{ +enum MBModesIntfr { + MV_PMODE_INTFR_1MV, + MV_PMODE_INTFR_2MV_FIELD, + MV_PMODE_INTFR_2MV, + MV_PMODE_INTFR_4MV_FIELD, + MV_PMODE_INTFR_4MV, + MV_PMODE_INTFR_INTRA, +}; +//@} + /** @name MV types for B frames */ //@{ enum BMVTypes { BMV_TYPE_BACKWARD, BMV_TYPE_FORWARD, - BMV_TYPE_INTERPOLATED + BMV_TYPE_INTERPOLATED, + BMV_TYPE_DIRECT }; //@} @@ -260,16 +273,18 @@ typedef struct VC1Context{ * -# 2 -> [-512, 511.f] x [-128, 127.f] * -# 3 -> [-1024, 1023.f] x [-256, 255.f] */ - uint8_t mvrange; + uint8_t mvrange; ///< Extended MV range flag uint8_t pquantizer; ///< Uniform (over sequence) quantizer in use VLC *cbpcy_vlc; ///< CBPCY VLC table - int tt_index; ///< Index for Transform Type tables + int tt_index; ///< Index for Transform Type tables (to decode TTMB) uint8_t* mv_type_mb_plane; ///< bitplane for mv_type == (4MV) uint8_t* direct_mb_plane; ///< bitplane for "direct" MBs + uint8_t* forward_mb_plane; ///< bitplane for "forward" MBs int mv_type_is_raw; ///< mv type mb plane is not coded int dmb_is_raw; ///< direct mb plane is raw + int fmb_is_raw; ///< forward mb plane is raw int skip_is_raw; ///< skip mb plane is not coded - uint8_t luty[256], lutuv[256]; // lookup tables used for intensity compensation + uint8_t luty[256], lutuv[256];///< lookup tables used for intensity compensation int use_ic; ///< use intensity compensation in B-frames int rnd; ///< rounding control @@ -307,6 +322,44 @@ typedef struct VC1Context{ uint8_t range_mapuv; //@} + /** Frame decoding info for interlaced picture */ + uint8_t dmvrange; ///< Extended differential MV range flag + int fourmvswitch; + int intcomp; + uint8_t lumscale2; ///< for interlaced field P picture + uint8_t lumshift2; + uint8_t luty2[256], lutuv2[256]; // lookup tables used for intensity compensation + VLC* mbmode_vlc; + VLC* imv_vlc; + VLC* twomvbp_vlc; + VLC* fourmvbp_vlc; + uint8_t twomvbp; + uint8_t fourmvbp; + uint8_t* fieldtx_plane; + int fieldtx_is_raw; + int8_t zzi_8x8[64]; + uint8_t *blk_mv_type_base, *blk_mv_type; ///< 0: frame MV, 1: field MV (interlaced frame) + uint8_t *mv_f_base, *mv_f[2]; ///< 0: MV obtained from same field, 1: opposite field + uint8_t *mv_f_last_base, *mv_f_last[2]; + uint8_t *mv_f_next_base, *mv_f_next[2]; + int field_mode; ///< 1 for interlaced field pictures + int fptype; + int second_field; + int refdist; ///< distance of the current picture from reference + int numref; ///< number of past field pictures used as reference + // 0 corresponds to 1 and 1 corresponds to 2 references + int reffield; ///< if numref = 0 (1 reference) then reffield decides which + // field to use among the two fields from previous frame + int intcompfield; ///< which of the two fields to be intensity compensated + // 0: both fields, 1: bottom field, 2: top field + int cur_field_type; ///< 0: top, 1: bottom + int ref_field_type[2]; ///< forward and backward reference field type (top or bottom) + int blocks_off, mb_off; + 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 pic_header_flag; + /** Frame decoding info for sprite modes */ //@{ int new_sprite; From f0c02e1cbc71043ffe8c1fa44f12330a63f9df10 Mon Sep 17 00:00:00 2001 From: Mashiat Sarker Shakkhar Date: Fri, 7 Oct 2011 00:00:25 +0500 Subject: [PATCH 05/34] vc1dec: interlaced stream decoding support 2/3 Cosmetics: reformat some data tables in vc1data.c Signed-off-by: Anton Khirnov --- libavcodec/vc1data.c | 462 +++++++++++++++++++++++++++++++++++++++++++ libavcodec/vc1data.h | 55 ++++++ 2 files changed, 517 insertions(+) diff --git a/libavcodec/vc1data.c b/libavcodec/vc1data.c index 43edf746b7..45346a1f1c 100644 --- a/libavcodec/vc1data.c +++ b/libavcodec/vc1data.c @@ -1,5 +1,6 @@ /* * VC-1 and WMV3 decoder + * copyright (c) 2011 Mashiat Sarker Shakkhar * copyright (c) 2006 Konstantin Shishkov * (c) 2005 anonymous, Alex Beregszaszi, Michael Niedermayer * @@ -48,6 +49,40 @@ const uint8_t ff_vc1_mv_pmode_table2[2][4] = { { MV_PMODE_1MV, MV_PMODE_MIXED_MV, MV_PMODE_1MV_HPEL, MV_PMODE_1MV_HPEL_BILIN } }; +/* MBMODE table for interlaced frame P-picture */ +const uint8_t ff_vc1_mbmode_intfrp[2][15][4] = { + { /* 1: 4-MV, 0: non-4-MV */ + /* Type, FIELDTX, 1-MV Differential present, Residuals (CBP) present */ + /* Table 164 - Table 167 */ + { MV_PMODE_INTFR_1MV , 0, 1, 1}, + { MV_PMODE_INTFR_1MV , 1, 1, 1}, + { MV_PMODE_INTFR_1MV , 0, 1, 0}, + { MV_PMODE_INTFR_1MV , 0, 0, 1}, + { MV_PMODE_INTFR_1MV , 1, 0, 1}, + { MV_PMODE_INTFR_2MV_FIELD , 0, 0, 1}, + { MV_PMODE_INTFR_2MV_FIELD , 1, 0, 1}, + { MV_PMODE_INTFR_2MV_FIELD , 0, 0, 0}, + { MV_PMODE_INTFR_INTRA , 0, 0, 0} }, + { + /* Table 160 - Table 163 */ + { MV_PMODE_INTFR_1MV , 0, 1, 1 }, + { MV_PMODE_INTFR_1MV , 1, 1, 1 }, + { MV_PMODE_INTFR_1MV , 0, 1, 0 }, + { MV_PMODE_INTFR_1MV , 0, 0, 1 }, + { MV_PMODE_INTFR_1MV , 1, 0, 1 }, + { MV_PMODE_INTFR_2MV_FIELD , 0, 0, 1 }, + { MV_PMODE_INTFR_2MV_FIELD , 1, 0, 1 }, + { MV_PMODE_INTFR_2MV_FIELD , 0, 0, 0 }, + { MV_PMODE_INTFR_4MV , 0, 0, 1 }, + { MV_PMODE_INTFR_4MV , 1, 0, 1 }, + { MV_PMODE_INTFR_4MV , 0, 0, 0 }, + { MV_PMODE_INTFR_4MV_FIELD , 0, 0, 1 }, + { MV_PMODE_INTFR_4MV_FIELD , 1, 0, 1 }, + { MV_PMODE_INTFR_4MV_FIELD , 0, 0, 0 }, + { MV_PMODE_INTFR_INTRA , 0, 0, 0 } + } +}; + const int ff_vc1_fps_nr[5] = { 24, 25, 30, 50, 60 }, ff_vc1_fps_dr[2] = { 1000, 1001 }; const uint8_t ff_vc1_pquant_table[3][32] = { @@ -84,14 +119,33 @@ VLC ff_vc1_ttmb_vlc[3]; VLC ff_vc1_mv_diff_vlc[4]; #define VC1_CBPCY_P_VLC_BITS 9 //14 VLC ff_vc1_cbpcy_p_vlc[4]; +#define VC1_ICBPCY_VLC_BITS 9 +VLC ff_vc1_icbpcy_vlc[8]; #define VC1_4MV_BLOCK_PATTERN_VLC_BITS 6 VLC ff_vc1_4mv_block_pattern_vlc[4]; +#define VC1_2MV_BLOCK_PATTERN_VLC_BITS 3 +VLC ff_vc1_2mv_block_pattern_vlc[4]; #define VC1_TTBLK_VLC_BITS 5 VLC ff_vc1_ttblk_vlc[3]; #define VC1_SUBBLKPAT_VLC_BITS 6 VLC ff_vc1_subblkpat_vlc[3]; +#define VC1_INTFR_4MV_MBMODE_VLC_BITS 9 +VLC ff_vc1_intfr_4mv_mbmode_vlc[4]; +#define VC1_INTFR_NON4MV_MBMODE_VLC_BITS 6 +VLC ff_vc1_intfr_non4mv_mbmode_vlc[4]; +#define VC1_IF_MMV_MBMODE_VLC_BITS 5 +VLC ff_vc1_if_mmv_mbmode_vlc[8]; +#define VC1_IF_1MV_MBMODE_VLC_BITS 5 +VLC ff_vc1_if_1mv_mbmode_vlc[8]; +#define VC1_1REF_MVDATA_VLC_BITS 9 +VLC ff_vc1_1ref_mvdata_vlc[4]; +#define VC1_2REF_MVDATA_VLC_BITS 9 +VLC ff_vc1_2ref_mvdata_vlc[8]; VLC ff_vc1_ac_coeff_table[8]; + +#define VC1_IF_MBMODE_VLC_BITS 5 // as a placeholder for VC1_IF_MMV_MBMODE_VLC_BITS + // or VC1_IF_1MV_MBMODE_VLC_BITS since they are the same //@} @@ -202,6 +256,273 @@ const uint8_t ff_vc1_4mv_block_pattern_bits[4][16] = { { 2, 4, 4, 4, 4, 4, 5, 5, 4, 5, 4, 5, 4, 5, 5, 4} }; +/* 2MV Block pattern VLC tables */ +const uint8_t ff_vc1_2mv_block_pattern_codes[4][4] = { + { 2, 1, 0, 3}, { 1, 0, 2, 3}, { 2, 0, 3, 1}, { 1, 3, 2, 0} +}; + +const uint8_t ff_vc1_2mv_block_pattern_bits[4][4] = { + { 2, 2, 2, 2}, { 1, 2, 3, 3}, { 3, 2, 3, 1}, { 1, 3, 3, 2} +}; + +/* Interlaced frame picture 4MV MBMODE VLC tables (p. 246, p. 360) */ +const uint16_t ff_vc1_intfr_4mv_mbmode_codes[4][15] = { + { 22, 17, 0, 47, 32, 10, 1, 3, 67, 133, 132, 92, 19, 93, 18}, + { 3, 45, 0, 7, 23, 6, 1, 2, 10, 39, 44, 8, 18, 77, 76}, + { 15, 6, 28, 9, 41, 6, 2, 15, 14, 8, 40, 29, 0, 21, 11}, + { 7, 198, 1, 2, 193, 13, 25, 0, 97, 1599, 98, 398, 798, 192, 1598} +}; + +const uint8_t ff_vc1_intfr_4mv_mbmode_bits[4][15] = { + { 5, 5, 2, 6, 6, 4, 2, 2, 7, 8, 8, 7, 5, 7, 5}, + { 3, 6, 3, 3, 5, 3, 3, 3, 4, 6, 6, 4, 5, 7, 7}, + { 4, 3, 5, 5, 7, 4, 2, 5, 5, 5, 7, 5, 2, 6, 5}, + { 4, 9, 1, 3, 9, 5, 6, 2, 8, 12, 8, 10, 11, 9, 12} +}; + +/* Interlaced frame picture NON-4MV MBMODE VLC tables (p. 363) */ +const uint8_t ff_vc1_intfr_non4mv_mbmode_codes[4][9] = { + { 9, 22, 0, 17, 16, 10, 1, 3, 23}, + { 7, 0, 5, 2, 1, 1, 6, 3, 4}, + { 1, 0, 10, 23, 44, 8, 3, 9, 45}, + { 7, 97, 1, 2, 49, 13, 25, 0, 96} +}; + +const uint8_t ff_vc1_intfr_non4mv_mbmode_bits[4][9] = { + { 4, 5, 2, 5, 5, 4, 2, 2, 5}, + { 3, 4, 6, 2, 3, 2, 3, 5, 6}, + { 2, 2, 4, 5, 6, 4, 2, 4, 6}, + { 4, 8, 1, 3, 7, 5, 6, 2, 8} +}; + +/* Interlaced field picture MBMODE VLC tables (p. 356 - 11.4.1, 11.4.2) */ +/* mixed-MV */ +const uint8_t ff_vc1_if_mmv_mbmode_codes[8][8] = { + { 16, 17, 3, 3, 0, 5, 9, 2 }, + { 8, 9, 3, 6, 7, 0, 5, 2 }, + { 16, 17, 5, 3, 0, 3, 9, 2 }, + { 56, 57, 15, 4, 5, 6, 29, 0 }, + { 52, 53, 27, 14, 15, 2, 12, 0 }, + { 56, 57, 29, 5, 6, 0, 15, 4 }, + { 16, 17, 6, 7, 0, 1, 9, 5 }, + { 56, 57, 0, 5, 6, 29, 4, 15 } +}; +const uint8_t ff_vc1_if_mmv_mbmode_bits[8][8] = { + { 6, 6, 2, 3, 2, 4, 5, 2 }, + { 5, 5, 3, 3, 3, 2, 4, 2 }, + { 6, 6, 4, 3, 2, 2, 5, 2 }, + { 6, 6, 4, 3, 3, 3, 5, 1 }, + { 6, 6, 5, 4, 4, 2, 4, 1 }, + { 6, 6, 5, 3, 3, 1, 4, 3 }, + { 5, 5, 3, 3, 2, 2, 4, 3 }, + { 6, 6, 1, 3, 3, 5, 3, 4 } +}; +/* 1MV */ +const uint8_t ff_vc1_if_1mv_mbmode_codes[8][6] = { + { 0, 1, 1, 1, 1, 1 }, + { 0, 1, 1, 1, 1, 1 }, + { 16, 17, 3, 0, 9, 5 }, + { 20, 21, 3, 11, 0, 4 }, + { 4, 5, 2, 3, 3, 0 }, + { 4, 5, 3, 2, 0, 3 }, + { 0, 1, 1, 1, 1, 1 }, + { 16, 17, 9, 5, 3, 0 } +}; +const uint8_t ff_vc1_if_1mv_mbmode_bits[8][6] = { + { 5, 5, 1, 3, 2, 4 }, + { 5, 5, 1, 2, 3, 4 }, + { 5, 5, 2, 1, 4, 3 }, + { 5, 5, 2, 4, 1, 3 }, + { 4, 4, 2, 3, 2, 2 }, + { 4, 4, 3, 2, 2, 2 }, + { 5, 5, 3, 4, 1, 2 }, + { 5, 5, 4, 3, 2, 1 } +}; + +/* Interlaced frame/field picture MVDATA VLC tables */ + +/* 1-reference tables */ +const uint32_t ff_vc1_1ref_mvdata_codes[4][72] = { /* uint32_t may be too big */ + {5, 12, 30, 18, 12, 52, 117, 112, 0, 8, 27, 8, 29, 124, 214, 478, 431, 5, 27, 38, 30, 18, 118, 77, + 502, 500, 57, 127, 39, 106, 113, 53, 113, 104, 476, 39, 115, 255, 232, 233, 126, 505, 501, 509, 62, 458, 1017, 76, + 105, 506, 479, 503, 112, 477, 3661, 1831, 914, 456, 459, 1016, 430, 504, 507, 58574, 58575, 29280, 29281, 29282, 29283, 29284, 29285, 29286}, + {7, 1, 7, 22, 1, 69, 24, 694, 6, 4, 23, 16, 41, 44, 346, 102, 414, 9, 40, 23, 0, 42, 4, 91, + 181, 206, 6, 68, 15, 70, 14, 172, 50, 55, 4587, 10, 26, 287, 22, 20, 43, 360, 85, 9173, 87, 47, 54, 46, + 361, 84, 1147, 415, 11133, 142, 2782, 1145, 1390, 2292, 5567, 1144, 9172, 44529, 22265, 712462, 712463, 356224, 356225, 356226, 356227, 356228, 356229, 356230}, + {2, 6, 7, 13, 7, 48, 255, 496, 2, 0, 5, 25, 30, 7, 99, 253, 35, 14, 27, 26, 6, 9, 24, 197, + 51, 497, 2, 1019, 499, 34, 508, 66, 1571, 131, 1568, 125, 64, 67, 996, 997, 401, 4073, 261, 520, 252, 1572, 1570, 400, + 1574, 2037, 3147, 8144, 4173, 101, 3138, 201, 1575, 3139, 3146, 4174, 8145, 4175, 1042, 66766, 66767, 33376, 33377, 33378, 33379, 33380, 33381, 33382}, + {13, 1, 4, 0, 23, 5, 127, 77, 3, 17, 62, 59, 23, 103, 74, 195, 242, 10, 44, 50, 61, 21, 40, 147, + 204, 150, 3, 117, 32, 45, 33, 41, 144, 464, 507, 28, 76, 96, 9, 8, 45, 159, 506, 317, 49, 252, 88, 146, + 240, 241, 205, 389, 357, 78, 145, 233, 388, 465, 486, 151, 487, 179, 316, 5710, 5711, 2848, 2849, 2850, 2851, 2852, 2853, 2854} +}; + +const uint8_t ff_vc1_1ref_mvdata_bits[4][72] = { + {3, 4, 5, 5, 5, 6, 7, 7, 2, 4, 5, 5, 6, 7, 8, 9, 9, 4, 6, 6, 6, 6, 7, 8, + 9, 9, 6, 8, 7, 7, 7, 7, 8, 8, 9, 6, 8, 8, 8, 8, 8, 9, 9, 9, 7, 10, 10, 8, + 8, 9, 9, 9, 8, 9, 13, 12, 11, 10, 10, 10, 9, 9, 9, 17, 17, 16, 16, 16, 16, 16, 16, 16}, + {3, 3, 4, 5, 5, 7, 8, 10, 3, 4, 5, 5, 6, 7, 9, 10, 12, 4, 6, 6, 5, 6, 6, 8, + 9, 11, 4, 7, 7, 7, 7, 8, 9, 9, 13, 5, 8, 9, 8, 8, 9, 10, 10, 14, 7, 9, 9, 9, + 10, 10, 11, 12, 14, 8, 12, 11, 11, 12, 13, 11, 14, 16, 15, 20, 20, 19, 19, 19, 19, 19, 19, 19}, + {3, 4, 4, 4, 5, 6, 8, 9, 2, 4, 5, 5, 5, 6, 7, 8, 8, 4, 7, 7, 6, 6, 7, 8, + 8, 9, 5, 10, 9, 8, 9, 9, 11, 10, 11, 7, 9, 9, 10, 10, 11, 12, 11, 12, 8, 11, 11, 11, + 11, 11, 12, 13, 15, 9, 12, 10, 11, 12, 12, 15, 13, 15, 13, 19, 19, 18, 18, 18, 18, 18, 18, 18}, + {4, 4, 4, 4, 5, 5, 7, 7, 3, 5, 6, 6, 6, 7, 7, 8, 8, 4, 6, 6, 6, 6, 7, 8, + 8, 8, 4, 7, 6, 6, 6, 7, 8, 9, 9, 5, 7, 7, 6, 6, 7, 8, 9, 9, 6, 8, 8, 8, + 8, 8, 8, 9, 10, 7, 8, 8, 9, 9, 9, 8, 9, 9, 9, 14, 14, 13, 13, 13, 13, 13, 13, 13} +}; + +/* 2-reference tables */ +const uint32_t ff_vc1_2ref_mvdata_codes[8][126] = { /* table 132 - table 139 */ + {12, 28, 11, 0, 14, 42, 80, 872, 2, 26, 4, 58, 29, 108, + 239, 444, 351, 15, 3, 28, 13, 11, 62, 167, 326, 409, 6, 31, + 4, 60, 7, 446, 139, 44, 1971, 5, 219, 86, 236, 82, 445, 120, + 207, 1395, 9, 35, 237, 24, 6, 68, 245, 121, 1746, 110, 43, 349, + 23, 895, 324, 206, 40, 171, 16, 437, 247, 166, 123, 40, 493, 489, + 1789, 4, 245, 41, 650, 651, 655, 3577, 821, 7813, 238, 701, 43, 984, + 977, 408, 489, 1309, 180, 63, 1109, 555, 553, 1105, 1400, 1970, 1392, 341, + 50, 976, 84, 1747, 1393, 1108, 820, 7153, 183, 41, 7812, 364, 411, 7152, + 1401, 3907, 181, 2209, 42, 365, 2208, 1952, 977, 2789, 340, 2788, 2617, 2616}, + {3, 9, 22, 16, 215, 821, 1396, 1365, 0, 29, 9, 23, 44, 173, + 884, 1715, 1399, 15, 24, 10, 46, 34, 380, 3707, 7049, 5592, 8, 52, + 109, 35, 450, 886, 723, 7242, 13066, 20, 106, 114, 108, 227, 411, 1855, + 7408, 2881, 50, 230, 224, 207, 171, 412, 683, 3627, 5593, 111, 451, 175, + 191, 172, 381, 1763, 3625, 6532, 84, 181, 378, 429, 409, 376, 856, 722, + 7243, 91, 680, 817, 904, 907, 880, 1811, 3267, 7409, 441, 1519, 1848, 754, + 827, 697, 1771, 1392, 3620, 925, 1442, 1443, 3709, 1518, 1849, 1364, 2725, 2724, + 887, 7413, 3022, 3705, 1632, 1652, 1770, 3708, 3429, 758, 5594, 7048, 1441, 7412, + 1510, 3624, 1397, 3428, 820, 13067, 5595, 2880, 3023, 3525, 3626, 1653, 1393, 1363}, + {4, 2, 16, 3, 23, 69, 62, 126, 3, 2, 40, 30, 21, 71, + 2, 333, 96, 11, 38, 36, 20, 50, 111, 195, 1329, 1765, 21, 63, + 45, 1, 318, 221, 246, 773, 817, 14, 3, 52, 51, 26, 330, 197, + 244, 1764, 1, 60, 125, 141, 157, 49, 110, 662, 205, 37, 329, 50, + 137, 54, 136, 111, 3, 797, 14, 426, 638, 97, 334, 335, 103, 255, + 387, 54, 855, 245, 198, 194, 665, 281, 561, 848, 44, 399, 1328, 663, + 4, 440, 192, 634, 785, 156, 1569, 409, 796, 247, 995, 854, 393, 5, + 107, 2242, 816, 1279, 1264, 849, 1266, 498, 883, 0, 3137, 2243, 2540, 994, + 772, 1271, 1265, 496, 328, 3136, 2541, 2240, 2241, 1267, 1278, 254, 499, 425}, + {0, 4, 47, 82, 16, 173, 1291, 400, 3, 22, 7, 13, 187, 371, + 201, 1295, 5932, 3, 17, 5, 67, 35, 75, 814, 11867, 1154, 9, 42, + 20, 42, 264, 1482, 1626, 8502, 8498, 11, 19, 65, 184, 372, 256, 5338, + 16462, 5175, 43, 133, 167, 160, 332, 666, 812, 8499, 5162, 81, 644, 172, + 258, 69, 68, 2075, 1630, 3255, 24, 1292, 530, 740, 515, 148, 290, 2074, + 1621, 51, 698, 582, 578, 2670, 1036, 2056, 8500, 16463, 373, 1029, 583, 298, + 2580, 699, 401, 2127, 5176, 175, 2967, 1155, 5179, 811, 579, 5163, 2392, 10687, + 73, 2668, 5339, 1197, 5342, 2126, 5172, 599, 11866, 519, 5173, 5177, 3254, 5178, + 404, 1620, 8501, 21372, 348, 576, 4114, 21373, 2393, 4248, 5174, 1631, 8230, 8503}, + {5, 25, 22, 17, 62, 94, 239, 226, 0, 57, 43, 38, 40, 18, + 194, 237, 285, 13, 49, 42, 37, 32, 92, 493, 589, 1904, 6, 122, + 96, 79, 72, 57, 390, 531, 3782, 15, 38, 95, 117, 112, 39, 475, + 966, 1935, 63, 166, 240, 58, 82, 78, 227, 473, 783, 16, 477, 167, + 247, 34, 146, 964, 751, 1890, 121, 143, 474, 135, 232, 186, 374, 238, + 944, 133, 281, 782, 264, 466, 268, 1907, 1060, 1076, 113, 1501, 449, 935, + 295, 141, 539, 1970, 479, 984, 1892, 3812, 947, 1869, 472, 1500, 2122, 1177, + 965, 7566, 1893, 1077, 1905, 450, 280, 956, 897, 903, 31539, 4247, 4246, 7885, + 3737, 3868, 3869, 3813, 284, 31538, 15768, 7567, 3736, 3943, 957, 896, 1176, 902}, + {13, 16, 46, 57, 13, 116, 237, 182, 1, 2, 0, 48, 41, 112, + 243, 140, 358, 9, 51, 120, 6, 196, 11, 355, 204, 1470, 31, 47, + 100, 24, 198, 10, 354, 704, 3827, 7, 15, 227, 202, 178, 399, 942, + 1887, 3153, 21, 71, 238, 226, 234, 9, 362, 707, 1437, 61, 8, 473, + 50, 14, 366, 812, 1627, 6507, 2, 15, 472, 141, 180, 484, 103, 791, + 1940, 34, 958, 789, 52, 55, 734, 108, 3838, 1644, 40, 971, 940, 53, + 363, 957, 705, 1580, 7678, 14, 1438, 1471, 218, 1577, 1412, 3767, 2826, 1645, + 12, 1918, 1436, 1912, 1886, 1882, 1581, 823, 820, 407, 7767, 7652, 6506, 7766, + 3152, 2879, 7764, 2827, 398, 438, 7765, 3252, 2878, 3766, 7653, 7679, 821, 439}, + {1, 11, 25, 111, 42, 117, 2027, 355, 1, 14, 26, 62, 28, 45, + 356, 2028, 357, 4, 6, 54, 127, 174, 344, 348, 1389, 1037584, 0, 4, + 123, 243, 59, 2029, 691, 716, 1390, 24, 62, 23, 30, 175, 1015, 1391, + 717, 1037585, 20, 173, 170, 20, 168, 339, 232, 510, 3535, 120, 440, 338, + 254, 689, 349, 352, 1037586, 1037587, 122, 688, 485, 233, 252, 1766, 3528, 1412, + 1037588, 171, 3550, 345, 1012, 3529, 3530, 506, 1037589, 1037590, 252, 511, 484, 175, + 346, 359, 3531, 1413, 1037591, 1015, 16213, 1037592, 3548, 1414, 16214, 1037593, 16215, 1037594, + 442, 1415, 1416, 3551, 690, 1037595, 3534, 1014, 1037596, 4052, 1037597, 1037598, 1037599, 518784, + 518785, 1388, 518786, 518787, 886, 1417, 1418, 518788, 518789, 3549, 518790, 518791, 1419, 32425}, + {3, 14, 15, 126, 98, 198, 3289, 1598, 2, 2, 0, 24, 12, 105, + 57, 1799, 3198, 2, 13, 27, 15, 410, 1607, 6711, 214724, 13421, 1, 30, + 127, 10, 225, 1633, 3300, 214725, 214726, 29, 48, 13, 203, 409, 800, 142, + 25902, 214727, 62, 57, 53, 51, 415, 448, 3290, 214728, 214729, 11, 208, 414, + 34, 56, 398, 798, 12948, 572, 50, 18, 19, 113, 413, 32, 3207, 3264, + 214730, 824, 1619, 418, 810, 802, 3303, 132, 287, 214731, 805, 1609, 811, 119, + 1608, 1602, 3206, 3212, 214732, 58, 6583, 67, 807, 140, 141, 3213, 214733, 214734, + 823, 3301, 133, 806, 839, 3236, 3199, 3354, 214735, 808, 107360, 107361, 3288, 1676, + 12949, 12950, 25903, 26328, 817, 1798, 573, 118, 3265, 898, 3302, 26329, 26330, 26331} +}; + +const uint8_t ff_vc1_2ref_mvdata_bits[8][126] = { + {4, 5, 5, 5, 6, 7, 8, 10, 2, 5, 5, 6, 6, 7, + 8, 9, 10, 4, 5, 6, 6, 7, 8, 9, 10, 11, 4, 6, + 6, 7, 7, 9, 9, 10, 12, 5, 8, 8, 8, 8, 9, 9, + 10, 12, 5, 7, 8, 7, 7, 8, 9, 9, 11, 7, 9, 10, + 9, 10, 10, 10, 10, 12, 6, 9, 9, 9, 9, 9, 10, 10, + 11, 7, 10, 10, 11, 11, 11, 12, 12, 14, 8, 11, 10, 11, + 11, 11, 11, 12, 12, 8, 12, 11, 11, 12, 12, 12, 12, 13, + 8, 12, 11, 11, 12, 12, 12, 13, 12, 9, 14, 13, 11, 13, + 12, 13, 12, 13, 9, 13, 13, 12, 12, 13, 13, 13, 13, 13}, + {3, 4, 5, 6, 8, 10, 11, 11, 2, 5, 5, 6, 7, 8, + 10, 11, 11, 4, 5, 5, 6, 7, 9, 12, 13, 13, 4, 6, + 7, 7, 9, 10, 11, 13, 14, 5, 7, 7, 7, 8, 9, 11, + 13, 13, 6, 8, 8, 8, 8, 9, 10, 12, 13, 7, 9, 8, + 8, 8, 9, 11, 12, 13, 7, 9, 9, 9, 9, 9, 10, 11, + 13, 8, 10, 10, 10, 10, 10, 11, 12, 13, 9, 11, 11, 10, + 10, 10, 11, 11, 12, 10, 12, 12, 12, 11, 11, 11, 12, 12, + 10, 13, 12, 12, 11, 11, 11, 12, 12, 10, 13, 13, 12, 13, + 11, 12, 11, 12, 10, 14, 13, 13, 12, 12, 12, 11, 11, 11}, + {4, 4, 5, 5, 6, 7, 8, 9, 2, 5, 6, 6, 6, 7, + 7, 9, 9, 4, 6, 6, 6, 7, 8, 9, 11, 12, 5, 7, + 7, 7, 9, 9, 10, 11, 12, 5, 7, 7, 7, 7, 9, 9, + 10, 12, 5, 8, 8, 8, 8, 8, 9, 10, 10, 6, 9, 8, + 8, 8, 8, 9, 9, 11, 6, 10, 10, 9, 9, 9, 9, 10, + 10, 7, 11, 10, 9, 9, 10, 9, 10, 11, 7, 10, 11, 10, + 10, 10, 9, 10, 11, 8, 12, 11, 11, 10, 11, 11, 10, 10, + 8, 12, 12, 11, 11, 11, 11, 10, 11, 8, 13, 12, 12, 11, + 11, 11, 11, 10, 9, 13, 12, 12, 12, 11, 11, 10, 10, 10}, + {3, 4, 6, 7, 7, 9, 11, 11, 2, 5, 5, 6, 8, 9, + 10, 11, 13, 3, 5, 5, 7, 8, 9, 12, 14, 13, 4, 6, + 6, 7, 9, 11, 13, 14, 14, 5, 7, 7, 8, 9, 9, 13, + 15, 13, 6, 8, 8, 8, 9, 10, 12, 14, 13, 7, 10, 9, + 9, 9, 9, 12, 13, 14, 7, 11, 10, 10, 10, 10, 11, 12, + 13, 8, 11, 12, 12, 12, 11, 12, 14, 15, 9, 11, 12, 11, + 12, 11, 11, 12, 13, 9, 12, 13, 13, 12, 12, 13, 14, 14, + 9, 12, 13, 13, 13, 12, 13, 12, 14, 10, 13, 13, 14, 13, + 11, 13, 14, 15, 10, 12, 13, 15, 14, 13, 13, 13, 14, 14}, + {4, 5, 5, 5, 6, 7, 8, 8, 2, 6, 6, 6, 6, 6, + 8, 9, 10, 4, 6, 6, 6, 6, 7, 9, 10, 11, 4, 7, + 7, 7, 7, 7, 9, 10, 12, 5, 7, 7, 7, 7, 7, 9, + 10, 11, 6, 8, 8, 7, 7, 7, 8, 9, 10, 6, 9, 8, + 8, 7, 8, 10, 10, 11, 7, 9, 9, 8, 8, 8, 9, 9, + 10, 8, 10, 10, 9, 9, 9, 11, 11, 11, 8, 11, 10, 10, + 9, 9, 10, 11, 10, 10, 12, 12, 11, 11, 10, 11, 12, 11, + 10, 13, 12, 11, 11, 10, 10, 11, 11, 11, 15, 13, 13, 13, + 12, 12, 12, 12, 10, 15, 14, 13, 12, 12, 11, 11, 11, 11}, + {4, 5, 6, 6, 6, 7, 8, 8, 2, 4, 5, 6, 6, 7, + 8, 8, 9, 4, 6, 7, 7, 8, 8, 9, 10, 11, 5, 6, + 7, 7, 8, 8, 9, 10, 12, 5, 7, 8, 8, 8, 9, 10, + 11, 12, 5, 7, 8, 8, 8, 8, 9, 10, 11, 6, 8, 9, + 8, 8, 9, 10, 11, 13, 5, 8, 9, 8, 8, 9, 9, 10, + 11, 6, 10, 10, 9, 9, 10, 10, 12, 13, 6, 10, 10, 9, + 9, 10, 10, 11, 13, 7, 11, 11, 11, 11, 11, 12, 12, 13, + 7, 11, 11, 11, 11, 11, 11, 12, 12, 9, 13, 13, 13, 13, + 12, 12, 13, 12, 9, 12, 13, 12, 12, 12, 13, 13, 12, 12}, + {3, 5, 6, 8, 9, 10, 12, 12, 1, 5, 6, 7, 8, 9, + 12, 12, 12, 4, 6, 7, 8, 9, 12, 12, 14, 21, 4, 6, + 8, 9, 9, 12, 13, 13, 14, 6, 9, 8, 8, 9, 13, 14, + 13, 21, 6, 9, 9, 8, 9, 10, 11, 12, 13, 8, 10, 10, + 11, 11, 12, 12, 21, 21, 8, 11, 10, 11, 11, 12, 13, 14, + 21, 9, 13, 10, 11, 13, 13, 12, 21, 21, 9, 12, 10, 11, + 12, 12, 13, 14, 21, 11, 15, 21, 13, 14, 15, 21, 15, 21, + 10, 14, 14, 13, 13, 21, 13, 13, 21, 13, 21, 21, 21, 20, + 20, 14, 20, 20, 11, 14, 14, 20, 20, 13, 20, 20, 14, 16}, + {2, 5, 6, 8, 9, 10, 13, 13, 2, 4, 5, 6, 8, 9, + 10, 13, 14, 3, 5, 7, 8, 10, 12, 15, 20, 16, 4, 6, + 8, 8, 10, 12, 13, 20, 20, 7, 8, 8, 9, 10, 11, 12, + 16, 20, 7, 8, 8, 8, 10, 11, 13, 20, 20, 8, 10, 10, + 10, 10, 11, 12, 15, 14, 8, 9, 9, 9, 10, 10, 13, 13, + 20, 11, 12, 11, 11, 11, 13, 12, 13, 20, 11, 12, 11, 11, + 12, 12, 13, 13, 20, 10, 14, 11, 11, 12, 12, 13, 20, 20, + 11, 13, 12, 11, 12, 13, 14, 14, 20, 11, 19, 19, 13, 13, + 15, 15, 16, 16, 11, 13, 14, 11, 13, 12, 13, 16, 16, 16} +}; + const uint8_t wmv3_dc_scale_table[32]={ 0, 2, 4, 8, 8, 8, 9, 9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,18,19,19,20,20,21,21 }; @@ -262,6 +583,112 @@ const uint8_t ff_vc1_cbpcy_p_bits[4][64] = { } }; +/* Interlaced CBPCY VLC tables (Table 124 - Table 131) */ + +const uint16_t ff_vc1_icbpcy_p_codes[8][63] = { + { + 12058, 12059, 6028, 144, 680, 681, 3015, 145, 682, 683, 1504, 74, 150, + 151, 189, 146, 684, 685, 1505, 152, 306, 307, 377, 308, 618, 619, 764, + 78, 64, 65, 43, 147, 686, 687, 1506, 310, 622, 623, 765, 158, 318, + 319, 383, 80, 66, 67, 44, 81, 164, 165, 190, 83, 68, 69, 45, + 84, 70, 71, 46, 3, 0, 1, 1 + }, { + 65, 66, 256, 67, 136, 137, 257, 69, 140, 141, 258, 16, 34, + 35, 36, 71, 16, 17, 259, 37, 88, 89, 90, 91, 90, 91, 92, + 12, 48, 49, 25, 9, 20, 21, 44, 92, 93, 94, 95, 38, 93, + 94, 95, 13, 52, 53, 27, 20, 39, 42, 43, 14, 56, 57, 29, + 15, 60, 61, 31, 5, 9, 0, 3 + }, { + 50, 51, 26, 38, 228, 229, 486, 39, 230, 231, 487, 14, 99, + 108, 119, 40, 232, 233, 488, 123, 218, 219, 236, 245, 440, 441, 474, + 33, 75, 84, 43, 41, 234, 235, 489, 74, 442, 443, 475, 32, 222, + 223, 242, 34, 85, 88, 45, 15, 112, 113, 120, 35, 89, 92, 47, + 36, 93, 98, 48, 2, 31, 6, 0 + }, { + 40, 41, 157, 0, 490, 491, 492, 1, 493, 494, 495, 5, 240, + 241, 59, 2, 496, 497, 498, 63, 348, 349, 153, 16, 976, 977, 304, + 15, 158, 159, 251, 3, 499, 500, 501, 17, 978, 979, 305, 9, 350, + 351, 156, 16, 168, 169, 56, 6, 242, 243, 77, 17, 170, 171, 57, + 18, 172, 173, 58, 6, 22, 23, 14 + }, { + 60, 61, 31, 10, 97, 98, 2, 11, 99, 100, 3, 7, 3, + 4, 11, 12, 101, 102, 4, 18, 10, 11, 20, 27, 24, 25, 52, + 44, 103, 104, 53, 13, 105, 108, 5, 96, 26, 27, 53, 19, 14, + 15, 21, 45, 109, 110, 56, 8, 8, 9, 12, 46, 111, 114, 58, + 47, 115, 0, 59, 7, 20, 21, 4 + }, { + 56, 57, 157, 10, 145, 146, 147, 11, 148, 149, 150, 3, 238, + 239, 54, 12, 151, 152, 153, 8, 484, 485, 106, 24, 972, 973, 214, + 14, 158, 159, 245, 13, 154, 155, 156, 25, 974, 975, 215, 9, 488, + 489, 144, 15, 232, 233, 246, 5, 240, 241, 55, 16, 234, 235, 247, + 17, 236, 237, 52, 0, 62, 63, 2 + }, { + 60, 61, 463, 0, 191, 224, 508, 1, 225, 226, 509, 9, 497, + 498, 499, 2, 227, 228, 510, 17, 1006, 1007, 1008, 33, 2018, 2019, 2020, + 24, 1015, 1022, 1023, 3, 229, 230, 128, 46, 2021, 2022, 2023, 22, 1012, + 1013, 1014, 25, 258, 259, 260, 10, 500, 501, 502, 26, 261, 262, 263, + 27, 376, 377, 462, 29, 189, 190, 496 + }, { + 3, 4, 438, 4, 46, 47, 14, 5, 48, 49, 15, 3, 10, + 11, 20, 6, 50, 51, 16, 5, 48, 49, 50, 9, 102, 103, 104, + 29, 439, 440, 441, 7, 52, 53, 17, 22, 105, 106, 107, 10, 54, + 55, 216, 30, 442, 443, 444, 4, 21, 22, 23, 31, 445, 446, 447, + 0, 16, 17, 18, 28, 217, 218, 19 + } +}; + +const uint8_t ff_vc1_icbpcy_p_bits[8][63] = { + { + 15, 15, 14, 9, 11, 11, 13, 9, 11, 11, 12, 8, 9, + 9, 9, 9, 11, 11, 12, 9, 10, 10, 10, 10, 11, 11, 11, + 8, 8, 8, 7, 9, 11, 11, 12, 10, 11, 11, 11, 9, 10, + 10, 10, 8, 8, 8, 7, 8, 9, 9, 9, 8, 8, 8, 7, + 8, 8, 8, 7, 3, 3, 3, 1 + }, { + 7, 7, 9, 7, 8, 8, 9, 7, 8, 8, 9, 6, 7, + 7, 7, 7, 7, 7, 9, 7, 8, 8, 8, 8, 9, 9, 9, + 6, 7, 7, 6, 6, 7, 7, 8, 8, 9, 9, 9, 7, 8, + 8, 8, 6, 7, 7, 6, 6, 7, 7, 7, 6, 7, 7, 6, + 6, 7, 7, 6, 3, 4, 3, 2 + }, { + 6, 6, 5, 6, 8, 8, 9, 6, 8, 8, 9, 5, 7, + 7, 7, 6, 8, 8, 9, 7, 8, 8, 8, 8, 9, 9, 9, + 6, 7, 7, 6, 6, 8, 8, 9, 7, 9, 9, 9, 6, 8, + 8, 8, 6, 7, 7, 6, 5, 7, 7, 7, 6, 7, 7, 6, + 6, 7, 7, 6, 3, 5, 4, 2 + }, { + 6, 6, 8, 4, 9, 9, 9, 4, 9, 9, 9, 4, 8, + 8, 7, 4, 9, 9, 9, 6, 9, 9, 8, 6, 10, 10, 9, + 5, 8, 8, 8, 4, 9, 9, 9, 6, 10, 10, 9, 5, 9, + 9, 8, 5, 8, 8, 7, 4, 8, 8, 7, 5, 8, 8, 7, + 5, 8, 8, 7, 3, 5, 5, 4 + }, { + 6, 6, 5, 5, 7, 7, 7, 5, 7, 7, 7, 5, 6, + 6, 6, 5, 7, 7, 7, 6, 7, 7, 7, 7, 8, 8, 8, + 6, 7, 7, 6, 5, 7, 7, 7, 7, 8, 8, 8, 6, 7, + 7, 7, 6, 7, 7, 6, 5, 6, 6, 6, 6, 7, 7, 6, + 6, 7, 6, 6, 4, 5, 5, 3 + }, { + 6, 6, 8, 4, 8, 8, 8, 4, 8, 8, 8, 4, 8, + 8, 7, 4, 8, 8, 8, 5, 9, 9, 8, 6, 10, 10, 9, + 5, 8, 8, 8, 4, 8, 8, 8, 6, 10, 10, 9, 5, 9, + 9, 8, 5, 8, 8, 8, 4, 8, 8, 7, 5, 8, 8, 8, + 5, 8, 8, 7, 3, 6, 6, 4 + }, { + 6, 6, 9, 3, 8, 8, 9, 3, 8, 8, 9, 4, 9, + 9, 9, 3, 8, 8, 9, 5, 10, 10, 10, 6, 11, 11, 11, + 5, 10, 10, 10, 3, 8, 8, 8, 6, 11, 11, 11, 5, 10, + 10, 10, 5, 9, 9, 9, 4, 9, 9, 9, 5, 9, 9, 9, + 5, 9, 9, 9, 5, 8, 8, 9 + }, { + 6, 6, 10, 3, 7, 7, 7, 3, 7, 7, 7, 4, 8, + 8, 8, 3, 7, 7, 7, 5, 9, 9, 9, 6, 10, 10, 10, + 6, 10, 10, 10, 3, 7, 7, 7, 6, 10, 10, 10, 5, 9, + 9, 9, 6, 10, 10, 10, 4, 8, 8, 8, 6, 10, 10, 10, + 5, 9, 9, 9, 6, 9, 9, 9 + } +}; + /* MacroBlock Transform Type: 7.1.3.11, p89 * 8x8:B * 8x4:B:btm 8x4:B:top 8x4:B:both, @@ -520,3 +947,38 @@ const int32_t ff_vc1_dqscale[63] = { 0x14E6, 0x147B, 0x1414, 0x13B1, 0x1352, 0x12F7, 0x129E, 0x1249, 0x11F7, 0x11A8, 0x115B, 0x1111, 0x10C9, 0x1084, 0x1000 }; + +/* P Interlaced field picture MV predictor scaling values (Table 114) */ +const uint16_t vc1_field_mvpred_scales[2][7][4] = { +// Refdist 0 1 2 3 or greater + { // current field is first + { 128, 192, 213, 224}, // SCALEOPP + { 512, 341, 307, 293}, // SCALESAME1 + { 219, 236, 242, 245}, // SCALESAME2 + { 32, 48, 53, 56}, // SCALEZONE1_X + { 8, 12, 13, 14}, // SCALEZONE1_Y + { 37, 20, 14, 11}, // ZONE1OFFSET_X + { 10, 5, 4, 3} // ZONE1OFFSET_Y + }, + { // current field is second + { 128, 64, 43, 32}, // SCALEOPP + { 512, 1024, 1536, 2048}, // SCALESAME1 + { 219, 204, 200, 198}, // SCALESAME2 + { 32, 16, 11, 8}, // SCALEZONE1_X + { 8, 4, 3, 2}, // SCALEZONE1_Y + { 37, 52, 56, 58}, // ZONE1OFFSET_X + { 10, 13, 14, 15} // ZONE1OFFSET_Y + } +}; + +/* B Interlaced field picture backward MV predictor scaling values for first field (Table 115) */ +const uint16_t vc1_b_field_mvpred_scales[7][4] = { +// BRFD 0 1 2 3 or greater + { 171, 205, 219, 228}, // SCALESAME + { 384, 320, 299, 288}, // SCALEOPP1 + { 230, 239, 244, 246}, // SCALEOPP2 + { 43, 51, 55, 57}, // SCALEZONE1_X + { 11, 13, 14, 14}, // SCALEZONE1_Y + { 26, 17, 12, 10}, // ZONE1OFFSET_X + { 7, 4, 3, 3} // ZONE1OFFSET_Y +}; diff --git a/libavcodec/vc1data.h b/libavcodec/vc1data.h index 131fd3a0ca..da8f0a1f40 100644 --- a/libavcodec/vc1data.h +++ b/libavcodec/vc1data.h @@ -44,6 +44,9 @@ extern const uint8_t ff_vc1_mv_pmode_table2[2][4]; extern const int ff_vc1_fps_nr[5], ff_vc1_fps_dr[2]; extern const uint8_t ff_vc1_pquant_table[3][32]; +/* MBMODE table for interlaced frame P-picture */ +extern const uint8_t ff_vc1_mbmode_intfrp[2][15][4]; + /** @name VC-1 VLC tables and defines * @todo TODO move this into the context */ @@ -63,14 +66,32 @@ extern VLC ff_vc1_ttmb_vlc[3]; extern VLC ff_vc1_mv_diff_vlc[4]; #define VC1_CBPCY_P_VLC_BITS 9 //14 extern VLC ff_vc1_cbpcy_p_vlc[4]; +#define VC1_ICBPCY_VLC_BITS 9 +extern VLC ff_vc1_icbpcy_vlc[8]; #define VC1_4MV_BLOCK_PATTERN_VLC_BITS 6 extern VLC ff_vc1_4mv_block_pattern_vlc[4]; +#define VC1_2MV_BLOCK_PATTERN_VLC_BITS 3 +extern VLC ff_vc1_2mv_block_pattern_vlc[4]; #define VC1_TTBLK_VLC_BITS 5 extern VLC ff_vc1_ttblk_vlc[3]; #define VC1_SUBBLKPAT_VLC_BITS 6 extern VLC ff_vc1_subblkpat_vlc[3]; +#define VC1_INTFR_4MV_MBMODE_VLC_BITS 9 +extern VLC ff_vc1_intfr_4mv_mbmode_vlc[4]; +#define VC1_INTFR_NON4MV_MBMODE_VLC_BITS 6 +extern VLC ff_vc1_intfr_non4mv_mbmode_vlc[4]; +#define VC1_IF_MMV_MBMODE_VLC_BITS 5 +extern VLC ff_vc1_if_mmv_mbmode_vlc[8]; +#define VC1_IF_1MV_MBMODE_VLC_BITS 5 +extern VLC ff_vc1_if_1mv_mbmode_vlc[8]; +#define VC1_1REF_MVDATA_VLC_BITS 9 +extern VLC ff_vc1_1ref_mvdata_vlc[4]; +#define VC1_2REF_MVDATA_VLC_BITS 9 +extern VLC ff_vc1_2ref_mvdata_vlc[8]; extern VLC ff_vc1_ac_coeff_table[8]; + +#define VC1_IF_MBMODE_VLC_BITS 5 //@} @@ -101,12 +122,20 @@ extern const uint8_t ff_vc1_norm6_spec[64][5]; extern const uint8_t ff_vc1_4mv_block_pattern_codes[4][16]; extern const uint8_t ff_vc1_4mv_block_pattern_bits[4][16]; +/* 2MV Block pattern VLC tables */ +extern const uint8_t ff_vc1_2mv_block_pattern_codes[4][4]; +extern const uint8_t ff_vc1_2mv_block_pattern_bits[4][4]; + extern const uint8_t wmv3_dc_scale_table[32]; /* P-Picture CBPCY VLC tables */ extern const uint16_t ff_vc1_cbpcy_p_codes[4][64]; extern const uint8_t ff_vc1_cbpcy_p_bits[4][64]; +/* Interlaced CBPCY VLC tables (Table 124 - Table 131) */ +extern const uint16_t ff_vc1_icbpcy_p_codes[8][63]; +extern const uint8_t ff_vc1_icbpcy_p_bits[8][63]; + /* MacroBlock Transform Type: 7.1.3.11, p89 * 8x8:B * 8x4:B:btm 8x4:B:top 8x4:B:both, @@ -131,6 +160,26 @@ extern const uint8_t ff_vc1_subblkpat_bits[3][15]; extern const uint16_t ff_vc1_mv_diff_codes[4][73]; extern const uint8_t ff_vc1_mv_diff_bits[4][73]; +/* Interlaced frame picture MBMODE VLC tables (p. 246, p. 360) */ +extern const uint16_t ff_vc1_intfr_4mv_mbmode_codes[4][15]; +extern const uint8_t ff_vc1_intfr_4mv_mbmode_bits[4][15]; +extern const uint8_t ff_vc1_intfr_non4mv_mbmode_codes[4][9]; +extern const uint8_t ff_vc1_intfr_non4mv_mbmode_bits[4][9]; + +/* Interlaced field picture MBMODE VLC tables (p. 356 - 11.4.1, 11.4.2) */ +extern const uint8_t ff_vc1_if_mmv_mbmode_codes[8][8]; +extern const uint8_t ff_vc1_if_mmv_mbmode_bits[8][8]; +extern const uint8_t ff_vc1_if_1mv_mbmode_codes[8][6]; +extern const uint8_t ff_vc1_if_1mv_mbmode_bits[8][6]; + +/* Interlaced frame/field picture MVDATA VLC tables */ +/* 1-reference tables */ +extern const uint32_t ff_vc1_1ref_mvdata_codes[4][72]; +extern const uint8_t ff_vc1_1ref_mvdata_bits[4][72]; +/* 2-reference tables */ +extern const uint32_t ff_vc1_2ref_mvdata_codes[8][126]; +extern const uint8_t ff_vc1_2ref_mvdata_bits[8][126]; + /* DC differentials low+hi-mo, p217 are the same as in msmpeg4data .h */ /* Scantables/ZZ scan are at 11.9 (p262) and 8.1.1.12 (p10) */ @@ -141,8 +190,14 @@ extern const int8_t ff_vc1_adv_interlaced_8x8_zz [64]; extern const int8_t ff_vc1_adv_interlaced_8x4_zz [32]; extern const int8_t ff_vc1_adv_interlaced_4x8_zz [32]; extern const int8_t ff_vc1_adv_interlaced_4x4_zz [16]; +extern const int8_t ff_vc1_intra_horz_8x8_zz [64]; +extern const int8_t ff_vc1_intra_vert_8x8_zz [64]; /* DQScale as specified in 8.1.3.9 - almost identical to 0x40000/i */ extern const int32_t ff_vc1_dqscale[63]; +/* P Interlaced field picture MV predictor scaling values (Table 114) */ +extern const uint16_t vc1_field_mvpred_scales[2][7][4]; +/* B Interlaced field picture backward MV predictor scaling values for first field (Table 115) */ +extern const uint16_t vc1_b_field_mvpred_scales[7][4]; #endif /* AVCODEC_VC1DATA_H */ From cad16562c8d76ea2a2a6495f29296c3ff7966946 Mon Sep 17 00:00:00 2001 From: Mashiat Sarker Shakkhar Date: Fri, 7 Oct 2011 00:00:26 +0500 Subject: [PATCH 06/34] vc1dec: interlaced stream decoding support 3/3 Cosmetics: break some lines and reformat TODOs Signed-off-by: Anton Khirnov --- libavcodec/vc1.c | 396 ++++++-- libavcodec/vc1dec.c | 2238 +++++++++++++++++++++++++++++++++++++------ libavcodec/vc1dsp.c | 21 + 3 files changed, 2236 insertions(+), 419 deletions(-) diff --git a/libavcodec/vc1.c b/libavcodec/vc1.c index 870feaaa76..11d1d58e44 100644 --- a/libavcodec/vc1.c +++ b/libavcodec/vc1.c @@ -1,5 +1,6 @@ /* * VC-1 and WMV3 decoder common code + * Copyright (c) 2011 Mashiat Sarker Shakkhar * Copyright (c) 2006-2007 Konstantin Shishkov * Partly based on vc9.c (c) 2005 Anonymous, Alex Beregszaszi, Michael Niedermayer * @@ -116,7 +117,7 @@ static int bitplane_decoding(uint8_t* data, int *raw_flag, VC1Context *v) int width, height, stride; width = v->s.mb_width; - height = v->s.mb_height; + height = v->s.mb_height >> v->field_mode; stride = v->s.mb_stride; invert = get_bits1(gb); imode = get_vlc2(gb, ff_vc1_imode_vlc.table, VC1_IMODE_VLC_BITS, 1); @@ -682,6 +683,7 @@ int vc1_parse_frame_header(VC1Context *v, GetBitContext* gb) v->lutuv[i] = av_clip_uint8((scale * (i - 128) + 128*64 + 32) >> 6); } } + v->qs_last = v->s.quarter_sample; if(v->mv_mode == MV_PMODE_1MV_HPEL || v->mv_mode == MV_PMODE_1MV_HPEL_BILIN) v->s.quarter_sample = 0; else if(v->mv_mode == MV_PMODE_INTENSITY_COMP) { @@ -739,6 +741,7 @@ int vc1_parse_frame_header(VC1Context *v, GetBitContext* gb) else v->tt_index = 2; v->mv_mode = get_bits1(gb) ? MV_PMODE_1MV : MV_PMODE_1MV_HPEL_BILIN; + v->qs_last = v->s.quarter_sample; v->s.quarter_sample = (v->mv_mode == MV_PMODE_1MV); v->s.mspel = v->s.quarter_sample; @@ -794,38 +797,78 @@ int 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 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 */ v->p_frame_skipped = 0; + if (v->second_field) { + v->s.pict_type = (v->fptype & 1) ? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I; + if (v->fptype & 4) + v->s.pict_type = (v->fptype & 1) ? AV_PICTURE_TYPE_BI : AV_PICTURE_TYPE_B; + v->s.current_picture_ptr->f.pict_type = v->s.pict_type; + if (!v->pic_header_flag) + goto parse_common_info; + } if(v->interlace){ v->fcm = decode012(gb); if(v->fcm){ - if(!v->warn_interlaced++) - av_log(v->s.avctx, AV_LOG_ERROR, "Interlaced frames/fields support is not implemented\n"); - return -1; + if (v->fcm == 2) + v->field_mode = 1; + else + v->field_mode = 0; + if (!v->warn_interlaced++) + av_log(v->s.avctx, AV_LOG_ERROR, "Interlaced frames/fields support is incomplete\n"); } } - switch(get_unary(gb, 0, 4)) { - case 0: - v->s.pict_type = AV_PICTURE_TYPE_P; - break; - case 1: - v->s.pict_type = AV_PICTURE_TYPE_B; - break; - case 2: - v->s.pict_type = AV_PICTURE_TYPE_I; - break; - case 3: - v->s.pict_type = AV_PICTURE_TYPE_BI; - break; - case 4: - v->s.pict_type = AV_PICTURE_TYPE_P; // skipped pic - v->p_frame_skipped = 1; - break; + + if (v->field_mode) { + v->fptype = get_bits(gb, 3); + v->s.pict_type = (v->fptype & 2) ? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I; + if (v->fptype & 4) // B-picture + v->s.pict_type = (v->fptype & 2) ? AV_PICTURE_TYPE_BI : AV_PICTURE_TYPE_B; + } else { + switch(get_unary(gb, 0, 4)) { + case 0: + v->s.pict_type = AV_PICTURE_TYPE_P; + break; + case 1: + v->s.pict_type = AV_PICTURE_TYPE_B; + break; + case 2: + v->s.pict_type = AV_PICTURE_TYPE_I; + break; + case 3: + v->s.pict_type = AV_PICTURE_TYPE_BI; + break; + case 4: + v->s.pict_type = AV_PICTURE_TYPE_P; // skipped pic + v->p_frame_skipped = 1; + break; + } } if(v->tfcntrflag) skip_bits(gb, 8); @@ -847,6 +890,26 @@ int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) v->rnd = get_bits1(gb); if(v->interlace) v->uvsamp = get_bits1(gb); + if (v->field_mode) { + if (!v->refdist_flag) + v->refdist = 0; + else { + if ((v->s.pict_type != AV_PICTURE_TYPE_B) + && (v->s.pict_type != AV_PICTURE_TYPE_BI)) { + v->refdist = get_bits(gb, 2); + if (v->refdist == 3) + v->refdist += get_unary(gb, 0, 16); + } else { + v->bfraction_lut_index = get_vlc2(gb, ff_vc1_bfraction_vlc.table, VC1_BFRACTION_VLC_BITS, 1); + v->bfraction = ff_vc1_bfraction_lut[v->bfraction_lut_index]; + v->frfd = (v->bfraction * v->refdist) >> 8; + v->brfd = v->refdist - v->frfd - 1; + if (v->brfd < 0) + v->brfd = 0; + } + } + goto parse_common_info; + } if(v->finterpflag) v->interpfrm = get_bits1(gb); if(v->s.pict_type == AV_PICTURE_TYPE_B) { v->bfraction_lut_index = get_vlc2(gb, ff_vc1_bfraction_vlc.table, VC1_BFRACTION_VLC_BITS, 1); @@ -855,6 +918,10 @@ int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) v->s.pict_type = AV_PICTURE_TYPE_BI; /* XXX: should not happen here */ } } + + parse_common_info: + if (v->field_mode) + v->cur_field_type = !(v->tff ^ v->second_field); pqindex = get_bits(gb, 5); if(!pqindex) return -1; v->pqindex = pqindex; @@ -869,23 +936,34 @@ int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) if (v->quantizer_mode == QUANT_NON_UNIFORM) v->pquantizer = 0; v->pqindex = pqindex; - if (pqindex < 9) v->halfpq = get_bits1(gb); - else v->halfpq = 0; + if (pqindex < 9) + v->halfpq = get_bits1(gb); + else + v->halfpq = 0; if (v->quantizer_mode == QUANT_FRAME_EXPLICIT) v->pquantizer = get_bits1(gb); if(v->postprocflag) v->postproc = get_bits(gb, 2); - if(v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_P) v->use_ic = 0; + if(v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_P) + v->use_ic = 0; - if(v->parse_only) + if (v->parse_only) return 0; switch(v->s.pict_type) { case AV_PICTURE_TYPE_I: case AV_PICTURE_TYPE_BI: + if (v->fcm == 1) { //interlace frame picture + status = bitplane_decoding(v->fieldtx_plane, &v->fieldtx_is_raw, v); + if (status < 0) + return -1; + av_log(v->s.avctx, AV_LOG_DEBUG, "FIELDTX plane encoding: " + "Imode: %i, Invert: %i\n", status>>1, status&1); + } status = bitplane_decoding(v->acpred_plane, &v->acpred_is_raw, v); - if (status < 0) return -1; + if (status < 0) + return -1; av_log(v->s.avctx, AV_LOG_DEBUG, "ACPRED plane encoding: " "Imode: %i, Invert: %i\n", status>>1, status&1); v->condover = CONDOVER_NONE; @@ -893,82 +971,148 @@ int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) v->condover = decode012(gb); if(v->condover == CONDOVER_SELECT) { status = bitplane_decoding(v->over_flags_plane, &v->overflg_is_raw, v); - if (status < 0) return -1; + if (status < 0) + return -1; av_log(v->s.avctx, AV_LOG_DEBUG, "CONDOVER plane encoding: " "Imode: %i, Invert: %i\n", status>>1, status&1); } } break; case AV_PICTURE_TYPE_P: - if (v->extended_mv) v->mvrange = get_unary(gb, 0, 3); - else v->mvrange = 0; + if (v->field_mode) { + v->numref = get_bits1(gb); + if (!v->numref) { + v->reffield = get_bits1(gb); + v->ref_field_type[0] = v->reffield ^ !v->cur_field_type; + } + } + if (v->extended_mv) + v->mvrange = get_unary(gb, 0, 3); + else + v->mvrange = 0; + if (v->interlace) { + if (v->extended_dmv) + v->dmvrange = get_unary(gb, 0, 3); + else + v->dmvrange = 0; + if (v->fcm == 1) { // interlaced frame picture + v->fourmvswitch = get_bits1(gb); + v->intcomp = get_bits1(gb); + if (v->intcomp) { + v->lumscale = get_bits(gb, 6); + v->lumshift = get_bits(gb, 6); + INIT_LUT(v->lumscale, v->lumshift, v->luty, v->lutuv); + } + status = bitplane_decoding(v->s.mbskip_table, &v->skip_is_raw, v); + av_log(v->s.avctx, AV_LOG_DEBUG, "SKIPMB plane encoding: " + "Imode: %i, Invert: %i\n", status>>1, status&1); + mbmodetab = get_bits(gb, 2); + if (v->fourmvswitch) + v->mbmode_vlc = &ff_vc1_intfr_4mv_mbmode_vlc[mbmodetab]; + else + v->mbmode_vlc = &ff_vc1_intfr_non4mv_mbmode_vlc[mbmodetab]; + imvtab = get_bits(gb, 2); + v->imv_vlc = &ff_vc1_1ref_mvdata_vlc[imvtab]; + // interlaced p-picture cbpcy range is [1, 63] + icbptab = get_bits(gb, 3); + v->cbpcy_vlc = &ff_vc1_icbpcy_vlc[icbptab]; + twomvbptab = get_bits(gb, 2); + v->twomvbp_vlc = &ff_vc1_2mv_block_pattern_vlc[twomvbptab]; + if (v->fourmvswitch) { + fourmvbptab = get_bits(gb, 2); + v->fourmvbp_vlc = &ff_vc1_4mv_block_pattern_vlc[fourmvbptab]; + } + } + } v->k_x = v->mvrange + 9 + (v->mvrange >> 1); //k_x can be 9 10 12 13 v->k_y = v->mvrange + 8; //k_y can be 8 9 10 11 v->range_x = 1 << (v->k_x - 1); v->range_y = 1 << (v->k_y - 1); - if (v->pq < 5) v->tt_index = 0; - else if(v->pq < 13) v->tt_index = 1; - else v->tt_index = 2; - - 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); - /* 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; + if (v->pq < 5) + v->tt_index = 0; + else if(v->pq < 13) + v->tt_index = 1; + else + v->tt_index = 2; + if (v->fcm != 1) { + int mvmode; + mvmode = get_unary(gb, 1, 4); + lowquant = (v->pq > 12) ? 0 : 1; + v->mv_mode = ff_vc1_mv_pmode_table[lowquant][mvmode]; + if (v->mv_mode == MV_PMODE_INTENSITY_COMP) { + int mvmode2; + mvmode2 = get_unary(gb, 1, 3); + v->mv_mode2 = ff_vc1_mv_pmode_table2[lowquant][mvmode2]; + if (v->field_mode) + v->intcompfield = decode210(gb); + v->lumscale = get_bits(gb, 6); + v->lumshift = get_bits(gb, 6); + INIT_LUT(v->lumscale, v->lumshift, v->luty, v->lutuv); + if ((v->field_mode) && !v->intcompfield) { + v->lumscale2 = get_bits(gb, 6); + v->lumshift2 = get_bits(gb, 6); + INIT_LUT(v->lumscale2, v->lumshift2, v->luty2, v->lutuv2); + } + v->use_ic = 1; } - 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); - } - v->use_ic = 1; - } - if(v->mv_mode == MV_PMODE_1MV_HPEL || v->mv_mode == MV_PMODE_1MV_HPEL_BILIN) - v->s.quarter_sample = 0; - else if(v->mv_mode == MV_PMODE_INTENSITY_COMP) { - if(v->mv_mode2 == MV_PMODE_1MV_HPEL || v->mv_mode2 == MV_PMODE_1MV_HPEL_BILIN) + v->qs_last = v->s.quarter_sample; + if(v->mv_mode == MV_PMODE_1MV_HPEL || v->mv_mode == MV_PMODE_1MV_HPEL_BILIN) v->s.quarter_sample = 0; - else + else if(v->mv_mode == MV_PMODE_INTENSITY_COMP) { + if(v->mv_mode2 == MV_PMODE_1MV_HPEL || v->mv_mode2 == MV_PMODE_1MV_HPEL_BILIN) + v->s.quarter_sample = 0; + else + v->s.quarter_sample = 1; + } else v->s.quarter_sample = 1; - } else - v->s.quarter_sample = 1; - v->s.mspel = !(v->mv_mode == MV_PMODE_1MV_HPEL_BILIN || (v->mv_mode == MV_PMODE_INTENSITY_COMP && v->mv_mode2 == MV_PMODE_1MV_HPEL_BILIN)); - - if ((v->mv_mode == MV_PMODE_INTENSITY_COMP && - v->mv_mode2 == MV_PMODE_MIXED_MV) - || v->mv_mode == MV_PMODE_MIXED_MV) - { - status = bitplane_decoding(v->mv_type_mb_plane, &v->mv_type_is_raw, v); - if (status < 0) return -1; - av_log(v->s.avctx, AV_LOG_DEBUG, "MB MV Type plane encoding: " - "Imode: %i, Invert: %i\n", status>>1, status&1); - } else { - v->mv_type_is_raw = 0; - memset(v->mv_type_mb_plane, 0, v->s.mb_stride * v->s.mb_height); + v->s.mspel = !(v->mv_mode == MV_PMODE_1MV_HPEL_BILIN || (v->mv_mode == MV_PMODE_INTENSITY_COMP && v->mv_mode2 == MV_PMODE_1MV_HPEL_BILIN)); } - status = bitplane_decoding(v->s.mbskip_table, &v->skip_is_raw, v); - if (status < 0) return -1; - av_log(v->s.avctx, AV_LOG_DEBUG, "MB Skip plane encoding: " - "Imode: %i, Invert: %i\n", status>>1, status&1); + if (v->fcm == 0) { // progressive + if ((v->mv_mode == MV_PMODE_INTENSITY_COMP && + v->mv_mode2 == MV_PMODE_MIXED_MV) + || v->mv_mode == MV_PMODE_MIXED_MV) + { + status = bitplane_decoding(v->mv_type_mb_plane, &v->mv_type_is_raw, v); + if (status < 0) + return -1; + av_log(v->s.avctx, AV_LOG_DEBUG, "MB MV Type plane encoding: " + "Imode: %i, Invert: %i\n", status>>1, status&1); + } else { + v->mv_type_is_raw = 0; + memset(v->mv_type_mb_plane, 0, v->s.mb_stride * v->s.mb_height); + } + status = bitplane_decoding(v->s.mbskip_table, &v->skip_is_raw, v); + if (status < 0) + return -1; + av_log(v->s.avctx, AV_LOG_DEBUG, "MB Skip plane encoding: " + "Imode: %i, Invert: %i\n", status>>1, status&1); - /* Hopefully this is correct for P frames */ - v->s.mv_table_index = get_bits(gb, 2); //but using ff_vc1_ tables - v->cbpcy_vlc = &ff_vc1_cbpcy_p_vlc[get_bits(gb, 2)]; + /* Hopefully this is correct for P frames */ + v->s.mv_table_index = get_bits(gb, 2); //but using ff_vc1_ tables + v->cbpcy_vlc = &ff_vc1_cbpcy_p_vlc[get_bits(gb, 2)]; + } else if (v->fcm == 1) { // frame interlaced + v->qs_last = v->s.quarter_sample; + v->s.quarter_sample = 1; + v->s.mspel = 1; + } else { // field interlaced + mbmodetab = get_bits(gb, 3); + imvtab = get_bits(gb, 2 + v->numref); + if (!v->numref) + v->imv_vlc = &ff_vc1_1ref_mvdata_vlc[imvtab]; + else + v->imv_vlc = &ff_vc1_2ref_mvdata_vlc[imvtab]; + icbptab = get_bits(gb, 3); + v->cbpcy_vlc = &ff_vc1_icbpcy_vlc[icbptab]; + if ((v->mv_mode == MV_PMODE_INTENSITY_COMP && + v->mv_mode2 == MV_PMODE_MIXED_MV) || v->mv_mode == MV_PMODE_MIXED_MV) { + fourmvbptab = get_bits(gb, 2); + v->fourmvbp_vlc = &ff_vc1_4mv_block_pattern_vlc[fourmvbptab]; + v->mbmode_vlc = &ff_vc1_if_mmv_mbmode_vlc[mbmodetab]; + } else { + v->mbmode_vlc = &ff_vc1_if_1mv_mbmode_vlc[mbmodetab]; + } + } if (v->dquant) { av_log(v->s.avctx, AV_LOG_DEBUG, "VOP DQuant info\n"); @@ -989,32 +1133,72 @@ int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) } break; case AV_PICTURE_TYPE_B: - if (v->extended_mv) v->mvrange = get_unary(gb, 0, 3); - else v->mvrange = 0; + // TODO: implement interlaced frame B picture decoding + if (v->fcm == 1) + return -1; + if (v->extended_mv) + v->mvrange = get_unary(gb, 0, 3); + else + v->mvrange = 0; v->k_x = v->mvrange + 9 + (v->mvrange >> 1); //k_x can be 9 10 12 13 v->k_y = v->mvrange + 8; //k_y can be 8 9 10 11 v->range_x = 1 << (v->k_x - 1); v->range_y = 1 << (v->k_y - 1); - if (v->pq < 5) v->tt_index = 0; - else if(v->pq < 13) v->tt_index = 1; - else v->tt_index = 2; + if (v->pq < 5) + v->tt_index = 0; + else if(v->pq < 13) + v->tt_index = 1; + else + v->tt_index = 2; - v->mv_mode = get_bits1(gb) ? MV_PMODE_1MV : MV_PMODE_1MV_HPEL_BILIN; - v->s.quarter_sample = (v->mv_mode == MV_PMODE_1MV); - v->s.mspel = v->s.quarter_sample; - - status = bitplane_decoding(v->direct_mb_plane, &v->dmb_is_raw, v); - if (status < 0) return -1; - av_log(v->s.avctx, AV_LOG_DEBUG, "MB Direct Type plane encoding: " - "Imode: %i, Invert: %i\n", status>>1, status&1); - status = bitplane_decoding(v->s.mbskip_table, &v->skip_is_raw, v); - if (status < 0) return -1; - av_log(v->s.avctx, AV_LOG_DEBUG, "MB Skip plane encoding: " - "Imode: %i, Invert: %i\n", status>>1, status&1); - - v->s.mv_table_index = get_bits(gb, 2); - v->cbpcy_vlc = &ff_vc1_cbpcy_p_vlc[get_bits(gb, 2)]; + if (v->field_mode) { + int mvmode; + if (v->extended_dmv) + v->dmvrange = get_unary(gb, 0, 3); + mvmode = get_unary(gb, 1, 3); + lowquant = (v->pq > 12) ? 0 : 1; + v->mv_mode = ff_vc1_mv_pmode_table2[lowquant][mvmode]; + v->qs_last = v->s.quarter_sample; + v->s.quarter_sample = (v->mv_mode == MV_PMODE_1MV || v->mv_mode == MV_PMODE_MIXED_MV); + v->s.mspel = !(v->mv_mode == MV_PMODE_1MV_HPEL_BILIN || v->mv_mode == MV_PMODE_1MV_HPEL); + status = bitplane_decoding(v->forward_mb_plane, &v->fmb_is_raw, v); + if (status < 0) + return -1; + av_log(v->s.avctx, AV_LOG_DEBUG, "MB Forward Type plane encoding: " + "Imode: %i, Invert: %i\n", status>>1, status&1); + mbmodetab = get_bits(gb, 3); + if (v->mv_mode == MV_PMODE_MIXED_MV) + v->mbmode_vlc = &ff_vc1_if_mmv_mbmode_vlc[mbmodetab]; + else + v->mbmode_vlc = &ff_vc1_if_1mv_mbmode_vlc[mbmodetab]; + imvtab = get_bits(gb, 3); + v->imv_vlc = &ff_vc1_2ref_mvdata_vlc[imvtab]; + icbptab = get_bits(gb, 3); + v->cbpcy_vlc = &ff_vc1_icbpcy_vlc[icbptab]; + if (v->mv_mode == MV_PMODE_MIXED_MV) { + fourmvbptab = get_bits(gb, 2); + v->fourmvbp_vlc = &ff_vc1_4mv_block_pattern_vlc[fourmvbptab]; + } + v->numref = 1; // interlaced field B pictures are always 2-ref + } else { + v->mv_mode = get_bits1(gb) ? MV_PMODE_1MV : MV_PMODE_1MV_HPEL_BILIN; + v->qs_last = v->s.quarter_sample; + v->s.quarter_sample = (v->mv_mode == MV_PMODE_1MV); + v->s.mspel = v->s.quarter_sample; + status = bitplane_decoding(v->direct_mb_plane, &v->dmb_is_raw, v); + if (status < 0) + return -1; + av_log(v->s.avctx, AV_LOG_DEBUG, "MB Direct Type plane encoding: " + "Imode: %i, Invert: %i\n", status>>1, status&1); + status = bitplane_decoding(v->s.mbskip_table, &v->skip_is_raw, v); + if (status < 0) + return -1; + av_log(v->s.avctx, AV_LOG_DEBUG, "MB Skip plane encoding: " + "Imode: %i, Invert: %i\n", status>>1, status&1); + v->s.mv_table_index = get_bits(gb, 2); + v->cbpcy_vlc = &ff_vc1_cbpcy_p_vlc[get_bits(gb, 2)]; + } if (v->dquant) { diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c index 095f08011b..0461e50f24 100644 --- a/libavcodec/vc1dec.c +++ b/libavcodec/vc1dec.c @@ -1,5 +1,6 @@ /* * VC-1 and WMV3 decoder + * Copyright (c) 2011 Mashiat Sarker Shakkhar * Copyright (c) 2006-2007 Konstantin Shishkov * Partly based on vc9.c (c) 2005 Anonymous, Alex Beregszaszi, Michael Niedermayer * @@ -48,11 +49,19 @@ static const uint16_t vlc_offs[] = { - 0, 520, 552, 616, 1128, 1160, 1224, 1740, 1772, 1836, 1900, 2436, - 2986, 3050, 3610, 4154, 4218, 4746, 5326, 5390, 5902, 6554, 7658, 8620, - 9262, 10202, 10756, 11310, 12228, 15078 + 0, 520, 552, 616, 1128, 1160, 1224, 1740, 1772, 1836, 1900, 2436, + 2986, 3050, 3610, 4154, 4218, 4746, 5326, 5390, 5902, 6554, 7658, 8342, + 9304, 9988, 10630, 11234, 12174, 13006, 13560, 14232, 14786, 15432, 16350, 17522, + 20372, 21818, 22330, 22394, 23166, 23678, 23742, 24820, 25332, 25396, 26460, 26980, + 27048, 27592, 27600, 27608, 27616, 27624, 28224, 28258, 28290, 28802, 28834, 28866, + 29378, 29412, 29444, 29960, 29994, 30026, 30538, 30572, 30604, 31120, 31154, 31186, + 31714, 31746, 31778, 32306, 32340, 32372 }; +// offset tables for interlaced picture MVDATA decoding +static const int offset_table1[9] = { 0, 1, 2, 4, 8, 16, 32, 64, 128}; +static const int offset_table2[9] = { 0, 1, 3, 7, 15, 31, 63, 127, 255}; + /** * Init VC-1 specific tables and VC1Context members * @param v The VC1Context to initialize @@ -62,7 +71,7 @@ static int vc1_init_common(VC1Context *v) { static int done = 0; int i = 0; - static VLC_TYPE vlc_table[15078][2]; + static VLC_TYPE vlc_table[32372][2]; v->hrd_rate = v->hrd_buffer = NULL; @@ -118,11 +127,64 @@ static int vc1_init_common(VC1Context *v) ff_vc1_mv_diff_codes[i], 2, 2, INIT_VLC_USE_NEW_STATIC); } for(i=0; i<8; i++){ - ff_vc1_ac_coeff_table[i].table = &vlc_table[vlc_offs[i+21]]; - ff_vc1_ac_coeff_table[i].table_allocated = vlc_offs[i+22] - vlc_offs[i+21]; + ff_vc1_ac_coeff_table[i].table = &vlc_table[vlc_offs[i*2+21]]; + ff_vc1_ac_coeff_table[i].table_allocated = vlc_offs[i*2+22] - vlc_offs[i*2+21]; init_vlc(&ff_vc1_ac_coeff_table[i], AC_VLC_BITS, vc1_ac_sizes[i], &vc1_ac_tables[i][0][1], 8, 4, &vc1_ac_tables[i][0][0], 8, 4, INIT_VLC_USE_NEW_STATIC); + /* initialize interlaced MVDATA tables (2-Ref) */ + ff_vc1_2ref_mvdata_vlc[i].table = &vlc_table[vlc_offs[i*2+22]]; + ff_vc1_2ref_mvdata_vlc[i].table_allocated = vlc_offs[i*2+23] - vlc_offs[i*2+22]; + init_vlc(&ff_vc1_2ref_mvdata_vlc[i], VC1_2REF_MVDATA_VLC_BITS, 126, + ff_vc1_2ref_mvdata_bits[i], 1, 1, + ff_vc1_2ref_mvdata_codes[i], 4, 4, INIT_VLC_USE_NEW_STATIC); + } + for (i=0; i<4; i++) { + /* initialize 4MV MBMODE VLC tables for interlaced frame P picture */ + ff_vc1_intfr_4mv_mbmode_vlc[i].table = &vlc_table[vlc_offs[i*3+37]]; + ff_vc1_intfr_4mv_mbmode_vlc[i].table_allocated = vlc_offs[i*3+38] - vlc_offs[i*3+37]; + init_vlc(&ff_vc1_intfr_4mv_mbmode_vlc[i], VC1_INTFR_4MV_MBMODE_VLC_BITS, 15, + ff_vc1_intfr_4mv_mbmode_bits[i], 1, 1, + ff_vc1_intfr_4mv_mbmode_codes[i], 2, 2, INIT_VLC_USE_NEW_STATIC); + /* initialize NON-4MV MBMODE VLC tables for the same */ + ff_vc1_intfr_non4mv_mbmode_vlc[i].table = &vlc_table[vlc_offs[i*3+38]]; + ff_vc1_intfr_non4mv_mbmode_vlc[i].table_allocated = vlc_offs[i*3+39] - vlc_offs[i*3+38]; + init_vlc(&ff_vc1_intfr_non4mv_mbmode_vlc[i], VC1_INTFR_NON4MV_MBMODE_VLC_BITS, 9, + ff_vc1_intfr_non4mv_mbmode_bits[i], 1, 1, + ff_vc1_intfr_non4mv_mbmode_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC); + /* initialize interlaced MVDATA tables (1-Ref) */ + ff_vc1_1ref_mvdata_vlc[i].table = &vlc_table[vlc_offs[i*3+39]]; + ff_vc1_1ref_mvdata_vlc[i].table_allocated = vlc_offs[i*3+40] - vlc_offs[i*3+39]; + init_vlc(&ff_vc1_1ref_mvdata_vlc[i], VC1_1REF_MVDATA_VLC_BITS, 72, + ff_vc1_1ref_mvdata_bits[i], 1, 1, + ff_vc1_1ref_mvdata_codes[i], 4, 4, INIT_VLC_USE_NEW_STATIC); + } + for (i=0; i<4; i++) { + /* Initialize 2MV Block pattern VLC tables */ + ff_vc1_2mv_block_pattern_vlc[i].table = &vlc_table[vlc_offs[i+49]]; + ff_vc1_2mv_block_pattern_vlc[i].table_allocated = vlc_offs[i+50] - vlc_offs[i+49]; + init_vlc(&ff_vc1_2mv_block_pattern_vlc[i], VC1_2MV_BLOCK_PATTERN_VLC_BITS, 4, + ff_vc1_2mv_block_pattern_bits[i], 1, 1, + ff_vc1_2mv_block_pattern_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC); + } + for (i=0; i<8; i++) { + /* Initialize interlaced CBPCY VLC tables (Table 124 - Table 131) */ + ff_vc1_icbpcy_vlc[i].table = &vlc_table[vlc_offs[i*3+53]]; + ff_vc1_icbpcy_vlc[i].table_allocated = vlc_offs[i*3+54] - vlc_offs[i*3+53]; + init_vlc(&ff_vc1_icbpcy_vlc[i], VC1_ICBPCY_VLC_BITS, 63, + ff_vc1_icbpcy_p_bits[i], 1, 1, + ff_vc1_icbpcy_p_codes[i], 2, 2, INIT_VLC_USE_NEW_STATIC); + /* Initialize interlaced field picture MBMODE VLC tables */ + ff_vc1_if_mmv_mbmode_vlc[i].table = &vlc_table[vlc_offs[i*3+54]]; + ff_vc1_if_mmv_mbmode_vlc[i].table_allocated = vlc_offs[i*3+55] - vlc_offs[i*3+54]; + init_vlc(&ff_vc1_if_mmv_mbmode_vlc[i], VC1_IF_MMV_MBMODE_VLC_BITS, 8, + ff_vc1_if_mmv_mbmode_bits[i], 1, 1, + ff_vc1_if_mmv_mbmode_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC); + ff_vc1_if_1mv_mbmode_vlc[i].table = &vlc_table[vlc_offs[i*3+55]]; + ff_vc1_if_1mv_mbmode_vlc[i].table_allocated = vlc_offs[i*3+56] - vlc_offs[i*3+55]; + init_vlc(&ff_vc1_if_1mv_mbmode_vlc[i], VC1_IF_1MV_MBMODE_VLC_BITS, 6, + ff_vc1_if_1mv_mbmode_bits[i], 1, 1, + ff_vc1_if_1mv_mbmode_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC); } done = 1; } @@ -162,6 +224,9 @@ enum Imode { static void vc1_put_signed_blocks_clamped(VC1Context *v) { MpegEncContext *s = &v->s; + int topleft_mb_pos, top_mb_pos; + int stride_y, fieldtx; + int v_dist; /* The put pixels loop is always one MB row behind the decoding loop, * because we can only put pixels when overlap filtering is done, and @@ -172,18 +237,22 @@ static void vc1_put_signed_blocks_clamped(VC1Context *v) * of the right MB edge, we need the next MB present. */ if (!s->first_slice_line) { if (s->mb_x) { + topleft_mb_pos = (s->mb_y - 1) * s->mb_stride + s->mb_x - 1; + fieldtx = v->fieldtx_plane[topleft_mb_pos]; + stride_y = (s->linesize) << fieldtx; + v_dist = (16 - fieldtx) >> (fieldtx == 0); s->dsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][0], s->dest[0] - 16 * s->linesize - 16, - s->linesize); + stride_y); s->dsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][1], s->dest[0] - 16 * s->linesize - 8, - s->linesize); + stride_y); s->dsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][2], - s->dest[0] - 8 * s->linesize - 16, - s->linesize); + s->dest[0] - v_dist * s->linesize - 16, + stride_y); s->dsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][3], - s->dest[0] - 8 * s->linesize - 8, - s->linesize); + s->dest[0] - v_dist * s->linesize - 8, + stride_y); s->dsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][4], s->dest[1] - 8 * s->uvlinesize - 8, s->uvlinesize); @@ -192,18 +261,22 @@ static void vc1_put_signed_blocks_clamped(VC1Context *v) s->uvlinesize); } if (s->mb_x == s->mb_width - 1) { + top_mb_pos = (s->mb_y - 1) * s->mb_stride + s->mb_x; + fieldtx = v->fieldtx_plane[top_mb_pos]; + stride_y = s->linesize << fieldtx; + v_dist = fieldtx ? 15 : 8; s->dsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][0], s->dest[0] - 16 * s->linesize, - s->linesize); + stride_y); s->dsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][1], s->dest[0] - 16 * s->linesize + 8, - s->linesize); + stride_y); s->dsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][2], - s->dest[0] - 8 * s->linesize, - s->linesize); + s->dest[0] - v_dist * s->linesize, + stride_y); s->dsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][3], - s->dest[0] - 8 * s->linesize + 8, - s->linesize); + s->dest[0] - v_dist * s->linesize + 8, + stride_y); s->dsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][4], s->dest[1] - 8 * s->uvlinesize, s->uvlinesize); @@ -406,33 +479,61 @@ static void vc1_mc_1mv(VC1Context *v, int dir) DSPContext *dsp = &v->s.dsp; uint8_t *srcY, *srcU, *srcV; int dxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y; - - if(!v->s.last_picture.f.data[0])return; + int off, off_uv; + int v_edge_pos = s->v_edge_pos >> v->field_mode; + if (!v->field_mode && !v->s.last_picture.f.data[0]) + return; mx = s->mv[dir][0][0]; my = s->mv[dir][0][1]; // store motion vectors for further use in B frames if(s->pict_type == AV_PICTURE_TYPE_P) { - s->current_picture.f.motion_val[1][s->block_index[0]][0] = mx; - s->current_picture.f.motion_val[1][s->block_index[0]][1] = my; + s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][0] = mx; + s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][1] = my; } + uvmx = (mx + ((mx & 3) == 3)) >> 1; uvmy = (my + ((my & 3) == 3)) >> 1; v->luma_mv[s->mb_x][0] = uvmx; v->luma_mv[s->mb_x][1] = uvmy; - if(v->fastuvmc) { + + if (v->field_mode && + v->cur_field_type != v->ref_field_type[dir]) { + my = my - 2 + 4 * v->cur_field_type; + uvmy = uvmy - 2 + 4 * v->cur_field_type; + } + + if(v->fastuvmc && (v->fcm != 1)) { // fastuvmc shall be ignored for interlaced frame picture uvmx = uvmx + ((uvmx<0)?(uvmx&1):-(uvmx&1)); uvmy = uvmy + ((uvmy<0)?(uvmy&1):-(uvmy&1)); } - if(!dir) { - srcY = s->last_picture.f.data[0]; - srcU = s->last_picture.f.data[1]; - srcV = s->last_picture.f.data[2]; + 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]; + } + } 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]; + 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]; + } } src_x = s->mb_x * 16 + (mx >> 2); @@ -456,6 +557,12 @@ static void vc1_mc_1mv(VC1Context *v, int dir) srcU += uvsrc_y * s->uvlinesize + uvsrc_x; srcV += uvsrc_y * s->uvlinesize + uvsrc_x; + if (v->field_mode && v->ref_field_type[dir]) { + srcY += s->current_picture_ptr->f.linesize[0]; + srcU += s->current_picture_ptr->f.linesize[1]; + srcV += s->current_picture_ptr->f.linesize[2]; + } + /* for grayscale we should not try to read from unknown area */ if(s->flags & CODEC_FLAG_GRAY) { srcU = s->edge_emu_buffer + 18 * s->linesize; @@ -464,17 +571,17 @@ static void vc1_mc_1mv(VC1Context *v, int dir) if(v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP) || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx&3) - 16 - s->mspel*3 - || (unsigned)(src_y - s->mspel) > s->v_edge_pos - (my&3) - 16 - s->mspel*3){ + || (unsigned)(src_y - s->mspel) > v_edge_pos - (my&3) - 16 - s->mspel*3){ uint8_t *uvbuf= s->edge_emu_buffer + 19 * s->linesize; srcY -= s->mspel * (1 + s->linesize); s->dsp.emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, 17+s->mspel*2, 17+s->mspel*2, - src_x - s->mspel, src_y - s->mspel, s->h_edge_pos, s->v_edge_pos); + src_x - s->mspel, src_y - s->mspel, s->h_edge_pos, v_edge_pos); srcY = s->edge_emu_buffer; s->dsp.emulated_edge_mc(uvbuf , srcU, s->uvlinesize, 8+1, 8+1, - uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1); + uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, v_edge_pos >> 1); s->dsp.emulated_edge_mc(uvbuf + 16, srcV, s->uvlinesize, 8+1, 8+1, - uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1); + uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, v_edge_pos >> 1); srcU = uvbuf; srcV = uvbuf + 16; /* if we deal with range reduction we need to scale source blocks */ @@ -520,20 +627,26 @@ 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; + } if(s->mspel) { dxy = ((my & 3) << 2) | (mx & 3); - 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); + 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); srcY += s->linesize * 8; - 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); + 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); } else { // hpel mc - always used for luma dxy = (my & 2) | ((mx & 2) >> 1); - if(!v->rnd) - dsp->put_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16); + dsp->put_pixels_tab[0][dxy](s->dest[0] + off, srcY, s->linesize, 16); else - dsp->put_no_rnd_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16); + dsp->put_no_rnd_pixels_tab[0][dxy](s->dest[0] + off, srcY, s->linesize, 16); } if(s->flags & CODEC_FLAG_GRAY) return; @@ -541,85 +654,11 @@ static void vc1_mc_1mv(VC1Context *v, int dir) uvmx = (uvmx&3)<<1; uvmy = (uvmy&3)<<1; if(!v->rnd){ - dsp->put_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy); - dsp->put_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy); + dsp->put_h264_chroma_pixels_tab[0](s->dest[1] + off_uv, srcU, s->uvlinesize, 8, uvmx, uvmy); + dsp->put_h264_chroma_pixels_tab[0](s->dest[2] + off_uv, srcV, s->uvlinesize, 8, uvmx, uvmy); }else{ - 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); - } -} - -/** Do motion compensation for 4-MV macroblock - luminance block - */ -static void vc1_mc_4mv_luma(VC1Context *v, int n) -{ - MpegEncContext *s = &v->s; - DSPContext *dsp = &v->s.dsp; - uint8_t *srcY; - int dxy, mx, my, src_x, src_y; - int off; - - if(!v->s.last_picture.f.data[0])return; - mx = s->mv[0][n][0]; - my = s->mv[0][n][1]; - srcY = s->last_picture.f.data[0]; - - off = s->linesize * 4 * (n&2) + (n&1) * 8; - - src_x = s->mb_x * 16 + (n&1) * 8 + (mx >> 2); - src_y = s->mb_y * 16 + (n&2) * 4 + (my >> 2); - - if(v->profile != PROFILE_ADVANCED){ - src_x = av_clip( src_x, -16, s->mb_width * 16); - src_y = av_clip( src_y, -16, s->mb_height * 16); - }else{ - src_x = av_clip( src_x, -17, s->avctx->coded_width); - src_y = av_clip( src_y, -18, s->avctx->coded_height + 1); - } - - srcY += src_y * s->linesize + src_x; - - if(v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP) - || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx&3) - 8 - s->mspel*2 - || (unsigned)(src_y - s->mspel) > s->v_edge_pos - (my&3) - 8 - s->mspel*2){ - srcY -= s->mspel * (1 + s->linesize); - s->dsp.emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, 9+s->mspel*2, 9+s->mspel*2, - src_x - s->mspel, src_y - s->mspel, s->h_edge_pos, s->v_edge_pos); - srcY = s->edge_emu_buffer; - /* if we deal with range reduction we need to scale source blocks */ - if(v->rangeredfrm) { - int i, j; - uint8_t *src; - - src = srcY; - for(j = 0; j < 9 + s->mspel*2; j++) { - for(i = 0; i < 9 + s->mspel*2; i++) src[i] = ((src[i] - 128) >> 1) + 128; - src += s->linesize; - } - } - /* if we deal with intensity compensation we need to scale source blocks */ - if(v->mv_mode == MV_PMODE_INTENSITY_COMP) { - int i, j; - uint8_t *src; - - src = srcY; - for(j = 0; j < 9 + s->mspel*2; j++) { - for(i = 0; i < 9 + s->mspel*2; i++) src[i] = v->luty[src[i]]; - src += s->linesize; - } - } - srcY += s->mspel * (1 + s->linesize); - } - - 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); - } else { // hpel mc - always used for luma - dxy = (my & 2) | ((mx & 2) >> 1); - if(!v->rnd) - dsp->put_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize, 8); - else - dsp->put_no_rnd_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize, 8); + 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); } } @@ -634,75 +673,268 @@ static inline int median4(int a, int b, int c, int d) } } +/** Do motion compensation for 4-MV macroblock - luminance block + */ +static void vc1_mc_4mv_luma(VC1Context *v, int n, int dir) +{ + MpegEncContext *s = &v->s; + DSPContext *dsp = &v->s.dsp; + uint8_t *srcY; + int dxy, mx, my, src_x, src_y; + int off; + int fieldmv = (v->fcm == 1) ? v->blk_mv_type[s->block_index[n]] : 0; + int v_edge_pos = s->v_edge_pos >> v->field_mode; + if(!v->field_mode && !v->s.last_picture.f.data[0])return; + mx = s->mv[dir][n][0]; + 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]; + } else + srcY = s->last_picture.f.data[0]; + } else + srcY = s->next_picture.f.data[0]; + + if (v->field_mode) { + if (v->cur_field_type != v->ref_field_type[dir]) + my = my - 2 + 4 * v->cur_field_type; + } + + if (s->pict_type == AV_PICTURE_TYPE_P && n == 3 && v->field_mode) { + int same_count = 0, opp_count = 0, k; + int chosen_mv[2][4][2], f; + int tx, ty; + for (k = 0; k < 4; k++) { + f = v->mv_f[0][s->block_index[k] + v->blocks_off]; + chosen_mv[f][f ? opp_count : same_count][0] = s->mv[0][k][0]; + chosen_mv[f][f ? opp_count : same_count][1] = s->mv[0][k][1]; + opp_count += f; + same_count += 1 - f; + } + f = opp_count > same_count; + switch (f ? opp_count : same_count) { + case 4: + tx = median4(chosen_mv[f][0][0], chosen_mv[f][1][0], chosen_mv[f][2][0], chosen_mv[f][3][0]); + ty = median4(chosen_mv[f][0][1], chosen_mv[f][1][1], chosen_mv[f][2][1], chosen_mv[f][3][1]); + break; + case 3: + tx = mid_pred(chosen_mv[f][0][0], chosen_mv[f][1][0], chosen_mv[f][2][0]); + ty = mid_pred(chosen_mv[f][0][1], chosen_mv[f][1][1], chosen_mv[f][2][1]); + break; + case 2: + tx = (chosen_mv[f][0][0] + chosen_mv[f][1][0]) / 2; + ty = (chosen_mv[f][0][1] + chosen_mv[f][1][1]) / 2; + break; + } + s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][0] = tx; + s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][1] = ty; + for (k = 0; k < 4; k++) v->mv_f[1][s->block_index[k] + v->blocks_off] = f; + } + + if (v->fcm == 1) { // not sure if needed for other types of picture + int qx, qy; + int width = s->avctx->coded_width; + int height = s->avctx->coded_height >> 1; + qx = (s->mb_x * 16) + (mx >> 2); + qy = (s->mb_y * 8) + (my >> 3); + + if (qx < -17) + mx -= 4 * (qx + 17); + else if (qx > width) + mx -= 4 * (qx - width); + if (qy < -18) + my -= 8 * (qy + 18); + else if (qy > height + 1) + my -= 8 * (qy - height - 1); + } + + if ((v->fcm == 1) && fieldmv) + 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) + src_y = s->mb_y * 16 + (n&2) * 4 + (my >> 2); + else + src_y = s->mb_y * 16 + ((n > 1) ? 1 : 0) + (my >> 2); + + if(v->profile != PROFILE_ADVANCED){ + src_x = av_clip( src_x, -16, s->mb_width * 16); + src_y = av_clip( src_y, -16, s->mb_height * 16); + }else{ + src_x = av_clip( src_x, -17, s->avctx->coded_width); + if (v->fcm == 1) { + if (src_y & 1) + src_y = av_clip( src_y, -17, s->avctx->coded_height + 1); + else + src_y = av_clip( src_y, -18, s->avctx->coded_height); + } else { + src_y = av_clip( src_y, -18, s->avctx->coded_height + 1); + } + } + + srcY += src_y * s->linesize + src_x; + if (v->field_mode && v->ref_field_type[dir]) + srcY += s->current_picture_ptr->f.linesize[0]; + + if (fieldmv && !(src_y & 1)) + v_edge_pos--; + if (fieldmv && (src_y & 1) && src_y < 4) + src_y--; + if(v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP) + || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx&3) - 8 - s->mspel*2 + || (unsigned)(src_y - (s->mspel< v_edge_pos - (my&3) - ((8 + s->mspel*2)<mspel * (1 + (s->linesize << fieldmv)); + /* check emulate edge stride and offset */ + s->dsp.emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, 9+s->mspel*2, (9+s->mspel*2) << fieldmv, src_x - s->mspel, + src_y - (s->mspel << fieldmv), s->h_edge_pos, v_edge_pos); + srcY = s->edge_emu_buffer; + /* if we deal with range reduction we need to scale source blocks */ + if(v->rangeredfrm) { + int i, j; + uint8_t *src; + + src = srcY; + for(j = 0; j < 9 + s->mspel*2; j++) { + for(i = 0; i < 9 + s->mspel*2; i++) src[i] = ((src[i] - 128) >> 1) + 128; + src += s->linesize << fieldmv; + } + } + /* if we deal with intensity compensation we need to scale source blocks */ + if(v->mv_mode == MV_PMODE_INTENSITY_COMP) { + int i, j; + uint8_t *src; + + src = srcY; + for(j = 0; j < 9 + s->mspel*2; j++) { + for(i = 0; i < 9 + s->mspel*2; i++) src[i] = v->luty[src[i]]; + src += s->linesize << fieldmv; + } + } + srcY += s->mspel * (1 + (s->linesize << fieldmv)); + } + + if(s->mspel) { + dxy = ((my & 3) << 2) | (mx & 3); + v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + off, srcY, s->linesize << fieldmv, v->rnd); + } else { // hpel mc - always used for luma + dxy = (my & 2) | ((mx & 2) >> 1); + if(!v->rnd) + dsp->put_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize, 8); + else + dsp->put_no_rnd_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize, 8); + } +} + +static av_always_inline int get_chroma_mv(int *mvx, int *mvy, int *a, int flag, int *tx, int *ty) +{ + int idx, i; + static const int count[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4}; + idx = ((a[3] != flag) << 3) | ((a[2] != flag) << 2) | ((a[1] != flag) << 1) | (a[0] != flag); + if(!idx) { + *tx = median4(mvx[0], mvx[1], mvx[2], mvx[3]); + *ty = median4(mvy[0], mvy[1], mvy[2], mvy[3]); + return 4; + } else if(count[idx] == 1) { + switch(idx) { + case 0x1: + *tx = mid_pred(mvx[1], mvx[2], mvx[3]); + *ty = mid_pred(mvy[1], mvy[2], mvy[3]); + return 3; + case 0x2: + *tx = mid_pred(mvx[0], mvx[2], mvx[3]); + *ty = mid_pred(mvy[0], mvy[2], mvy[3]); + return 3; + case 0x4: + *tx = mid_pred(mvx[0], mvx[1], mvx[3]); + *ty = mid_pred(mvy[0], mvy[1], mvy[3]); + return 3; + case 0x8: + *tx = mid_pred(mvx[0], mvx[1], mvx[2]); + *ty = mid_pred(mvy[0], mvy[1], mvy[2]); + return 3; + } + } else if(count[idx] == 2) { + int t1 = 0, t2 = 0; + for (i = 0; i < 3; i++) + if (!a[i]) { + t1 = i; + break; + } + for (i = t1 + 1; i < 4; i++) + if (!a[i]) { + t2 = i; + break; + } + *tx = (mvx[t1] + mvx[t2]) / 2; + *ty = (mvy[t1] + mvy[t2]) / 2; + return 2; + } else { + return 0; + } + return -1; +} /** Do motion compensation for 4-MV macroblock - both chroma blocks */ -static void vc1_mc_4mv_chroma(VC1Context *v) +static void vc1_mc_4mv_chroma(VC1Context *v, int dir) { MpegEncContext *s = &v->s; DSPContext *dsp = &v->s.dsp; uint8_t *srcU, *srcV; int uvmx, uvmy, uvsrc_x, uvsrc_y; - int i, idx, tx = 0, ty = 0; - int mvx[4], mvy[4], intra[4]; - static const int count[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4}; + 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 v_edge_pos = s->v_edge_pos >> v->field_mode; - if(!v->s.last_picture.f.data[0])return; + if(!v->field_mode && !v->s.last_picture.f.data[0])return; if(s->flags & CODEC_FLAG_GRAY) return; - for(i = 0; i < 4; i++) { - mvx[i] = s->mv[0][i][0]; - mvy[i] = s->mv[0][i][1]; - intra[i] = v->mb_type[0][s->block_index[i]]; + for(k = 0; k < 4; k++) { + mvx[k] = s->mv[dir][k][0]; + mvy[k] = s->mv[dir][k][1]; + intra[k] = v->mb_type[0][s->block_index[k]]; + if (v->field_mode) + mv_f[k] = v->mv_f[dir][s->block_index[k] + v->blocks_off]; } /* calculate chroma MV vector from four luma MVs */ - idx = (intra[3] << 3) | (intra[2] << 2) | (intra[1] << 1) | intra[0]; - if(!idx) { // all blocks are inter - tx = median4(mvx[0], mvx[1], mvx[2], mvx[3]); - ty = median4(mvy[0], mvy[1], mvy[2], mvy[3]); - } else if(count[idx] == 1) { // 3 inter blocks - switch(idx) { - case 0x1: - tx = mid_pred(mvx[1], mvx[2], mvx[3]); - ty = mid_pred(mvy[1], mvy[2], mvy[3]); - break; - case 0x2: - tx = mid_pred(mvx[0], mvx[2], mvx[3]); - ty = mid_pred(mvy[0], mvy[2], mvy[3]); - break; - case 0x4: - tx = mid_pred(mvx[0], mvx[1], mvx[3]); - ty = mid_pred(mvy[0], mvy[1], mvy[3]); - break; - case 0x8: - tx = mid_pred(mvx[0], mvx[1], mvx[2]); - ty = mid_pred(mvy[0], mvy[1], mvy[2]); - break; + if (!v->field_mode || (v->field_mode && !v->numref)) { + valid_count = get_chroma_mv(mvx, mvy, intra, 0, &tx, &ty); + if (!valid_count) { + v->luma_mv[s->mb_x][0] = v->luma_mv[s->mb_x][1] = 0; + return; //no need to do MC for intra blocks } - } else if(count[idx] == 2) { - int t1 = 0, t2 = 0; - for(i=0; i<3;i++) if(!intra[i]) {t1 = i; break;} - for(i= t1+1; i<4; i++)if(!intra[i]) {t2 = i; break;} - tx = (mvx[t1] + mvx[t2]) / 2; - ty = (mvy[t1] + mvy[t2]) / 2; } else { - s->current_picture.f.motion_val[1][s->block_index[0]][0] = 0; - s->current_picture.f.motion_val[1][s->block_index[0]][1] = 0; - v->luma_mv[s->mb_x][0] = v->luma_mv[s->mb_x][1] = 0; - return; //no need to do MC for inter blocks + int dominant = 0; + if (mv_f[0] + mv_f[1] + mv_f[2] + mv_f[3] > 2) + dominant = 1; + valid_count = get_chroma_mv(mvx, mvy, mv_f, dominant, &tx, &ty); + if (dominant) + chroma_ref_type = !v->cur_field_type; } - - s->current_picture.f.motion_val[1][s->block_index[0]][0] = tx; - s->current_picture.f.motion_val[1][s->block_index[0]][1] = ty; uvmx = (tx + ((tx&3) == 3)) >> 1; uvmy = (ty + ((ty&3) == 3)) >> 1; + v->luma_mv[s->mb_x][0] = uvmx; v->luma_mv[s->mb_x][1] = uvmy; + if(v->fastuvmc) { uvmx = uvmx + ((uvmx<0)?(uvmx&1):-(uvmx&1)); uvmy = uvmy + ((uvmy<0)?(uvmy&1):-(uvmy&1)); } + // Field conversion bias + if (v->cur_field_type != chroma_ref_type) + uvmy += 2 - 4 * chroma_ref_type; uvsrc_x = s->mb_x * 8 + (uvmx >> 2); uvsrc_y = s->mb_y * 8 + (uvmy >> 2); @@ -715,15 +947,39 @@ static void vc1_mc_4mv_chroma(VC1Context *v) uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1); } - 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; + 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; + } 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; + } + } 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; + } + } 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; + } + + if (v->field_mode) { + if (chroma_ref_type) { + 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; + } + if(v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP) || (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 9 - || (unsigned)uvsrc_y > (s->v_edge_pos >> 1) - 9){ + || (unsigned)uvsrc_y > (v_edge_pos >> 1) - 9){ s->dsp.emulated_edge_mc(s->edge_emu_buffer , srcU, s->uvlinesize, 8+1, 8+1, - uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1); + uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, v_edge_pos >> 1); s->dsp.emulated_edge_mc(s->edge_emu_buffer + 16, srcV, s->uvlinesize, 8+1, 8+1, - uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1); + uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, v_edge_pos >> 1); srcU = s->edge_emu_buffer; srcV = s->edge_emu_buffer + 16; @@ -763,11 +1019,89 @@ static void vc1_mc_4mv_chroma(VC1Context *v) uvmx = (uvmx&3)<<1; uvmy = (uvmy&3)<<1; if(!v->rnd){ - dsp->put_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy); - dsp->put_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy); + dsp->put_h264_chroma_pixels_tab[0](s->dest[1] + off, srcU, s->uvlinesize, 8, uvmx, uvmy); + dsp->put_h264_chroma_pixels_tab[0](s->dest[2] + off, srcV, s->uvlinesize, 8, uvmx, uvmy); }else{ - 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); + 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); + } +} + +/** Do motion compensation for 4-MV field chroma macroblock (both U and V) + */ +static void vc1_mc_4mv_chroma4(VC1Context *v) +{ + MpegEncContext *s = &v->s; + DSPContext *dsp = &v->s.dsp; + uint8_t *srcU, *srcV; + int uvsrc_x, uvsrc_y; + int uvmx_field[4], uvmy_field[4]; + int i, off, tx, ty; + int fieldmv = v->blk_mv_type[s->block_index[0]]; + static const int s_rndtblfield[16] = {0, 0, 1, 2, 4, 4, 5, 6, 2, 2, 3, 8, 6, 6, 7, 12}; + int v_dist = fieldmv ? 1 : 4; // vertical offset for lower sub-blocks + int v_edge_pos = s->v_edge_pos >> 1; + + if (!v->s.last_picture.f.data[0]) return; + if (s->flags & CODEC_FLAG_GRAY) return; + + for (i = 0; i < 4; i++) { + tx = s->mv[0][i][0]; + uvmx_field[i] = (tx + ((tx & 3) == 3)) >> 1; + ty = s->mv[0][i][1]; + if (fieldmv) + uvmy_field[i] = (ty >> 4) * 8 + s_rndtblfield[ty & 0xF]; + else + uvmy_field[i] = (ty + ((ty & 3) == 3)) >> 1; + } + + for (i = 0; i < 4; i++) { + off = (i & 1) * 4 + ((i & 2) ? v_dist * s->uvlinesize : 0); + uvsrc_x = s->mb_x * 8 + (i & 1) * 4 + (uvmx_field[i] >> 2); + uvsrc_y = s->mb_y * 8 + ((i & 2) ? v_dist : 0) + (uvmy_field[i] >> 2); + // FIXME: implement proper pull-back (see vc1cropmv.c, vc1CROPMV_ChromaPullBack()) + uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width >> 1); + uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1); + 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; + uvmx_field[i] = (uvmx_field[i] & 3) << 1; + uvmy_field[i] = (uvmy_field[i] & 3) << 1; + + if (fieldmv && !(uvsrc_y & 1)) + v_edge_pos--; + if (fieldmv && (uvsrc_y & 1) && uvsrc_y < 2) + uvsrc_y--; + if((v->mv_mode == MV_PMODE_INTENSITY_COMP) + || (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 5 + || (unsigned)uvsrc_y > v_edge_pos - (5 << fieldmv)){ + s->dsp.emulated_edge_mc(s->edge_emu_buffer, srcU, s->uvlinesize, 5, (5 << fieldmv), uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, v_edge_pos); + s->dsp.emulated_edge_mc(s->edge_emu_buffer + 16, srcV, s->uvlinesize, 5, (5 << fieldmv), uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, v_edge_pos); + srcU = s->edge_emu_buffer; + srcV = s->edge_emu_buffer + 16; + + /* if we deal with intensity compensation we need to scale source blocks */ + if(v->mv_mode == MV_PMODE_INTENSITY_COMP) { + int i, j; + uint8_t *src, *src2; + + src = srcU; src2 = srcV; + for(j = 0; j < 5; j++) { + for(i = 0; i < 5; i++) { + src[i] = v->lutuv[src[i]]; + src2[i] = v->lutuv[src2[i]]; + } + src += s->uvlinesize << 1; + src2 += s->uvlinesize << 1; + } + } + } + if (!v->rnd) { + dsp->put_h264_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]); + dsp->put_h264_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]); + } else { + v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]); + v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]); + } } } @@ -865,16 +1199,249 @@ static void vc1_mc_4mv_chroma(VC1Context *v) _dmv_y = (sign ^ ((val>>1) + offset_table[index1])) - sign; \ } +static av_always_inline void get_mvdata_interlaced(VC1Context *v, int *dmv_x, int *dmv_y, int *pred_flag) +{ + int index, index1; + int extend_x = 0, extend_y = 0; + GetBitContext *gb = &v->s.gb; + int bits, esc; + int val, sign; + const int* offs_tab; + + if (v->numref) { + bits = VC1_2REF_MVDATA_VLC_BITS; + esc = 125; + } else { + bits = VC1_1REF_MVDATA_VLC_BITS; + esc = 71; + } + switch (v->dmvrange) { + case 1: + extend_x = 1; + break; + case 2: + extend_y = 1; + break; + case 3: + extend_x = extend_y = 1; + break; + } + index = get_vlc2(gb, v->imv_vlc->table, bits, 3); + if (index == esc) { + *dmv_x = get_bits(gb, v->k_x); + *dmv_y = get_bits(gb, v->k_y); + if (v->numref) { + *pred_flag = *dmv_y & 1; + *dmv_y = (*dmv_y + *pred_flag) >> 1; + } + } + else { + if (extend_x) + offs_tab = offset_table2; + else + offs_tab = offset_table1; + index1 = (index + 1) % 9; + if (index1 != 0) { + val = get_bits(gb, index1 + extend_x); + sign = 0 -(val & 1); + *dmv_x = (sign ^ ((val >> 1) + offs_tab[index1])) - sign; + } else + *dmv_x = 0; + if (extend_y) + offs_tab = offset_table2; + else + offs_tab = offset_table1; + index1 = (index + 1) / 9; + if (index1 > v->numref) { + val = get_bits(gb, (index1 + (extend_y << v->numref)) >> v->numref); + sign = 0 - (val & 1); + *dmv_y = (sign ^ ((val >> 1) + offs_tab[index1 >> v->numref])) - sign; + } else + *dmv_y = 0; + if (v->numref) + *pred_flag = index1 & 1; + } +} + +static av_always_inline int scaleforsame_x(VC1Context *v, int n /* MV */, int dir) +{ + int scaledvalue, refdist; + int scalesame1, scalesame2; + int scalezone1_x, zone1offset_x; + + if (v->s.pict_type != AV_PICTURE_TYPE_B) + refdist = v->refdist; + else + refdist = dir ? v->brfd : v->frfd; + if (refdist > 3) + refdist = 3; + scalesame1 = vc1_field_mvpred_scales[v->second_field][1][refdist]; + scalesame2 = vc1_field_mvpred_scales[v->second_field][2][refdist]; + scalezone1_x = vc1_field_mvpred_scales[v->second_field][3][refdist]; + zone1offset_x = vc1_field_mvpred_scales[v->second_field][5][refdist]; + + if (FFABS(n) > 255) + scaledvalue = n; + else { + if (FFABS(n) < scalezone1_x) + scaledvalue = (n * scalesame1) >> 8; + else { + if (n < 0) + scaledvalue = ((n * scalesame2) >> 8) - zone1offset_x; + else + scaledvalue = ((n * scalesame2) >> 8) + zone1offset_x; + } + } + return av_clip(scaledvalue, -v->range_x, v->range_x - 1); +} + +static av_always_inline int scaleforsame_y(VC1Context *v, int i, int n /* MV */, int dir) +{ + int scaledvalue, refdist; + int scalesame1, scalesame2; + int scalezone1_y, zone1offset_y; + + if (v->s.pict_type != AV_PICTURE_TYPE_B) + refdist = v->refdist; + else + refdist = dir ? v->brfd : v->frfd; + if (refdist > 3) + refdist = 3; + scalesame1 = vc1_field_mvpred_scales[v->second_field][1][refdist]; + scalesame2 = vc1_field_mvpred_scales[v->second_field][2][refdist]; + scalezone1_y = vc1_field_mvpred_scales[v->second_field][4][refdist]; + zone1offset_y = vc1_field_mvpred_scales[v->second_field][6][refdist]; + + if (FFABS(n) > 63) + scaledvalue = n; + else { + if (FFABS(n) < scalezone1_y) + scaledvalue = (n * scalesame1) >> 8; + else { + if (n < 0) + scaledvalue = ((n * scalesame2) >> 8) - zone1offset_y; + else + scaledvalue = ((n * scalesame2) >> 8) + zone1offset_y; + } + } + + if (v->cur_field_type && !v->ref_field_type[dir]) + return av_clip(scaledvalue, -v->range_y / 2 + 1, v->range_y / 2); + else + return av_clip(scaledvalue, -v->range_y / 2, v->range_y / 2 - 1); +} + +static av_always_inline int scaleforopp_x(VC1Context *v, int n /* MV */) +{ + int scalezone1_x, zone1offset_x; + int scaleopp1, scaleopp2, brfd; + int scaledvalue; + + brfd = FFMIN(v->brfd, 3); + scalezone1_x = vc1_b_field_mvpred_scales[3][brfd]; + zone1offset_x = vc1_b_field_mvpred_scales[5][brfd]; + scaleopp1 = vc1_b_field_mvpred_scales[1][brfd]; + scaleopp2 = vc1_b_field_mvpred_scales[2][brfd]; + + if (FFABS(n) > 255) + scaledvalue = n; + else { + if (FFABS(n) < scalezone1_x) + scaledvalue = (n * scaleopp1) >> 8; + else { + if (n < 0) + scaledvalue = ((n * scaleopp2) >> 8) - zone1offset_x; + else + scaledvalue = ((n * scaleopp2) >> 8) + zone1offset_x; + } + } + return av_clip(scaledvalue, -v->range_x, v->range_x - 1); +} + +static av_always_inline int scaleforopp_y(VC1Context *v, int n /* MV */, int dir) +{ + int scalezone1_y, zone1offset_y; + int scaleopp1, scaleopp2, brfd; + int scaledvalue; + + brfd = FFMIN(v->brfd, 3); + scalezone1_y = vc1_b_field_mvpred_scales[4][brfd]; + zone1offset_y = vc1_b_field_mvpred_scales[6][brfd]; + scaleopp1 = vc1_b_field_mvpred_scales[1][brfd]; + scaleopp2 = vc1_b_field_mvpred_scales[2][brfd]; + + if (FFABS(n) > 63) + scaledvalue = n; + else { + if (FFABS(n) < scalezone1_y) + scaledvalue = (n * scaleopp1) >> 8; + else { + if (n < 0) + scaledvalue = ((n * scaleopp2) >> 8) - zone1offset_y; + else + scaledvalue = ((n * scaleopp2) >> 8) + zone1offset_y; + } + } + if (v->cur_field_type && !v->ref_field_type[dir]) { + return av_clip(scaledvalue, -v->range_y / 2 + 1, v->range_y / 2); + } else { + return av_clip(scaledvalue, -v->range_y / 2, v->range_y / 2 - 1); + } +} + +static av_always_inline int scaleforsame(VC1Context *v, int i, int n /* MV */, int dim, int dir) +{ + int brfd, scalesame; + if (v->s.pict_type != AV_PICTURE_TYPE_B || v->second_field || !dir) { + if (dim) + return scaleforsame_y(v, i, n, dir); + else + return scaleforsame_x(v, n, dir); + } + brfd = FFMIN(v->brfd, 3); + scalesame = vc1_b_field_mvpred_scales[0][brfd]; + return(n * scalesame >> 8); +} + +static av_always_inline int scaleforopp(VC1Context *v, int n /* MV */, int dim, int dir) +{ + int refdist, scaleopp; + if (v->s.pict_type == AV_PICTURE_TYPE_B && !v->second_field && dir == 1) { + if (dim) + return scaleforopp_y(v, n, dir); + else + return scaleforopp_x(v, n); + } + if (v->s.pict_type != AV_PICTURE_TYPE_B) + refdist = FFMIN(v->refdist, 3); + else + refdist = dir ? v->brfd : v->frfd; + scaleopp = vc1_field_mvpred_scales[v->second_field][0][refdist]; + return(n * scaleopp >> 8); +} + /** Predict and set motion vector */ -static inline void vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y, int mv1, int r_x, int r_y, uint8_t* is_intra) +static inline void vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y, int mv1, int r_x, int r_y, uint8_t* is_intra, int pred_flag, int dir) { MpegEncContext *s = &v->s; int xy, wrap, off = 0; int16_t *A, *B, *C; int px, py; int sum; + int mixedmv_pic, num_samefield = 0, num_oppfield = 0; + int opposit, f; + int16_t samefield_pred[2], oppfield_pred[2]; + int16_t samefield_predA[2], oppfield_predA[2]; + int16_t samefield_predB[2], oppfield_predB[2]; + int16_t samefield_predC[2], oppfield_predC[2]; + int16_t *predA, *predC; + int a_valid, b_valid, c_valid; + int hybridmv_thresh, y_bias = 0; + if (v->mv_mode == MV_PMODE_MIXED_MV || + ((v->mv_mode == MV_PMODE_INTENSITY_COMP) && (v->mv_mode2 == MV_PMODE_MIXED_MV))) mixedmv_pic = 1; + else mixedmv_pic = 0; /* scale MV difference to be quad-pel */ dmv_x <<= 1 - s->quarter_sample; dmv_y <<= 1 - s->quarter_sample; @@ -883,35 +1450,38 @@ static inline void vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y, int m xy = s->block_index[n]; if(s->mb_intra){ - s->mv[0][n][0] = s->current_picture.f.motion_val[0][xy][0] = 0; - s->mv[0][n][1] = s->current_picture.f.motion_val[0][xy][1] = 0; - s->current_picture.f.motion_val[1][xy][0] = 0; - s->current_picture.f.motion_val[1][xy][1] = 0; + s->mv[0][n][0] = s->current_picture.f.motion_val[0][xy + v->blocks_off][0] = 0; + s->mv[0][n][1] = s->current_picture.f.motion_val[0][xy + v->blocks_off][1] = 0; + s->current_picture.f.motion_val[1][xy + v->blocks_off][0] = 0; + s->current_picture.f.motion_val[1][xy + v->blocks_off][1] = 0; if(mv1) { /* duplicate motion data for 1-MV block */ - s->current_picture.f.motion_val[0][xy + 1][0] = 0; - s->current_picture.f.motion_val[0][xy + 1][1] = 0; - s->current_picture.f.motion_val[0][xy + wrap][0] = 0; - s->current_picture.f.motion_val[0][xy + wrap][1] = 0; - s->current_picture.f.motion_val[0][xy + wrap + 1][0] = 0; - s->current_picture.f.motion_val[0][xy + wrap + 1][1] = 0; + s->current_picture.f.motion_val[0][xy + 1 + v->blocks_off][0] = 0; + s->current_picture.f.motion_val[0][xy + 1 + v->blocks_off][1] = 0; + s->current_picture.f.motion_val[0][xy + wrap + v->blocks_off][0] = 0; + s->current_picture.f.motion_val[0][xy + wrap + v->blocks_off][1] = 0; + s->current_picture.f.motion_val[0][xy + wrap + 1 + v->blocks_off][0] = 0; + s->current_picture.f.motion_val[0][xy + wrap + 1 + v->blocks_off][1] = 0; v->luma_mv[s->mb_x][0] = v->luma_mv[s->mb_x][1] = 0; - s->current_picture.f.motion_val[1][xy + 1][0] = 0; - s->current_picture.f.motion_val[1][xy + 1][1] = 0; - s->current_picture.f.motion_val[1][xy + wrap][0] = 0; - s->current_picture.f.motion_val[1][xy + wrap][1] = 0; - s->current_picture.f.motion_val[1][xy + wrap + 1][0] = 0; - s->current_picture.f.motion_val[1][xy + wrap + 1][1] = 0; + s->current_picture.f.motion_val[1][xy + 1 + v->blocks_off][0] = 0; + s->current_picture.f.motion_val[1][xy + 1 + v->blocks_off][1] = 0; + s->current_picture.f.motion_val[1][xy + wrap][0] = 0; + s->current_picture.f.motion_val[1][xy + wrap + v->blocks_off][1] = 0; + s->current_picture.f.motion_val[1][xy + wrap + 1 + v->blocks_off][0] = 0; + s->current_picture.f.motion_val[1][xy + wrap + 1 + v->blocks_off][1] = 0; } return; } - C = s->current_picture.f.motion_val[0][xy - 1]; - A = s->current_picture.f.motion_val[0][xy - wrap]; - if(mv1) - off = (s->mb_x == (s->mb_width - 1)) ? -1 : 2; - else { + C = s->current_picture.f.motion_val[dir][xy - 1 + v->blocks_off]; + A = s->current_picture.f.motion_val[dir][xy - wrap + v->blocks_off]; + if(mv1) { + if (v->field_mode && mixedmv_pic) + off = (s->mb_x == (s->mb_width - 1)) ? -2 : 2; + else + off = (s->mb_x == (s->mb_width - 1)) ? -1 : 2; + } else { //in 4-MV mode different blocks have different B predictor position - switch(n){ + switch (n) { case 0: off = (s->mb_x > 0) ? -1 : 1; break; @@ -925,24 +1495,135 @@ static inline void vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y, int m off = -1; } } - B = s->current_picture.f.motion_val[0][xy - wrap + off]; + B = s->current_picture.f.motion_val[dir][xy - wrap + off + v->blocks_off]; - if(!s->first_slice_line || (n==2 || n==3)) { // predictor A is not out of bounds - if(s->mb_width == 1) { - px = A[0]; - py = A[1]; - } else { - px = mid_pred(A[0], B[0], C[0]); - py = mid_pred(A[1], B[1], C[1]); - } - } else if(s->mb_x || (n==1 || n==3)) { // predictor C is not out of bounds - px = C[0]; - py = C[1]; - } else { - px = py = 0; + a_valid = !s->first_slice_line || (n==2 || n==3); + b_valid = a_valid && (s->mb_width > 1); + c_valid = s->mb_x || (n==1 || n==3); + if (v->field_mode) { + a_valid = a_valid && !is_intra[xy - wrap]; + b_valid = b_valid && !is_intra[xy - wrap + off]; + c_valid = c_valid && !is_intra[xy - 1]; } + + if (a_valid) { + f = v->mv_f[dir][xy - wrap + v->blocks_off]; + num_oppfield += f; + num_samefield += 1 - f; + if (f) { + oppfield_predA[0] = A[0]; + oppfield_predA[1] = A[1]; + samefield_predA[0] = scaleforsame(v, 0, A[0], 0, dir); + samefield_predA[1] = scaleforsame(v, n, A[1], 1, dir); + } else { + samefield_predA[0] = A[0]; + samefield_predA[1] = A[1]; + if (v->numref) + oppfield_predA[0] = scaleforopp(v, A[0], 0, dir); + if (v->numref) + oppfield_predA[1] = scaleforopp(v, A[1], 1, dir); + } + } else { + samefield_predA[0] = samefield_predA[1] = 0; + oppfield_predA[0] = oppfield_predA[1] = 0; + } + if (c_valid) { + f = v->mv_f[dir][xy - 1 + v->blocks_off]; + num_oppfield += f; + num_samefield += 1 - f; + if (f) { + oppfield_predC[0] = C[0]; + oppfield_predC[1] = C[1]; + samefield_predC[0] = scaleforsame(v, 0, C[0], 0, dir); + samefield_predC[1] = scaleforsame(v, n, C[1], 1, dir); + } else { + samefield_predC[0] = C[0]; + samefield_predC[1] = C[1]; + if (v->numref) + oppfield_predC[0] = scaleforopp(v, C[0], 0, dir); + if (v->numref) + oppfield_predC[1] = scaleforopp(v, C[1], 1, dir); + } + } else { + samefield_predC[0] = samefield_predC[1] = 0; + oppfield_predC[0] = oppfield_predC[1] = 0; + } + if (b_valid) { + f = v->mv_f[dir][xy - wrap + off + v->blocks_off]; + num_oppfield += f; + num_samefield += 1 - f; + if (f) { + oppfield_predB[0] = B[0]; + oppfield_predB[1] = B[1]; + samefield_predB[0] = scaleforsame(v, 0, B[0], 0, dir); + samefield_predB[1] = scaleforsame(v, n, B[1], 1, dir); + } else { + samefield_predB[0] = B[0]; + samefield_predB[1] = B[1]; + if (v->numref) + oppfield_predB[0] = scaleforopp(v, B[0], 0, dir); + if (v->numref) + oppfield_predB[1] = scaleforopp(v, B[1], 1, dir); + } + } else { + samefield_predB[0] = samefield_predB[1] = 0; + oppfield_predB[0] = oppfield_predB[1] = 0; + } + + if (a_valid) { + samefield_pred[0] = samefield_predA[0]; + samefield_pred[1] = samefield_predA[1]; + oppfield_pred[0] = oppfield_predA[0]; + oppfield_pred[1] = oppfield_predA[1]; + } else if (c_valid) { + samefield_pred[0] = samefield_predC[0]; + samefield_pred[1] = samefield_predC[1]; + oppfield_pred[0] = oppfield_predC[0]; + oppfield_pred[1] = oppfield_predC[1]; + } else if (b_valid) { + samefield_pred[0] = samefield_predB[0]; + samefield_pred[1] = samefield_predB[1]; + oppfield_pred[0] = oppfield_predB[0]; + oppfield_pred[1] = oppfield_predB[1]; + } else { + samefield_pred[0] = samefield_pred[1] = 0; + oppfield_pred[0] = oppfield_pred[1] = 0; + } + + if (num_samefield + num_oppfield > 1) { + samefield_pred[0] = mid_pred(samefield_predA[0], samefield_predB[0], samefield_predC[0]); + samefield_pred[1] = mid_pred(samefield_predA[1], samefield_predB[1], samefield_predC[1]); + if (v->numref) + oppfield_pred[0] = mid_pred(oppfield_predA[0], oppfield_predB[0], oppfield_predC[0]); + if (v->numref) + oppfield_pred[1] = mid_pred(oppfield_predA[1], oppfield_predB[1], oppfield_predC[1]); + } + + if (v->field_mode) { + if (num_samefield <= num_oppfield) + opposit = 1 - pred_flag; + else + opposit = pred_flag; + } else + opposit = 0; + if (opposit) { + px = oppfield_pred[0]; + py = oppfield_pred[1]; + predA = oppfield_predA; + predC = oppfield_predC; + v->mv_f[dir][xy + v->blocks_off] = f = 1; + v->ref_field_type[dir] = !v->cur_field_type; + } else { + px = samefield_pred[0]; + py = samefield_pred[1]; + predA = samefield_predA; + predC = samefield_predC; + v->mv_f[dir][xy + v->blocks_off] = f = 0; + v->ref_field_type[dir] = v->cur_field_type; + } + /* Pullback MV as specified in 8.3.5.3.4 */ - { + if (!v->field_mode) { int qx, qy, X, Y; qx = (s->mb_x << 6) + ((n==1 || n==3) ? 32 : 0); qy = (s->mb_y << 6) + ((n==2 || n==3) ? 32 : 0); @@ -958,46 +1639,285 @@ static inline void vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y, int m if(qx + px > X) px = X - qx; if(qy + py > Y) py = Y - qy; } - /* Calculate hybrid prediction as specified in 8.3.5.3.5 */ - if((!s->first_slice_line || (n==2 || n==3)) && (s->mb_x || (n==1 || n==3))) { - if(is_intra[xy - wrap]) - sum = FFABS(px) + FFABS(py); + + if (!v->field_mode || s->pict_type != AV_PICTURE_TYPE_B) { + /* Calculate hybrid prediction as specified in 8.3.5.3.5 (also 10.3.5.4.3.5) */ + if (v->field_mode && !s->quarter_sample) + hybridmv_thresh = 16; else - sum = FFABS(px - A[0]) + FFABS(py - A[1]); - if(sum > 32) { - if(get_bits1(&s->gb)) { - px = A[0]; - py = A[1]; - } else { - px = C[0]; - py = C[1]; - } - } else { - if(is_intra[xy - 1]) + hybridmv_thresh = 32; + if (a_valid && c_valid) { + if (is_intra[xy - wrap]) sum = FFABS(px) + FFABS(py); else - sum = FFABS(px - C[0]) + FFABS(py - C[1]); - if(sum > 32) { - if(get_bits1(&s->gb)) { - px = A[0]; - py = A[1]; + sum = FFABS(px - predA[0]) + FFABS(py - predA[1]); + if (sum > hybridmv_thresh) { + if (get_bits1(&s->gb)) { // read HYBRIDPRED bit + px = predA[0]; + py = predA[1]; } else { - px = C[0]; - py = C[1]; + px = predC[0]; + py = predC[1]; + } + } else { + if (is_intra[xy - 1]) + sum = FFABS(px) + FFABS(py); + else + sum = FFABS(px - predC[0]) + FFABS(py - predC[1]); + if (sum > hybridmv_thresh) { + if(get_bits1(&s->gb)) { + px = predA[0]; + py = predA[1]; + } else { + px = predC[0]; + py = predC[1]; + } } } } } + + if (v->field_mode && !s->quarter_sample) { + r_x <<= 1; + r_y <<= 1; + } + if (v->field_mode && v->numref) + r_y >>= 1; + if (v->field_mode && v->cur_field_type && v->ref_field_type[dir] == 0) + y_bias = 1; + /* store MV using signed modulus of MV range defined in 4.11 */ + s->mv[dir][n][0] = s->current_picture.f.motion_val[dir][xy + v->blocks_off][0] = ((px + dmv_x + r_x) & ((r_x << 1) - 1)) - r_x; + s->mv[dir][n][1] = s->current_picture.f.motion_val[dir][xy + v->blocks_off][1] = ((py + dmv_y + r_y - y_bias) & ((r_y << 1) - 1)) - r_y + y_bias; + if(mv1) { /* duplicate motion data for 1-MV block */ + s->current_picture.f.motion_val[dir][xy + 1 + v->blocks_off][0] = s->current_picture.f.motion_val[dir][xy + v->blocks_off][0]; + s->current_picture.f.motion_val[dir][xy + 1 + v->blocks_off][1] = s->current_picture.f.motion_val[dir][xy + v->blocks_off][1]; + s->current_picture.f.motion_val[dir][xy + wrap + v->blocks_off][0] = s->current_picture.f.motion_val[dir][xy + v->blocks_off][0]; + s->current_picture.f.motion_val[dir][xy + wrap + v->blocks_off][1] = s->current_picture.f.motion_val[dir][xy + v->blocks_off][1]; + s->current_picture.f.motion_val[dir][xy + wrap + 1 + v->blocks_off][0] = s->current_picture.f.motion_val[dir][xy + v->blocks_off][0]; + s->current_picture.f.motion_val[dir][xy + wrap + 1 + v->blocks_off][1] = s->current_picture.f.motion_val[dir][xy + v->blocks_off][1]; + v->mv_f[dir][xy + 1 + v->blocks_off] = v->mv_f[dir][xy + v->blocks_off]; + v->mv_f[dir][xy + wrap + v->blocks_off] = v->mv_f[dir][xy + wrap + 1 + v->blocks_off] = v->mv_f[dir][xy + v->blocks_off]; + } +} + +/** Predict and set motion vector for interlaced frame picture MBs + */ +static inline void vc1_pred_mv_intfr(VC1Context *v, int n, int dmv_x, int dmv_y, int mvn, int r_x, int r_y, uint8_t* is_intra) +{ + MpegEncContext *s = &v->s; + int xy, wrap, off = 0; + int A[2], B[2], C[2]; + int px, py; + int a_valid = 0, b_valid = 0, c_valid = 0; + int field_a, field_b, field_c; // 0: same, 1: opposit + int total_valid, num_samefield, num_oppfield; + int pos_c, pos_b, n_adj; + + wrap = s->b8_stride; + xy = s->block_index[n]; + + if(s->mb_intra){ + s->mv[0][n][0] = s->current_picture.f.motion_val[0][xy][0] = 0; + s->mv[0][n][1] = s->current_picture.f.motion_val[0][xy][1] = 0; + s->current_picture.f.motion_val[1][xy][0] = 0; + s->current_picture.f.motion_val[1][xy][1] = 0; + if(mvn == 1) { /* duplicate motion data for 1-MV block */ + s->current_picture.f.motion_val[0][xy + 1][0] = 0; + s->current_picture.f.motion_val[0][xy + 1][1] = 0; + s->current_picture.f.motion_val[0][xy + wrap][0] = 0; + s->current_picture.f.motion_val[0][xy + wrap][1] = 0; + s->current_picture.f.motion_val[0][xy + wrap + 1][0] = 0; + s->current_picture.f.motion_val[0][xy + wrap + 1][1] = 0; + v->luma_mv[s->mb_x][0] = v->luma_mv[s->mb_x][1] = 0; + s->current_picture.f.motion_val[1][xy + 1][0] = 0; + s->current_picture.f.motion_val[1][xy + 1][1] = 0; + s->current_picture.f.motion_val[1][xy + wrap][0] = 0; + s->current_picture.f.motion_val[1][xy + wrap][1] = 0; + s->current_picture.f.motion_val[1][xy + wrap + 1][0] = 0; + s->current_picture.f.motion_val[1][xy + wrap + 1][1] = 0; + } + return; + } + + off = ((n == 0) || (n == 1)) ? 1 : -1; + /* predict A */ + if (s->mb_x || (n == 1) || (n == 3)) { + if ((v->blk_mv_type[xy]) // current block (MB) has a field MV + || (!v->blk_mv_type[xy] && !v->blk_mv_type[xy - 1])) { // or both have frame MV + A[0] = s->current_picture.f.motion_val[0][xy - 1][0]; + A[1] = s->current_picture.f.motion_val[0][xy - 1][1]; + a_valid = 1; + } else { // current block has frame mv and cand. has field MV (so average) + A[0] = (s->current_picture.f.motion_val[0][xy - 1][0] + + s->current_picture.f.motion_val[0][xy - 1 + off*wrap][0] + 1) >> 1; + A[1] = (s->current_picture.f.motion_val[0][xy - 1][1] + + s->current_picture.f.motion_val[0][xy - 1 + off*wrap][1] + 1) >> 1; + a_valid = 1; + } + if (!(n & 1) && v->is_intra[s->mb_x - 1]) { + a_valid = 0; + A[0] = A[1] = 0; + } + } else A[0] = A[1] = 0; + /* Predict B and C */ + B[0] = B[1] = C[0] = C[1] = 0; + if (n == 0 || n == 1 || v->blk_mv_type[xy]) { + if (!s->first_slice_line) { + if (!v->is_intra[s->mb_x - s->mb_stride]) { + b_valid = 1; + n_adj = n | 2; + pos_b = s->block_index[n_adj] - 2 * wrap; + if (v->blk_mv_type[pos_b] && v->blk_mv_type[xy]) { + n_adj = (n & 2) | (n & 1); + } + B[0] = s->current_picture.f.motion_val[0][s->block_index[n_adj] - 2 * wrap][0]; + B[1] = s->current_picture.f.motion_val[0][s->block_index[n_adj] - 2 * wrap][1]; + if (v->blk_mv_type[pos_b] && !v->blk_mv_type[xy]) { + B[0] = (1 + B[0] + s->current_picture.f.motion_val[0][s->block_index[n_adj ^ 2] - 2 * wrap][0]) >> 1; + B[1] = (1 + B[1] + s->current_picture.f.motion_val[0][s->block_index[n_adj ^ 2] - 2 * wrap][1]) >> 1; + } + } + if (s->mb_width > 1) { + if (!v->is_intra[s->mb_x - s->mb_stride + 1]) { + c_valid = 1; + n_adj = 2; + pos_c = s->block_index[2] - 2*wrap + 2; + if (v->blk_mv_type[pos_c] && v->blk_mv_type[xy]) { + n_adj = n & 2; + } + C[0] = s->current_picture.f.motion_val[0][s->block_index[n_adj] - 2*wrap + 2][0]; + C[1] = s->current_picture.f.motion_val[0][s->block_index[n_adj] - 2*wrap + 2][1]; + if (v->blk_mv_type[pos_c] && !v->blk_mv_type[xy]) { + C[0] = (1 + C[0] + (s->current_picture.f.motion_val[0][s->block_index[n_adj ^ 2] - 2 * wrap + 2][0])) >> 1; + C[1] = (1 + C[1] + (s->current_picture.f.motion_val[0][s->block_index[n_adj ^ 2] - 2 * wrap + 2][1])) >> 1; + } + if (s->mb_x == s->mb_width - 1) { + if (!v->is_intra[s->mb_x - s->mb_stride - 1]) { + c_valid = 1; + n_adj = 3; + pos_c = s->block_index[3] - 2*wrap - 2; + if (v->blk_mv_type[pos_c] && v->blk_mv_type[xy]) { + n_adj = n | 1; + } + C[0] = s->current_picture.f.motion_val[0][s->block_index[n_adj] - 2*wrap - 2][0]; + C[1] = s->current_picture.f.motion_val[0][s->block_index[n_adj] - 2*wrap - 2][1]; + if (v->blk_mv_type[pos_c] && !v->blk_mv_type[xy]) { + C[0] = (1 + C[0] + s->current_picture.f.motion_val[0][s->block_index[1] - 2*wrap - 2][0]) >> 1; + C[1] = (1 + C[1] + s->current_picture.f.motion_val[0][s->block_index[1] - 2*wrap - 2][1]) >> 1; + } + } else c_valid = 0; + } + } + } + } + } else { + pos_b = s->block_index[1]; + b_valid = 1; + B[0] = s->current_picture.f.motion_val[0][pos_b][0]; + B[1] = s->current_picture.f.motion_val[0][pos_b][1]; + pos_c = s->block_index[0]; + c_valid = 1; + C[0] = s->current_picture.f.motion_val[0][pos_c][0]; + C[1] = s->current_picture.f.motion_val[0][pos_c][1]; + } + + total_valid = a_valid + b_valid + c_valid; + // check if predictor A is out of bounds + if (!s->mb_x && !(n==1 || n==3)) { + A[0] = A[1] = 0; + } + // check if predictor B is out of bounds + if ((s->first_slice_line && v->blk_mv_type[xy]) || (s->first_slice_line && !(n & 2))) { + B[0] = B[1] = C[0] = C[1] = 0; + } + if (!v->blk_mv_type[xy]) { + if(s->mb_width == 1) { + px = B[0]; + py = B[1]; + } else { + if (total_valid >= 2) { + px = mid_pred(A[0], B[0], C[0]); + py = mid_pred(A[1], B[1], C[1]); + } else if (total_valid) { + if (a_valid) { px = A[0]; py = A[1]; } + if (b_valid) { px = B[0]; py = B[1]; } + if (c_valid) { px = C[0]; py = C[1]; } + } else px = py = 0; + } + } else { + if (a_valid) + field_a = (A[1] & 4) ? 1 : 0; + else + field_a = 0; + if (b_valid) + field_b = (B[1] & 4) ? 1 : 0; + else + field_b = 0; + if (c_valid) + field_c = (C[1] & 4) ? 1 : 0; + else + field_c = 0; + + num_oppfield = field_a + field_b + field_c; + num_samefield = total_valid - num_oppfield; + if (total_valid == 3) { + if ((num_samefield == 3) || (num_oppfield == 3)) { + px = mid_pred(A[0], B[0], C[0]); + py = mid_pred(A[1], B[1], C[1]); + } else if (num_samefield >= num_oppfield) { + /* take one MV from same field set depending on priority + the check for B may not be necessary */ + px = (!field_a) ? A[0] : B[0]; + py = (!field_a) ? A[1] : B[1]; + } else { + px = (field_a) ? A[0] : B[0]; + py = (field_a) ? A[1] : B[1]; + } + } else if (total_valid == 2) { + if (num_samefield >= num_oppfield) { + if (!field_a && a_valid) { + px = A[0]; + py = A[1]; + } else if (!field_b && b_valid) { + px = B[0]; + py = B[1]; + } else if (c_valid) { + px = C[0]; + py = C[1]; + } else px = py = 0; + } else { + if (field_a && a_valid) { + px = A[0]; + py = A[1]; + } else if (field_b && b_valid) { + px = B[0]; + py = B[1]; + } else if (c_valid) { + px = C[0]; + py = C[1]; + } + } + } else if (total_valid == 1) { + px = (a_valid) ? A[0] : ((b_valid) ? B[0] : C[0]); + py = (a_valid) ? A[1] : ((b_valid) ? B[1] : C[1]); + } else px = py = 0; + } + /* store MV using signed modulus of MV range defined in 4.11 */ s->mv[0][n][0] = s->current_picture.f.motion_val[0][xy][0] = ((px + dmv_x + r_x) & ((r_x << 1) - 1)) - r_x; s->mv[0][n][1] = s->current_picture.f.motion_val[0][xy][1] = ((py + dmv_y + r_y) & ((r_y << 1) - 1)) - r_y; - if(mv1) { /* duplicate motion data for 1-MV block */ - s->current_picture.f.motion_val[0][xy + 1][0] = s->current_picture.f.motion_val[0][xy][0]; - s->current_picture.f.motion_val[0][xy + 1][1] = s->current_picture.f.motion_val[0][xy][1]; - s->current_picture.f.motion_val[0][xy + wrap][0] = s->current_picture.f.motion_val[0][xy][0]; - s->current_picture.f.motion_val[0][xy + wrap][1] = s->current_picture.f.motion_val[0][xy][1]; + if(mvn == 1) { /* duplicate motion data for 1-MV block */ + s->current_picture.f.motion_val[0][xy + 1][0] = s->current_picture.f.motion_val[0][xy][0]; + s->current_picture.f.motion_val[0][xy + 1][1] = s->current_picture.f.motion_val[0][xy][1]; + s->current_picture.f.motion_val[0][xy + wrap][0] = s->current_picture.f.motion_val[0][xy][0]; + s->current_picture.f.motion_val[0][xy + wrap][1] = s->current_picture.f.motion_val[0][xy][1]; s->current_picture.f.motion_val[0][xy + wrap + 1][0] = s->current_picture.f.motion_val[0][xy][0]; s->current_picture.f.motion_val[0][xy + wrap + 1][1] = s->current_picture.f.motion_val[0][xy][1]; + } else if (mvn == 2) { /* duplicate motion data for 2-Field MV block */ + s->current_picture.f.motion_val[0][xy + 1][0] = s->current_picture.f.motion_val[0][xy][0]; + s->current_picture.f.motion_val[0][xy + 1][1] = s->current_picture.f.motion_val[0][xy][1]; + s->mv[0][n + 1][0] = s->mv[0][n][0]; + s->mv[0][n + 1][1] = s->mv[0][n][1]; } } @@ -1009,13 +1929,21 @@ static void vc1_interp_mc(VC1Context *v) DSPContext *dsp = &v->s.dsp; 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->s.next_picture.f.data[0])return; + if (!v->field_mode && !v->s.next_picture.f.data[0]) + return; mx = s->mv[1][0][0]; my = s->mv[1][0][1]; uvmx = (mx + ((mx & 3) == 3)) >> 1; uvmy = (my + ((my & 3) == 3)) >> 1; + if (v->field_mode) { + if (v->cur_field_type != v->ref_field_type[1]) + my = my - 2 + 4 * v->cur_field_type; + uvmy = uvmy - 2 + 4 * v->cur_field_type; + } if(v->fastuvmc) { uvmx = uvmx + ((uvmx<0)?-(uvmx&1):(uvmx&1)); uvmy = uvmy + ((uvmy<0)?-(uvmy&1):(uvmy&1)); @@ -1045,6 +1973,12 @@ static void vc1_interp_mc(VC1Context *v) srcU += uvsrc_y * s->uvlinesize + uvsrc_x; srcV += uvsrc_y * s->uvlinesize + uvsrc_x; + if (v->field_mode && v->ref_field_type[1]) { + srcY += s->current_picture_ptr->f.linesize[0]; + srcU += s->current_picture_ptr->f.linesize[1]; + srcV += s->current_picture_ptr->f.linesize[2]; + } + /* for grayscale we should not try to read from unknown area */ if(s->flags & CODEC_FLAG_GRAY) { srcU = s->edge_emu_buffer + 18 * s->linesize; @@ -1053,17 +1987,17 @@ static void vc1_interp_mc(VC1Context *v) if(v->rangeredfrm || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx&3) - 16 - s->mspel*3 - || (unsigned)(src_y - s->mspel) > s->v_edge_pos - (my&3) - 16 - s->mspel*3){ + || (unsigned)(src_y - s->mspel) > v_edge_pos - (my&3) - 16 - s->mspel*3){ uint8_t *uvbuf= s->edge_emu_buffer + 19 * s->linesize; srcY -= s->mspel * (1 + s->linesize); s->dsp.emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, 17+s->mspel*2, 17+s->mspel*2, - src_x - s->mspel, src_y - s->mspel, s->h_edge_pos, s->v_edge_pos); + src_x - s->mspel, src_y - s->mspel, s->h_edge_pos, v_edge_pos); srcY = s->edge_emu_buffer; s->dsp.emulated_edge_mc(uvbuf , srcU, s->uvlinesize, 8+1, 8+1, - uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1); + uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, v_edge_pos >> 1); s->dsp.emulated_edge_mc(uvbuf + 16, srcV, s->uvlinesize, 8+1, 8+1, - uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1); + uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, v_edge_pos >> 1); srcU = uvbuf; srcV = uvbuf + 16; /* if we deal with range reduction we need to scale source blocks */ @@ -1089,20 +2023,28 @@ 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; + } + if(s->mspel) { dxy = ((my & 3) << 2) | (mx & 3); - v->vc1dsp.avg_vc1_mspel_pixels_tab[dxy](s->dest[0] , srcY , s->linesize, v->rnd); - v->vc1dsp.avg_vc1_mspel_pixels_tab[dxy](s->dest[0] + 8, srcY + 8, s->linesize, v->rnd); + v->vc1dsp.avg_vc1_mspel_pixels_tab[dxy](s->dest[0] + off , srcY , s->linesize, v->rnd); + v->vc1dsp.avg_vc1_mspel_pixels_tab[dxy](s->dest[0] + off + 8, srcY + 8, s->linesize, v->rnd); srcY += s->linesize * 8; - v->vc1dsp.avg_vc1_mspel_pixels_tab[dxy](s->dest[0] + 8 * s->linesize , srcY , s->linesize, v->rnd); - v->vc1dsp.avg_vc1_mspel_pixels_tab[dxy](s->dest[0] + 8 * s->linesize + 8, srcY + 8, s->linesize, v->rnd); + v->vc1dsp.avg_vc1_mspel_pixels_tab[dxy](s->dest[0] + off + 8 * s->linesize , srcY , s->linesize, v->rnd); + v->vc1dsp.avg_vc1_mspel_pixels_tab[dxy](s->dest[0] + off + 8 * s->linesize + 8, srcY + 8, s->linesize, v->rnd); } else { // hpel mc dxy = (my & 2) | ((mx & 2) >> 1); if(!v->rnd) - dsp->avg_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16); + dsp->avg_pixels_tab[0][dxy](s->dest[0] + off, srcY, s->linesize, 16); else - dsp->avg_no_rnd_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16); + dsp->avg_no_rnd_pixels_tab[0][dxy](s->dest[0] + off, srcY, s->linesize, 16); } if(s->flags & CODEC_FLAG_GRAY) return; @@ -1110,11 +2052,11 @@ static void vc1_interp_mc(VC1Context *v) uvmx = (uvmx&3)<<1; uvmy = (uvmy&3)<<1; if(!v->rnd){ - dsp->avg_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy); - dsp->avg_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy); + dsp->avg_h264_chroma_pixels_tab[0](s->dest[1] + off_uv, srcU, s->uvlinesize, 8, uvmx, uvmy); + dsp->avg_h264_chroma_pixels_tab[0](s->dest[2] + off_uv, srcV, s->uvlinesize, 8, uvmx, uvmy); }else{ - v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy); - v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy); + v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1] + off_uv, srcU, s->uvlinesize, 8, uvmx, uvmy); + v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2] + off_uv, srcV, s->uvlinesize, 8, uvmx, uvmy); } } @@ -1137,6 +2079,19 @@ static av_always_inline int scale_mv(int value, int bfrac, int inv, int qs) #endif } +static av_always_inline int scale_mv_intfi(int value, int bfrac, int inv, int qs, int qs_last) +{ + int n = bfrac; + + if (inv) + n -= 256; + n <<= !qs_last; + if (!qs) + return (value * n + 255) >> 9; + else + return (value * n + 128) >> 8; +} + /** Reconstruct motion vector for B-frame and do motion compensation */ static inline void vc1_b_mc(VC1Context *v, int dmv_x[2], int dmv_y[2], int direct, int mode) @@ -1185,27 +2140,29 @@ static inline void vc1_pred_b_mv(VC1Context *v, int dmv_x[2], int dmv_y[2], int xy = s->block_index[0]; if(s->mb_intra) { - s->current_picture.f.motion_val[0][xy][0] = - s->current_picture.f.motion_val[0][xy][1] = - s->current_picture.f.motion_val[1][xy][0] = - s->current_picture.f.motion_val[1][xy][1] = 0; + s->current_picture.f.motion_val[0][xy + v->blocks_off][0] = + s->current_picture.f.motion_val[0][xy + v->blocks_off][1] = + s->current_picture.f.motion_val[1][xy + v->blocks_off][0] = + s->current_picture.f.motion_val[1][xy + v->blocks_off][1] = 0; return; } - s->mv[0][0][0] = scale_mv(s->next_picture.f.motion_val[1][xy][0], v->bfraction, 0, s->quarter_sample); - s->mv[0][0][1] = scale_mv(s->next_picture.f.motion_val[1][xy][1], v->bfraction, 0, s->quarter_sample); - s->mv[1][0][0] = scale_mv(s->next_picture.f.motion_val[1][xy][0], v->bfraction, 1, s->quarter_sample); - s->mv[1][0][1] = scale_mv(s->next_picture.f.motion_val[1][xy][1], v->bfraction, 1, s->quarter_sample); + if (!v->field_mode) { + s->mv[0][0][0] = scale_mv(s->next_picture.f.motion_val[1][xy][0], v->bfraction, 0, s->quarter_sample); + s->mv[0][0][1] = scale_mv(s->next_picture.f.motion_val[1][xy][1], v->bfraction, 0, s->quarter_sample); + s->mv[1][0][0] = scale_mv(s->next_picture.f.motion_val[1][xy][0], v->bfraction, 1, s->quarter_sample); + s->mv[1][0][1] = scale_mv(s->next_picture.f.motion_val[1][xy][1], v->bfraction, 1, s->quarter_sample); - /* Pullback predicted motion vectors as specified in 8.4.5.4 */ - s->mv[0][0][0] = av_clip(s->mv[0][0][0], -60 - (s->mb_x << 6), (s->mb_width << 6) - 4 - (s->mb_x << 6)); - s->mv[0][0][1] = av_clip(s->mv[0][0][1], -60 - (s->mb_y << 6), (s->mb_height << 6) - 4 - (s->mb_y << 6)); - s->mv[1][0][0] = av_clip(s->mv[1][0][0], -60 - (s->mb_x << 6), (s->mb_width << 6) - 4 - (s->mb_x << 6)); - s->mv[1][0][1] = av_clip(s->mv[1][0][1], -60 - (s->mb_y << 6), (s->mb_height << 6) - 4 - (s->mb_y << 6)); + /* Pullback predicted motion vectors as specified in 8.4.5.4 */ + s->mv[0][0][0] = av_clip(s->mv[0][0][0], -60 - (s->mb_x << 6), (s->mb_width << 6) - 4 - (s->mb_x << 6)); + s->mv[0][0][1] = av_clip(s->mv[0][0][1], -60 - (s->mb_y << 6), (s->mb_height << 6) - 4 - (s->mb_y << 6)); + s->mv[1][0][0] = av_clip(s->mv[1][0][0], -60 - (s->mb_x << 6), (s->mb_width << 6) - 4 - (s->mb_x << 6)); + s->mv[1][0][1] = av_clip(s->mv[1][0][1], -60 - (s->mb_y << 6), (s->mb_height << 6) - 4 - (s->mb_y << 6)); + } if(direct) { - s->current_picture.f.motion_val[0][xy][0] = s->mv[0][0][0]; - s->current_picture.f.motion_val[0][xy][1] = s->mv[0][0][1]; - s->current_picture.f.motion_val[1][xy][0] = s->mv[1][0][0]; - s->current_picture.f.motion_val[1][xy][1] = s->mv[1][0][1]; + s->current_picture.f.motion_val[0][xy + v->blocks_off][0] = s->mv[0][0][0]; + s->current_picture.f.motion_val[0][xy + v->blocks_off][1] = s->mv[0][0][1]; + s->current_picture.f.motion_val[1][xy + v->blocks_off][0] = s->mv[1][0][0]; + s->current_picture.f.motion_val[1][xy + v->blocks_off][1] = s->mv[1][0][1]; return; } @@ -1372,6 +2329,59 @@ static inline void vc1_pred_b_mv(VC1Context *v, int dmv_x[2], int dmv_y[2], int s->current_picture.f.motion_val[1][xy][1] = s->mv[1][0][1]; } +static inline void vc1_pred_b_mv_intfi(VC1Context *v, int n, int *dmv_x, int *dmv_y, int mv1, int *pred_flag) +{ + int dir = (v->bmvtype == BMV_TYPE_BACKWARD) ? 1 : 0; + MpegEncContext *s = &v->s; + int mb_pos = s->mb_x + s->mb_y * s->mb_stride; + + if (v->bmvtype == BMV_TYPE_DIRECT) { + int total_opp, k, f; + if (s->next_picture.f.mb_type[mb_pos + v->mb_off] != MB_TYPE_INTRA) { + s->mv[0][0][0] = scale_mv_intfi(s->next_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][0], v->bfraction, 0, s->quarter_sample, v->qs_last); + s->mv[0][0][1] = scale_mv_intfi(s->next_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][1], v->bfraction, 0, s->quarter_sample, v->qs_last); + s->mv[1][0][0] = scale_mv_intfi(s->next_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][0], v->bfraction, 1, s->quarter_sample, v->qs_last); + s->mv[1][0][1] = scale_mv_intfi(s->next_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][1], v->bfraction, 1, s->quarter_sample, v->qs_last); + + total_opp = v->mv_f_next[0][s->block_index[0] + v->blocks_off] + + v->mv_f_next[0][s->block_index[1] + v->blocks_off] + + v->mv_f_next[0][s->block_index[2] + v->blocks_off] + + v->mv_f_next[0][s->block_index[3] + v->blocks_off]; + f = (total_opp > 2) ? 1 : 0; + } else { + s->mv[0][0][0] = s->mv[0][0][1] = 0; + s->mv[1][0][0] = s->mv[1][0][1] = 0; + f = 0; + } + v->ref_field_type[0] = v->ref_field_type[1] = v->cur_field_type ^ f; + for (k = 0; k < 4; k++) { + s->current_picture.f.motion_val[0][s->block_index[k] + v->blocks_off][0] = s->mv[0][0][0]; + s->current_picture.f.motion_val[0][s->block_index[k] + v->blocks_off][1] = s->mv[0][0][1]; + s->current_picture.f.motion_val[1][s->block_index[k] + v->blocks_off][0] = s->mv[1][0][0]; + s->current_picture.f.motion_val[1][s->block_index[k] + v->blocks_off][1] = s->mv[1][0][1]; + v->mv_f[0][s->block_index[k] + v->blocks_off] = f; + v->mv_f[1][s->block_index[k] + v->blocks_off] = f; + } + return; + } + if (v->bmvtype == BMV_TYPE_INTERPOLATED) { + vc1_pred_mv(v, 0, dmv_x[0], dmv_y[0], 1, v->range_x, v->range_y, v->mb_type[0], pred_flag[0], 0); + vc1_pred_mv(v, 0, dmv_x[1], dmv_y[1], 1, v->range_x, v->range_y, v->mb_type[0], pred_flag[1], 1); + return; + } + if (dir) { // backward + vc1_pred_mv(v, n, dmv_x[1], dmv_y[1], mv1, v->range_x, v->range_y, v->mb_type[0], pred_flag[1], 1); + if (n == 3 || mv1) { + vc1_pred_mv(v, 0, dmv_x[0], dmv_y[0], 1, v->range_x, v->range_y, v->mb_type[0], 0, 0); + } + } else { // forward + vc1_pred_mv(v, n, dmv_x[0], dmv_y[0], mv1, v->range_x, v->range_y, v->mb_type[0], pred_flag[0], 0); + if (n == 3 || mv1) { + vc1_pred_mv(v, 0, dmv_x[1], dmv_y[1], 1, v->range_x, v->range_y, v->mb_type[0], 0, 1); + } + } +} + /** Get predicted DC value for I-frames only * prediction dir: left=0, top=1 * @param s MpegEncContext @@ -1866,12 +2876,20 @@ static int vc1_decode_i_block_adv(VC1Context *v, DCTELEM block[64], int n, int c int k; if(v->s.ac_pred) { - if(!dc_pred_dir) - zz_table = v->zz_8x8[2]; + if (!use_pred && v->fcm == 1) { + zz_table = v->zzi_8x8; + } else { + if(!dc_pred_dir) //top + zz_table = v->zz_8x8[2]; + else //left + zz_table = v->zz_8x8[3]; + } + } else { + if (v->fcm != 1) + zz_table = v->zz_8x8[1]; else - zz_table = v->zz_8x8[3]; - } else - zz_table = v->zz_8x8[1]; + zz_table = v->zzi_8x8; + } while (!last) { vc1_decode_ac_coeff(v, &last, &skip, &value, codingset); @@ -2076,7 +3094,18 @@ static int vc1_decode_intra_block(VC1Context *v, DCTELEM block[64], int n, int c i += skip; if(i > 63) break; - block[v->zz_8x8[0][i++]] = value; + if (v->fcm == 0) + block[v->zz_8x8[0][i++]] = value; + else { + if(use_pred && (v->fcm == 1)) { + if(!dc_pred_dir) //top + block[v->zz_8x8[2][i++]] = value; + else //left + block[v->zz_8x8[3][i++]] = value; + } else { + block[v->zzi_8x8[i++]] = value; + } + } } /* apply AC prediction if needed */ @@ -2217,7 +3246,10 @@ static int vc1_decode_p_block(VC1Context *v, DCTELEM block[64], int n, int mquan i += skip; if(i > 63) break; - idx = v->zz_8x8[0][i++]; + if (!v->interlace) + idx = v->zz_8x8[0][i++]; + else + idx = v->zzi_8x8[i++]; block[idx] = value * scale; if(!v->pquantizer) block[idx] += (block[idx] < 0) ? -mquant : mquant; @@ -2242,7 +3274,10 @@ static int vc1_decode_p_block(VC1Context *v, DCTELEM block[64], int n, int mquan i += skip; if(i > 15) break; - idx = ff_vc1_simple_progressive_4x4_zz[i++]; + if (!v->interlace) + idx = ff_vc1_simple_progressive_4x4_zz[i++]; + else + idx = ff_vc1_adv_interlaced_4x4_zz[i++]; block[idx + off] = value * scale; if(!v->pquantizer) block[idx + off] += (block[idx + off] < 0) ? -mquant : mquant; @@ -2266,7 +3301,10 @@ static int vc1_decode_p_block(VC1Context *v, DCTELEM block[64], int n, int mquan i += skip; if(i > 31) break; - idx = v->zz_8x4[i++]+off; + if (!v->interlace) + idx = v->zz_8x4[i++] + off; + else + idx = ff_vc1_adv_interlaced_8x4_zz[i++] + off; block[idx] = value * scale; if(!v->pquantizer) block[idx] += (block[idx] < 0) ? -mquant : mquant; @@ -2290,7 +3328,10 @@ static int vc1_decode_p_block(VC1Context *v, DCTELEM block[64], int n, int mquan i += skip; if(i > 31) break; - idx = v->zz_4x8[i++]+off; + if (!v->interlace) + idx = v->zz_4x8[i++] + off; + else + idx = ff_vc1_adv_interlaced_4x8_zz[i++] + off; block[idx] = value * scale; if(!v->pquantizer) block[idx] += (block[idx] < 0) ? -mquant : mquant; @@ -2463,7 +3504,7 @@ static void vc1_apply_p_loop_filter(VC1Context *v) } } -/** Decode one P-frame MB (in Simple/Main profile) +/** Decode one P-frame MB */ static int vc1_decode_p_mb(VC1Context *v) { @@ -2506,7 +3547,7 @@ static int vc1_decode_p_mb(VC1Context *v) s->current_picture.f.motion_val[1][s->block_index[0]][1] = 0; } s->current_picture.f.mb_type[mb_pos] = s->mb_intra ? MB_TYPE_INTRA : MB_TYPE_16x16; - vc1_pred_mv(v, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0]); + vc1_pred_mv(v, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0], 0, 0); /* FIXME Set DC val for inter block ? */ if (s->mb_intra && !mb_has_coeffs) @@ -2517,7 +3558,8 @@ static int vc1_decode_p_mb(VC1Context *v) } else if (mb_has_coeffs) { - if (s->mb_intra) s->ac_pred = get_bits1(gb); + if (s->mb_intra) + s->ac_pred = get_bits1(gb); cbp = get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2); GET_MQUANT(); } @@ -2578,7 +3620,7 @@ static int vc1_decode_p_mb(VC1Context *v) } s->current_picture.f.mb_type[mb_pos] = MB_TYPE_SKIP; s->current_picture.f.qscale_table[mb_pos] = 0; - vc1_pred_mv(v, 0, 0, 0, 1, v->range_x, v->range_y, v->mb_type[0]); + vc1_pred_mv(v, 0, 0, 0, 1, v->range_x, v->range_y, v->mb_type[0], 0, 0); vc1_mc_1mv(v, 0); } } //1MV mode @@ -2602,8 +3644,8 @@ static int vc1_decode_p_mb(VC1Context *v) if(val) { GET_MVDATA(dmv_x, dmv_y); } - vc1_pred_mv(v, i, dmv_x, dmv_y, 0, v->range_x, v->range_y, v->mb_type[0]); - if(!s->mb_intra) vc1_mc_4mv_luma(v, i); + vc1_pred_mv(v, i, dmv_x, dmv_y, 0, v->range_x, v->range_y, v->mb_type[0], 0, 0); + if(!s->mb_intra) vc1_mc_4mv_luma(v, i, 0); intra_count += s->mb_intra; is_intra[i] = s->mb_intra; is_coded[i] = mb_has_coeffs; @@ -2612,7 +3654,7 @@ static int vc1_decode_p_mb(VC1Context *v) is_intra[i] = (intra_count >= 3); is_coded[i] = val; } - if(i == 4) vc1_mc_4mv_chroma(v); + if(i == 4) vc1_mc_4mv_chroma(v, 0); v->mb_type[0][s->block_index[i]] = is_intra[i]; if(!coded_inter) coded_inter = !is_intra[i] & is_coded[i]; } @@ -2682,10 +3724,10 @@ static int vc1_decode_p_mb(VC1Context *v) } for (i=0; i<4; i++) { - vc1_pred_mv(v, i, 0, 0, 0, v->range_x, v->range_y, v->mb_type[0]); - vc1_mc_4mv_luma(v, i); + vc1_pred_mv(v, i, 0, 0, 0, v->range_x, v->range_y, v->mb_type[0], 0, 0); + vc1_mc_4mv_luma(v, i, 0); } - vc1_mc_4mv_chroma(v); + vc1_mc_4mv_chroma(v, 0); s->current_picture.f.qscale_table[mb_pos] = 0; } } @@ -2697,6 +3739,324 @@ end: return 0; } +/* Decode one macroblock in an interlaced frame p picture */ + +static int vc1_decode_p_mb_intfr(VC1Context *v) +{ + MpegEncContext *s = &v->s; + GetBitContext *gb = &s->gb; + int i; + int mb_pos = s->mb_x + s->mb_y * s->mb_stride; + int cbp = 0; /* cbp decoding stuff */ + int mqdiff, mquant; /* MB quantization */ + int ttmb = v->ttfrm; /* MB Transform type */ + + int mb_has_coeffs = 1; /* last_flag */ + int dmv_x, dmv_y; /* Differential MV components */ + int val; /* temp value */ + int first_block = 1; + int dst_idx, off; + int skipped, fourmv = 0, twomv = 0; + int block_cbp = 0, pat, block_tt = 0; + int idx_mbmode = 0, mvbp; + int stride_y, fieldtx; + + mquant = v->pq; /* Loosy initialization */ + + if (v->skip_is_raw) + skipped = get_bits1(gb); + else + skipped = v->s.mbskip_table[mb_pos]; + if (!skipped) { + if (v->fourmvswitch) + idx_mbmode = get_vlc2(gb, v->mbmode_vlc->table, VC1_INTFR_4MV_MBMODE_VLC_BITS, 2); // try getting this done + else + idx_mbmode = get_vlc2(gb, v->mbmode_vlc->table, VC1_INTFR_NON4MV_MBMODE_VLC_BITS, 2); // in a single line + switch (ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][0]) { + /* store the motion vector type in a flag (useful later) */ + case MV_PMODE_INTFR_4MV: + fourmv = 1; + v->blk_mv_type[s->block_index[0]] = 0; + v->blk_mv_type[s->block_index[1]] = 0; + v->blk_mv_type[s->block_index[2]] = 0; + v->blk_mv_type[s->block_index[3]] = 0; + break; + case MV_PMODE_INTFR_4MV_FIELD: + fourmv = 1; + v->blk_mv_type[s->block_index[0]] = 1; + v->blk_mv_type[s->block_index[1]] = 1; + v->blk_mv_type[s->block_index[2]] = 1; + v->blk_mv_type[s->block_index[3]] = 1; + break; + case MV_PMODE_INTFR_2MV_FIELD: + twomv = 1; + v->blk_mv_type[s->block_index[0]] = 1; + v->blk_mv_type[s->block_index[1]] = 1; + v->blk_mv_type[s->block_index[2]] = 1; + v->blk_mv_type[s->block_index[3]] = 1; + break; + case MV_PMODE_INTFR_1MV: + v->blk_mv_type[s->block_index[0]] = 0; + v->blk_mv_type[s->block_index[1]] = 0; + v->blk_mv_type[s->block_index[2]] = 0; + v->blk_mv_type[s->block_index[3]] = 0; + break; + } + if (ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][0] == MV_PMODE_INTFR_INTRA) { // intra MB + s->current_picture.f.motion_val[1][s->block_index[0]][0] = 0; + s->current_picture.f.motion_val[1][s->block_index[0]][1] = 0; + s->current_picture.f.mb_type[mb_pos] = MB_TYPE_INTRA; + s->mb_intra = v->is_intra[s->mb_x] = 1; + for (i = 0; i < 6; i++) v->mb_type[0][s->block_index[i]] = 1; + fieldtx = v->fieldtx_plane[mb_pos] = get_bits1(gb); + mb_has_coeffs = get_bits1(gb); + if (mb_has_coeffs) + cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2); + v->s.ac_pred = v->acpred_plane[mb_pos] = get_bits1(gb); + GET_MQUANT(); + s->current_picture.f.qscale_table[mb_pos] = mquant; + /* Set DC scale - y and c use the same (not sure if necessary here) */ + s->y_dc_scale = s->y_dc_scale_table[mquant]; + s->c_dc_scale = s->c_dc_scale_table[mquant]; + dst_idx = 0; + for (i=0; i<6; i++) { + s->dc_val[0][s->block_index[i]] = 0; + dst_idx += i >> 2; + val = ((cbp >> (5 - i)) & 1); + v->mb_type[0][s->block_index[i]] = s->mb_intra; + v->a_avail = v->c_avail = 0; + if(i == 2 || i == 3 || !s->first_slice_line) + v->a_avail = v->mb_type[0][s->block_index[i] - s->block_wrap[i]]; + if(i == 1 || i == 3 || s->mb_x) + v->c_avail = v->mb_type[0][s->block_index[i] - 1]; + + vc1_decode_intra_block(v, s->block[i], i, val, mquant, (i&4)?v->codingset2:v->codingset); + if((i>3) && (s->flags & CODEC_FLAG_GRAY)) continue; + v->vc1dsp.vc1_inv_trans_8x8(s->block[i]); + if (i < 4) { + stride_y = s->linesize << fieldtx; + off = (fieldtx) ? ((i & 1) * 8) + ((i & 2) >> 1) * s->linesize : (i & 1) * 8 + 4 * (i & 2) * s->linesize; + } else { + stride_y = s->uvlinesize; + off = 0; + } + s->dsp.put_signed_pixels_clamped(s->block[i], s->dest[dst_idx] + off, stride_y); + //TODO: loop filter + } + + } else { //inter MB + mb_has_coeffs = ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][3]; + if (mb_has_coeffs) + cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2); + if (ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][0] == MV_PMODE_INTFR_2MV_FIELD) { + v->twomvbp = get_vlc2(gb, v->twomvbp_vlc->table, VC1_2MV_BLOCK_PATTERN_VLC_BITS, 1); + } else { + if ((ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][0] == MV_PMODE_INTFR_4MV) + || (ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][0] == MV_PMODE_INTFR_4MV_FIELD)) { + v->fourmvbp = get_vlc2(gb, v->fourmvbp_vlc->table, VC1_4MV_BLOCK_PATTERN_VLC_BITS, 1); + } + } + s->mb_intra = v->is_intra[s->mb_x] = 0; + for (i = 0; i < 6; i++) v->mb_type[0][s->block_index[i]] = 0; + fieldtx = v->fieldtx_plane[mb_pos] = ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][1]; + /* for all motion vector read MVDATA and motion compensate each block */ + dst_idx = 0; + if (fourmv) { + mvbp = v->fourmvbp; + for (i=0; i<6; i++) { + if (i < 4) { + dmv_x = dmv_y = 0; + val = ((mvbp >> (3 - i)) & 1); + if(val) { + get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0); + } + vc1_pred_mv_intfr(v, i, dmv_x, dmv_y, 0, v->range_x, v->range_y, v->mb_type[0]); + vc1_mc_4mv_luma(v, i, 0); + } else if (i == 4) { + vc1_mc_4mv_chroma4(v); + } + } + } else if (twomv) { + mvbp = v->twomvbp; + dmv_x = dmv_y = 0; + if (mvbp & 2) { + get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0); + } + vc1_pred_mv_intfr(v, 0, dmv_x, dmv_y, 2, v->range_x, v->range_y, v->mb_type[0]); + vc1_mc_4mv_luma(v, 0, 0); + vc1_mc_4mv_luma(v, 1, 0); + dmv_x = dmv_y = 0; + if (mvbp & 1) { + get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0); + } + vc1_pred_mv_intfr(v, 2, dmv_x, dmv_y, 2, v->range_x, v->range_y, v->mb_type[0]); + vc1_mc_4mv_luma(v, 2, 0); + vc1_mc_4mv_luma(v, 3, 0); + vc1_mc_4mv_chroma4(v); + } else { + mvbp = ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][2]; + if (mvbp) { + get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0); + } + vc1_pred_mv_intfr(v, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0]); + vc1_mc_1mv(v, 0); + } + if (cbp) + GET_MQUANT(); // p. 227 + s->current_picture.f.qscale_table[mb_pos] = mquant; + if (!v->ttmbf && cbp) + ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2); + for (i=0; i<6; i++) { + s->dc_val[0][s->block_index[i]] = 0; + dst_idx += i >> 2; + val = ((cbp >> (5 - i)) & 1); + if (!fieldtx) + off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize); + else + off = (i & 4) ? 0 : ((i & 1) * 8 + ((i > 1) * s->linesize)); + if (val) { + pat = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, first_block, s->dest[dst_idx] + off, (i&4)?s->uvlinesize:(s->linesize << fieldtx), (i&4) && (s->flags & CODEC_FLAG_GRAY), &block_tt); + block_cbp |= pat << (i << 2); + if (!v->ttmbf && ttmb < 8) + ttmb = -1; + first_block = 0; + } + } + } + } else { // skipped + s->mb_intra = v->is_intra[s->mb_x] = 0; + for(i = 0; i < 6; i++) { + v->mb_type[0][s->block_index[i]] = 0; + s->dc_val[0][s->block_index[i]] = 0; + } + s->current_picture.f.mb_type[mb_pos] = MB_TYPE_SKIP; + s->current_picture.f.qscale_table[mb_pos] = 0; + v->blk_mv_type[s->block_index[0]] = 0; + v->blk_mv_type[s->block_index[1]] = 0; + v->blk_mv_type[s->block_index[2]] = 0; + v->blk_mv_type[s->block_index[3]] = 0; + vc1_pred_mv_intfr(v, 0, 0, 0, 1, v->range_x, v->range_y, v->mb_type[0]); + vc1_mc_1mv(v, 0); + } + if (s->mb_x == s->mb_width - 1) + memmove(v->is_intra_base, v->is_intra, sizeof(v->is_intra_base[0])*s->mb_stride); + return 0; +} + +static int vc1_decode_p_mb_intfi(VC1Context *v) +{ + MpegEncContext *s = &v->s; + GetBitContext *gb = &s->gb; + int i; + int mb_pos = s->mb_x + s->mb_y * s->mb_stride; + int cbp = 0; /* cbp decoding stuff */ + int mqdiff, mquant; /* MB quantization */ + int ttmb = v->ttfrm; /* MB Transform type */ + + int mb_has_coeffs = 1; /* last_flag */ + int dmv_x, dmv_y; /* Differential MV components */ + int val; /* temp values */ + int first_block = 1; + int dst_idx, off; + int pred_flag; + int block_cbp = 0, pat, block_tt = 0; + int idx_mbmode = 0; + + mquant = v->pq; /* Loosy initialization */ + + idx_mbmode = get_vlc2(gb, v->mbmode_vlc->table, VC1_IF_MBMODE_VLC_BITS, 2); + if (idx_mbmode <= 1) { // intra MB + s->mb_intra = v->is_intra[s->mb_x] = 1; + s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0; + s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0; + s->current_picture.f.mb_type[mb_pos + v->mb_off] = MB_TYPE_INTRA; + GET_MQUANT(); + s->current_picture.f.qscale_table[mb_pos] = mquant; + /* Set DC scale - y and c use the same (not sure if necessary here) */ + s->y_dc_scale = s->y_dc_scale_table[mquant]; + s->c_dc_scale = s->c_dc_scale_table[mquant]; + v->s.ac_pred = v->acpred_plane[mb_pos] = get_bits1(gb); + mb_has_coeffs = idx_mbmode & 1; + if (mb_has_coeffs) + cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_ICBPCY_VLC_BITS, 2); + dst_idx = 0; + for (i=0; i<6; i++) { + s->dc_val[0][s->block_index[i]] = 0; + v->mb_type[0][s->block_index[i]] = 1; + dst_idx += i >> 2; + val = ((cbp >> (5 - i)) & 1); + v->a_avail = v->c_avail = 0; + if(i == 2 || i == 3 || !s->first_slice_line) + v->a_avail = v->mb_type[0][s->block_index[i] - s->block_wrap[i]]; + if(i == 1 || i == 3 || s->mb_x) + v->c_avail = v->mb_type[0][s->block_index[i] - 1]; + + vc1_decode_intra_block(v, s->block[i], i, val, mquant, (i&4)?v->codingset2:v->codingset); + if((i>3) && (s->flags & CODEC_FLAG_GRAY)) 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 + } + } else { + s->mb_intra = v->is_intra[s->mb_x] = 0; + s->current_picture.f.mb_type[mb_pos + v->mb_off] = MB_TYPE_16x16; + for (i = 0; i < 6; i++) v->mb_type[0][s->block_index[i]] = 0; + if (idx_mbmode <= 5) { // 1-MV + dmv_x = dmv_y = 0; + if (idx_mbmode & 1) { + get_mvdata_interlaced(v, &dmv_x, &dmv_y, &pred_flag); + } + vc1_pred_mv(v, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0], pred_flag, 0); + vc1_mc_1mv(v, 0); + mb_has_coeffs = !(idx_mbmode & 2); + } else { // 4-MV + v->fourmvbp = get_vlc2(gb, v->fourmvbp_vlc->table, VC1_4MV_BLOCK_PATTERN_VLC_BITS, 1); + for (i=0; i<6; i++) { + if (i < 4) { + dmv_x = dmv_y = pred_flag = 0; + val = ((v->fourmvbp >> (3 - i)) & 1); + if(val) { + get_mvdata_interlaced(v, &dmv_x, &dmv_y, &pred_flag); + } + vc1_pred_mv(v, i, dmv_x, dmv_y, 0, v->range_x, v->range_y, v->mb_type[0], pred_flag, 0); + vc1_mc_4mv_luma(v, i, 0); + } else if (i == 4) + vc1_mc_4mv_chroma(v, 0); + } + mb_has_coeffs = idx_mbmode & 1; + } + if (mb_has_coeffs) + cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2); + if (cbp) { + GET_MQUANT(); + } + s->current_picture.f.qscale_table[mb_pos] = mquant; + if (!v->ttmbf && cbp) { + ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2); + } + dst_idx = 0; + for (i=0; i<6; i++) { + s->dc_val[0][s->block_index[i]] = 0; + 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, (i&4)?s->uvlinesize:s->linesize, (i&4) && (s->flags & CODEC_FLAG_GRAY), &block_tt); + block_cbp |= pat << (i << 2); + if(!v->ttmbf && ttmb < 8) ttmb = -1; + first_block = 0; + } + } + } + if (s->mb_x == s->mb_width - 1) + memmove(v->is_intra_base, v->is_intra, sizeof(v->is_intra_base[0])*s->mb_stride); + return 0; +} + /** Decode one B-frame MB (in Main profile) */ static void vc1_decode_b_mb(VC1Context *v) @@ -2841,6 +4201,153 @@ static void vc1_decode_b_mb(VC1Context *v) } } +/** Decode one B-frame MB (in interlaced field B picture) + */ +static void vc1_decode_b_mb_intfi(VC1Context *v) +{ + MpegEncContext *s = &v->s; + GetBitContext *gb = &s->gb; + int i, j; + int mb_pos = s->mb_x + s->mb_y * s->mb_stride; + int cbp = 0; /* cbp decoding stuff */ + int mqdiff, mquant; /* MB quantization */ + int ttmb = v->ttfrm; /* MB Transform type */ + int mb_has_coeffs = 0; /* last_flag */ + int val; /* temp value */ + int first_block = 1; + int dst_idx, off; + int fwd; + int dmv_x[2], dmv_y[2], pred_flag[2]; + int bmvtype = BMV_TYPE_BACKWARD; + int idx_mbmode, interpmvp; + + mquant = v->pq; /* Loosy initialization */ + s->mb_intra = 0; + + idx_mbmode = get_vlc2(gb, v->mbmode_vlc->table, VC1_IF_MBMODE_VLC_BITS, 2); + if (idx_mbmode <= 1) { // intra MB + s->mb_intra = v->is_intra[s->mb_x] = 1; + s->current_picture.f.motion_val[1][s->block_index[0]][0] = 0; + s->current_picture.f.motion_val[1][s->block_index[0]][1] = 0; + s->current_picture.f.mb_type[mb_pos + v->mb_off] = MB_TYPE_INTRA; + GET_MQUANT(); + s->current_picture.f.qscale_table[mb_pos] = mquant; + /* Set DC scale - y and c use the same (not sure if necessary here) */ + s->y_dc_scale = s->y_dc_scale_table[mquant]; + s->c_dc_scale = s->c_dc_scale_table[mquant]; + v->s.ac_pred = v->acpred_plane[mb_pos] = get_bits1(gb); + mb_has_coeffs = idx_mbmode & 1; + if (mb_has_coeffs) + cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_ICBPCY_VLC_BITS, 2); + dst_idx = 0; + for (i=0; i<6; i++) { + s->dc_val[0][s->block_index[i]] = 0; + dst_idx += i >> 2; + val = ((cbp >> (5 - i)) & 1); + v->mb_type[0][s->block_index[i]] = s->mb_intra; + v->a_avail = v->c_avail = 0; + if(i == 2 || i == 3 || !s->first_slice_line) + v->a_avail = v->mb_type[0][s->block_index[i] - s->block_wrap[i]]; + if(i == 1 || i == 3 || s->mb_x) + v->c_avail = v->mb_type[0][s->block_index[i] - 1]; + + vc1_decode_intra_block(v, s->block[i], i, val, mquant, (i&4)?v->codingset2:v->codingset); + if((i>3) && (s->flags & CODEC_FLAG_GRAY)) continue; + v->vc1dsp.vc1_inv_trans_8x8(s->block[i]); + if(v->rangeredfrm) 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 + } + } else { + s->mb_intra = v->is_intra[s->mb_x] = 0; + s->current_picture.f.mb_type[mb_pos + v->mb_off] = MB_TYPE_16x16; + for (i = 0; i < 6; i++) v->mb_type[0][s->block_index[i]] = 0; + if (v->fmb_is_raw) + fwd = v->forward_mb_plane[mb_pos] = get_bits1(gb); + else + fwd = v->forward_mb_plane[mb_pos]; + if (idx_mbmode <= 5) { // 1-MV + dmv_x[0] = dmv_x[1] = dmv_y[0] = dmv_y[1] = 0; + pred_flag[0] = pred_flag[1] = 0; + if (fwd) + bmvtype = BMV_TYPE_FORWARD; + else { + bmvtype = decode012(gb); + switch(bmvtype) { + case 0: + bmvtype = BMV_TYPE_BACKWARD; + break; + case 1: + bmvtype = BMV_TYPE_DIRECT; + break; + case 2: + bmvtype = BMV_TYPE_INTERPOLATED; + interpmvp = get_bits1(gb); + } + } + v->bmvtype = bmvtype; + if (bmvtype != BMV_TYPE_DIRECT && idx_mbmode & 1) { + get_mvdata_interlaced(v, &dmv_x[bmvtype == BMV_TYPE_BACKWARD], &dmv_y[bmvtype == BMV_TYPE_BACKWARD], &pred_flag[bmvtype == BMV_TYPE_BACKWARD]); + } + if (bmvtype == BMV_TYPE_INTERPOLATED && interpmvp) { + get_mvdata_interlaced(v, &dmv_x[1], &dmv_y[1], &pred_flag[1]); + } + if (bmvtype == BMV_TYPE_DIRECT) { + dmv_x[0] = dmv_y[0] = pred_flag[0] = 0; + dmv_x[1] = dmv_y[1] = pred_flag[0] = 0; + } + vc1_pred_b_mv_intfi(v, 0, dmv_x, dmv_y, 1, pred_flag); + vc1_b_mc(v, dmv_x, dmv_y, (bmvtype == BMV_TYPE_DIRECT), bmvtype); + mb_has_coeffs = !(idx_mbmode & 2); + } else { // 4-MV + if (fwd) + bmvtype = BMV_TYPE_FORWARD; + v->bmvtype = bmvtype; + v->fourmvbp = get_vlc2(gb, v->fourmvbp_vlc->table, VC1_4MV_BLOCK_PATTERN_VLC_BITS, 1); + for (i=0; i<6; i++) { + if (i < 4) { + dmv_x[0] = dmv_y[0] = pred_flag[0] = 0; + dmv_x[1] = dmv_y[1] = pred_flag[1] = 0; + val = ((v->fourmvbp >> (3 - i)) & 1); + if(val) { + get_mvdata_interlaced(v, &dmv_x[bmvtype == BMV_TYPE_BACKWARD], &dmv_y[bmvtype == BMV_TYPE_BACKWARD], &pred_flag[bmvtype == BMV_TYPE_BACKWARD]); + } + vc1_pred_b_mv_intfi(v, i, dmv_x, dmv_y, 0, pred_flag); + vc1_mc_4mv_luma(v, i, bmvtype == BMV_TYPE_BACKWARD); + } else if (i == 4) + vc1_mc_4mv_chroma(v, bmvtype == BMV_TYPE_BACKWARD); + } + mb_has_coeffs = idx_mbmode & 1; + } + if (mb_has_coeffs) + cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2); + if (cbp) { + GET_MQUANT(); + } + s->current_picture.f.qscale_table[mb_pos] = mquant; + if (!v->ttmbf && cbp) { + ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2); + } + dst_idx = 0; + for (i=0; i<6; i++) { + s->dc_val[0][s->block_index[i]] = 0; + 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, (i&4)?s->uvlinesize:s->linesize, (i&4) && (s->flags & CODEC_FLAG_GRAY), NULL); + if(!v->ttmbf && ttmb < 8) + ttmb = -1; + first_block = 0; + } + } + } +} + /** Decode blocks of I-frame */ static void vc1_decode_i_blocks(VC1Context *v) @@ -3029,13 +4536,15 @@ static void vc1_decode_i_blocks_adv(VC1Context *v) ff_update_block_index(s); s->dsp.clear_blocks(block[0]); mb_pos = s->mb_x + s->mb_y * s->mb_stride; - s->current_picture.f.mb_type[mb_pos] = MB_TYPE_INTRA; - s->current_picture.f.motion_val[1][s->block_index[0]][0] = 0; - s->current_picture.f.motion_val[1][s->block_index[0]][1] = 0; + s->current_picture.f.mb_type[mb_pos + v->mb_off] = MB_TYPE_INTRA; + s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0; + s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0; // do actual MB decoding and displaying + if (v->fieldtx_is_raw) + v->fieldtx_plane[mb_pos] = get_bits1(&v->s.gb); cbp = get_vlc2(&v->s.gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2); - if(v->acpred_is_raw) + if( v->acpred_is_raw) v->s.ac_pred = get_bits1(&v->s.gb); else v->s.ac_pred = v->acpred_plane[mb_pos]; @@ -3074,6 +4583,7 @@ static void vc1_decode_i_blocks_adv(VC1Context *v) if(v->s.loop_filter) vc1_loop_filter_iblk_delayed(v, v->pq); if(get_bits_count(&s->gb) > v->bits) { + // TODO: may need modification to handle slice coding ff_er_add_slice(s, 0, s->start_mb_y, s->mb_x, s->mb_y, (AC_END|DC_END|MV_END)); av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i\n", get_bits_count(&s->gb), v->bits); return; @@ -3096,7 +4606,7 @@ static void vc1_decode_i_blocks_adv(VC1Context *v) } if (v->s.loop_filter) ff_draw_horiz_band(s, (s->end_mb_y-1)*16, 16); - ff_er_add_slice(s, 0, s->start_mb_y, s->mb_width - 1, s->end_mb_y - 1, (AC_END|DC_END|MV_END)); + ff_er_add_slice(s, 0, s->start_mb_y << v->field_mode, s->mb_width - 1, (s->end_mb_y << v->field_mode) - 1, (AC_END|DC_END|MV_END)); } static void vc1_decode_p_blocks(VC1Context *v) @@ -3138,10 +4648,15 @@ static void vc1_decode_p_blocks(VC1Context *v) for(; s->mb_x < s->mb_width; s->mb_x++) { ff_update_block_index(s); - vc1_decode_p_mb(v); - if (s->mb_y != s->start_mb_y && apply_loop_filter) + if (v->fcm == 2) + vc1_decode_p_mb_intfi(v); + else if (v->fcm == 1) + vc1_decode_p_mb_intfr(v); + else vc1_decode_p_mb(v); + if (s->mb_y != s->start_mb_y && apply_loop_filter && v->fcm == 0) vc1_apply_p_loop_filter(v); if(get_bits_count(&s->gb) > v->bits || get_bits_count(&s->gb) < 0) { + // TODO: may need modification to handle slice coding ff_er_add_slice(s, 0, s->start_mb_y, s->mb_x, s->mb_y, (AC_END|DC_END|MV_END)); av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i at %ix%i\n", get_bits_count(&s->gb), v->bits,s->mb_x,s->mb_y); return; @@ -3164,7 +4679,7 @@ static void vc1_decode_p_blocks(VC1Context *v) } if (s->end_mb_y >= s->start_mb_y) ff_draw_horiz_band(s, (s->end_mb_y-1) * 16, 16); - ff_er_add_slice(s, 0, s->start_mb_y, s->mb_width - 1, s->end_mb_y - 1, (AC_END|DC_END|MV_END)); + ff_er_add_slice(s, 0, s->start_mb_y << v->field_mode, s->mb_width - 1, (s->end_mb_y << v->field_mode) - 1, (AC_END|DC_END|MV_END)); } static void vc1_decode_b_blocks(VC1Context *v) @@ -3203,8 +4718,12 @@ static void vc1_decode_b_blocks(VC1Context *v) for(; s->mb_x < s->mb_width; s->mb_x++) { ff_update_block_index(s); - vc1_decode_b_mb(v); + if (v->fcm == 2) + vc1_decode_b_mb_intfi(v); + else + vc1_decode_b_mb(v); if(get_bits_count(&s->gb) > v->bits || get_bits_count(&s->gb) < 0) { + // TODO: may need modification to handle slice coding ff_er_add_slice(s, 0, s->start_mb_y, s->mb_x, s->mb_y, (AC_END|DC_END|MV_END)); av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i at %ix%i\n", get_bits_count(&s->gb), v->bits,s->mb_x,s->mb_y); return; @@ -3219,7 +4738,7 @@ static void vc1_decode_b_blocks(VC1Context *v) } if (v->s.loop_filter) ff_draw_horiz_band(s, (s->end_mb_y-1)*16, 16); - ff_er_add_slice(s, 0, s->start_mb_y, s->mb_width - 1, s->end_mb_y - 1, (AC_END|DC_END|MV_END)); + ff_er_add_slice(s, 0, s->start_mb_y << v->field_mode, s->mb_width - 1, (s->end_mb_y << v->field_mode) - 1, (AC_END|DC_END|MV_END)); } static void vc1_decode_skip_blocks(VC1Context *v) @@ -3559,6 +5078,8 @@ static av_cold int vc1_decode_init_alloc_tables(VC1Context *v) /* Allocate mb bitplanes */ v->mv_type_mb_plane = av_malloc(s->mb_stride * s->mb_height); v->direct_mb_plane = av_malloc(s->mb_stride * s->mb_height); + v->forward_mb_plane = av_malloc(s->mb_stride * s->mb_height); + v->fieldtx_plane = av_mallocz(s->mb_stride * s->mb_height); v->acpred_plane = av_malloc(s->mb_stride * s->mb_height); v->over_flags_plane = av_malloc(s->mb_stride * s->mb_height); @@ -3568,7 +5089,7 @@ static av_cold int vc1_decode_init_alloc_tables(VC1Context *v) v->cbp = v->cbp_base + s->mb_stride; v->ttblk_base = av_malloc(sizeof(v->ttblk_base[0]) * 2 * s->mb_stride); v->ttblk = v->ttblk_base + s->mb_stride; - v->is_intra_base = av_malloc(sizeof(v->is_intra_base[0]) * 2 * s->mb_stride); + v->is_intra_base = av_mallocz(sizeof(v->is_intra_base[0]) * 2 * s->mb_stride); v->is_intra = v->is_intra_base + s->mb_stride; v->luma_mv_base = av_malloc(sizeof(v->luma_mv_base[0]) * 2 * s->mb_stride); v->luma_mv = v->luma_mv_base + s->mb_stride; @@ -3579,6 +5100,19 @@ static av_cold int vc1_decode_init_alloc_tables(VC1Context *v) v->mb_type[1] = v->mb_type_base + s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride + 1; v->mb_type[2] = v->mb_type[1] + s->mb_stride * (s->mb_height + 1); + /* allocate memory to store block level MV info */ + v->blk_mv_type_base = av_mallocz(s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2); + v->blk_mv_type = v->blk_mv_type_base + s->b8_stride + 1; + v->mv_f_base = av_mallocz(2 * (s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2)); + v->mv_f[0] = v->mv_f_base + s->b8_stride + 1; + v->mv_f[1] = v->mv_f[0] + (s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2); + v->mv_f_last_base = av_mallocz(2 * (s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2)); + v->mv_f_last[0] = v->mv_f_last_base + s->b8_stride + 1; + v->mv_f_last[1] = v->mv_f_last[0] + (s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2); + v->mv_f_next_base = av_mallocz(2 * (s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2)); + v->mv_f_next[0] = v->mv_f_next_base + s->b8_stride + 1; + v->mv_f_next[1] = v->mv_f_next[0] + (s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2); + /* Init coded blocks info */ if (v->profile == PROFILE_ADVANCED) { @@ -3722,6 +5256,7 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx) v->zz_8x8[1][i] = transpose(wmv1_scantable[1][i]); v->zz_8x8[2][i] = transpose(wmv1_scantable[2][i]); v->zz_8x8[3][i] = transpose(wmv1_scantable[3][i]); + v->zzi_8x8[i] = transpose(ff_vc1_adv_interlaced_8x8_zz[i]); } v->left_blk_sh = 0; v->top_blk_sh = 3; @@ -3765,9 +5300,15 @@ static av_cold int vc1_decode_end(AVCodecContext *avctx) MPV_common_end(&v->s); av_freep(&v->mv_type_mb_plane); av_freep(&v->direct_mb_plane); + av_freep(&v->forward_mb_plane); + av_freep(&v->fieldtx_plane); av_freep(&v->acpred_plane); av_freep(&v->over_flags_plane); av_freep(&v->mb_type_base); + av_freep(&v->blk_mv_type_base); + av_freep(&v->mv_f_base); + av_freep(&v->mv_f_last_base); + av_freep(&v->mv_f_next_base); av_freep(&v->block); av_freep(&v->cbp_base); av_freep(&v->ttblk_base); @@ -3791,7 +5332,9 @@ static int vc1_decode_frame(AVCodecContext *avctx, MpegEncContext *s = &v->s; AVFrame *pict = data; uint8_t *buf2 = NULL; + uint8_t *buf_field2 = NULL; const uint8_t *buf_start = buf; + int mb_height, n_slices1; struct { uint8_t *buf; GetBitContext gb; @@ -3839,6 +5382,26 @@ static int vc1_decode_frame(AVCodecContext *avctx, buf_start = start; buf_size2 = vc1_unescape_buffer(start + 4, size, buf2); break; + case VC1_CODE_FIELD: { + int buf_size3; + slices = av_realloc(slices, sizeof(*slices) * (n_slices+1)); + if (!slices) goto err; + slices[n_slices].buf = av_mallocz(buf_size + FF_INPUT_BUFFER_PADDING_SIZE); + if (!slices[n_slices].buf) goto err; + buf_size3 = vc1_unescape_buffer(start + 4, size, + slices[n_slices].buf); + init_get_bits(&slices[n_slices].gb, slices[n_slices].buf, + buf_size3 << 3); + /* assuming that the field marker is at the exact middle, + hope it's correct */ + slices[n_slices].mby_start = s->mb_height >> 1; + n_slices1 = n_slices - 1; // index of the last slice of the first field + n_slices++; + // not necessary, ad hoc until I find a way to handle WVC1i + buf_field2 = av_mallocz(buf_size + FF_INPUT_BUFFER_PADDING_SIZE); + vc1_unescape_buffer(start + 4, size, buf_field2); + break; + } case VC1_CODE_ENTRYPOINT: /* it should be before frame data */ buf_size2 = vc1_unescape_buffer(start + 4, size, buf2); init_get_bits(&s->gb, buf2, buf_size2*8); @@ -3867,13 +5430,11 @@ static int vc1_decode_frame(AVCodecContext *avctx, if((divider == (buf + buf_size)) || AV_RB32(divider) != VC1_CODE_FIELD){ av_log(avctx, AV_LOG_ERROR, "Error in WVC1 interlaced frame\n"); goto err; + } else { // found field marker, unescape second field + buf_field2 = av_mallocz(buf_size + FF_INPUT_BUFFER_PADDING_SIZE); + vc1_unescape_buffer(divider + 4, buf + buf_size - divider - 4, buf_field2); } - buf_size2 = vc1_unescape_buffer(buf, divider - buf, buf2); - // TODO - if(!v->warn_interlaced++) - av_log(v->s.avctx, AV_LOG_ERROR, "Interlaced WVC1 support is not implemented\n"); - goto err; }else{ buf_size2 = vc1_unescape_buffer(buf, buf_size, buf2); } @@ -3925,6 +5486,7 @@ static int vc1_decode_frame(AVCodecContext *avctx, } // do parse frame header + v->pic_header_flag = 0; if(v->profile < PROFILE_ADVANCED) { if(vc1_parse_frame_header(v, &s->gb) == -1) { goto err; @@ -3995,13 +5557,65 @@ static int vc1_decode_frame(AVCodecContext *avctx, ff_er_frame_start(s); v->bits = buf_size * 8; + if (v->field_mode) { + uint8_t *tmp[2]; + s->current_picture.f.linesize[0] <<= 1; + s->current_picture.f.linesize[1] <<= 1; + s->current_picture.f.linesize[2] <<= 1; + s->linesize <<= 1; + s->uvlinesize <<= 1; + tmp[0] = v->mv_f_last[0]; + tmp[1] = v->mv_f_last[1]; + v->mv_f_last[0] = v->mv_f_next[0]; + v->mv_f_last[1] = v->mv_f_next[1]; + v->mv_f_next[0] = v->mv_f[0]; + v->mv_f_next[1] = v->mv_f[1]; + v->mv_f[0] = tmp[0]; + v->mv_f[1] = tmp[1]; + } + mb_height = s->mb_height >> v->field_mode; for (i = 0; i <= n_slices; i++) { - if (i && get_bits1(&s->gb)) - vc1_parse_frame_header_adv(v, &s->gb); - s->start_mb_y = (i == 0) ? 0 : FFMAX(0, slices[i-1].mby_start); - s->end_mb_y = (i == n_slices) ? s->mb_height : FFMIN(s->mb_height, slices[i].mby_start); + if (i > 0 && slices[i - 1].mby_start >= mb_height) { + v->second_field = 1; + v->blocks_off = s->mb_width * s->mb_height << 1; + v->mb_off = s->mb_stride * s->mb_height >> 1; + } else { + v->second_field = 0; + v->blocks_off = 0; + v->mb_off = 0; + } + if (i) { + v->pic_header_flag = 0; + if (v->field_mode && i == n_slices1 + 2) + vc1_parse_frame_header_adv(v, &s->gb); + else if (get_bits1(&s->gb)) { + v->pic_header_flag = 1; + vc1_parse_frame_header_adv(v, &s->gb); + } + } + s->start_mb_y = (i == 0) ? 0 : FFMAX(0, slices[i-1].mby_start % mb_height); + if (!v->field_mode || v->second_field) + s->end_mb_y = (i == n_slices ) ? mb_height : FFMIN(mb_height, slices[i].mby_start % mb_height); + else + s->end_mb_y = (i == n_slices1 + 1) ? mb_height : FFMIN(mb_height, slices[i].mby_start % mb_height); vc1_decode_blocks(v); - if (i != n_slices) s->gb = slices[i].gb; + if (i != n_slices) + s->gb = slices[i].gb; + } + if (v->field_mode) { + av_free(buf_field2); + v->second_field = 0; + } + if(v->field_mode){ + if (s->pict_type == AV_PICTURE_TYPE_B) { + memcpy(v->mv_f_base, v->mv_f_next_base, + 2 * (s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2)); + } + s->current_picture.f.linesize[0] >>= 1; + s->current_picture.f.linesize[1] >>= 1; + s->current_picture.f.linesize[2] >>= 1; + s->linesize >>= 1; + s->uvlinesize >>= 1; } //av_log(s->avctx, AV_LOG_INFO, "Consumed %i/%i bits\n", get_bits_count(&s->gb), s->gb.size_in_bits); // if(get_bits_count(&s->gb) > buf_size * 8) @@ -4011,9 +5625,6 @@ static int vc1_decode_frame(AVCodecContext *avctx, MPV_frame_end(s); -assert(s->current_picture.f.pict_type == s->current_picture_ptr->f.pict_type); -assert(s->current_picture.f.pict_type == s->pict_type); - if (avctx->codec_id == CODEC_ID_WMV3IMAGE || avctx->codec_id == CODEC_ID_VC1IMAGE) { image: avctx->width = avctx->coded_width = v->output_width; @@ -4051,6 +5662,7 @@ err: for (i = 0; i < n_slices; i++) av_free(slices[i].buf); av_free(slices); + av_free(buf_field2); return -1; } diff --git a/libavcodec/vc1dsp.c b/libavcodec/vc1dsp.c index 4dd56727c7..77725095c3 100644 --- a/libavcodec/vc1dsp.c +++ b/libavcodec/vc1dsp.c @@ -688,6 +688,26 @@ static void put_no_rnd_vc1_chroma_mc8_c(uint8_t *dst/*align 8*/, uint8_t *src/*a } } +static void put_no_rnd_vc1_chroma_mc4_c(uint8_t *dst, uint8_t *src, int stride, int h, int x, int y){ + const int A=(8-x)*(8-y); + const int B=( x)*(8-y); + const int C=(8-x)*( y); + const int D=( x)*( y); + int i; + + assert(x<8 && y<8 && x>=0 && y>=0); + + for(i=0; i> 6; + dst[1] = (A*src[1] + B*src[2] + C*src[stride+1] + D*src[stride+2] + 32 - 4) >> 6; + dst[2] = (A*src[2] + B*src[3] + C*src[stride+2] + D*src[stride+3] + 32 - 4) >> 6; + dst[3] = (A*src[3] + B*src[4] + C*src[stride+3] + D*src[stride+4] + 32 - 4) >> 6; + dst+= stride; + src+= stride; + } +} + #define avg2(a,b) ((a+b+1)>>1) static void avg_no_rnd_vc1_chroma_mc8_c(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y){ const int A=(8-x)*(8-y); @@ -829,6 +849,7 @@ av_cold void ff_vc1dsp_init(VC1DSPContext* dsp) { dsp->put_no_rnd_vc1_chroma_pixels_tab[0]= put_no_rnd_vc1_chroma_mc8_c; dsp->avg_no_rnd_vc1_chroma_pixels_tab[0]= avg_no_rnd_vc1_chroma_mc8_c; + dsp->put_no_rnd_vc1_chroma_pixels_tab[1] = put_no_rnd_vc1_chroma_mc4_c; #if CONFIG_WMV3IMAGE_DECODER || CONFIG_VC1IMAGE_DECODER dsp->sprite_h = sprite_h_c; From 51757ac7894ef85abe4ae76624511c2e14b7bd6b Mon Sep 17 00:00:00 2001 From: Mashiat Sarker Shakkhar Date: Fri, 7 Oct 2011 00:00:27 +0500 Subject: [PATCH 07/34] lavc: Micro version bump for VC1 interlaced decoding support Signed-off-by: Anton Khirnov --- Changelog | 1 + libavcodec/version.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Changelog b/Changelog index 48ce306fea..c2f16b367b 100644 --- a/Changelog +++ b/Changelog @@ -49,6 +49,7 @@ easier to use. The changes are: - select filter - Apple ProRes decoder - CELT in Ogg demuxing +- VC-1 interlaced decoding version 0.7: diff --git a/libavcodec/version.h b/libavcodec/version.h index d9e60cca01..5657511d80 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -22,7 +22,7 @@ #define LIBAVCODEC_VERSION_MAJOR 53 #define LIBAVCODEC_VERSION_MINOR 12 -#define LIBAVCODEC_VERSION_MICRO 1 +#define LIBAVCODEC_VERSION_MICRO 2 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ From 80bdf7e0b7975956c42f17589cb21a5531f179ef Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 14 Sep 2011 14:24:02 -0400 Subject: [PATCH 08/34] ra144dec: use a more descriptive calculation for output data size --- libavcodec/ra144dec.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libavcodec/ra144dec.c b/libavcodec/ra144dec.c index 10c85b72e2..6707601643 100644 --- a/libavcodec/ra144dec.c +++ b/libavcodec/ra144dec.c @@ -64,13 +64,15 @@ static int ra144_decode_frame(AVCodecContext * avctx, void *vdata, uint16_t block_coefs[4][10]; // LPC coefficients of each sub-block unsigned int lpc_refl[10]; // LPC reflection coefficients of the frame int i, j; + int out_size; int16_t *data = vdata; unsigned int energy; RA144Context *ractx = avctx->priv_data; GetBitContext gb; - if (*data_size < 2*160) + out_size = NBLOCKS * BLOCKSIZE * av_get_bytes_per_sample(avctx->sample_fmt); + if (*data_size < out_size) return -1; if(buf_size < 20) { @@ -110,7 +112,7 @@ static int ra144_decode_frame(AVCodecContext * avctx, void *vdata, FFSWAP(unsigned int *, ractx->lpc_coef[0], ractx->lpc_coef[1]); - *data_size = 2*160; + *data_size = out_size; return 20; } From cadd4d332a48d37d0248eafe955050f4f7d08eb5 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 14 Sep 2011 14:24:59 -0400 Subject: [PATCH 09/34] ra144dec: log an error message when output buffer is too small. also return AVERROR(EINVAL) instead of -1. --- libavcodec/ra144dec.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libavcodec/ra144dec.c b/libavcodec/ra144dec.c index 6707601643..f026e24ccd 100644 --- a/libavcodec/ra144dec.c +++ b/libavcodec/ra144dec.c @@ -72,8 +72,10 @@ static int ra144_decode_frame(AVCodecContext * avctx, void *vdata, GetBitContext gb; out_size = NBLOCKS * BLOCKSIZE * av_get_bytes_per_sample(avctx->sample_fmt); - if (*data_size < out_size) - return -1; + if (*data_size < out_size) { + av_log(avctx, AV_LOG_ERROR, "Output buffer is too small\n"); + return AVERROR(EINVAL); + } if(buf_size < 20) { av_log(avctx, AV_LOG_ERROR, From f10524d51c1c957b58d0ceda171310caf9eaed96 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 14 Sep 2011 14:42:31 -0400 Subject: [PATCH 10/34] ra144: use macro constants to make the code more understandable. --- libavcodec/ra144.c | 40 ++++++++++++++++++++-------------------- libavcodec/ra144dec.c | 18 +++++++++--------- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/libavcodec/ra144.c b/libavcodec/ra144.c index fd2ed3299d..e6442d694d 100644 --- a/libavcodec/ra144.c +++ b/libavcodec/ra144.c @@ -1544,22 +1544,22 @@ void ff_copy_and_dup(int16_t *target, const int16_t *source, int offset) int ff_eval_refl(int *refl, const int16_t *coefs, AVCodecContext *avctx) { int b, i, j; - int buffer1[10]; - int buffer2[10]; + int buffer1[LPC_ORDER]; + int buffer2[LPC_ORDER]; int *bp1 = buffer1; int *bp2 = buffer2; - for (i=0; i < 10; i++) + for (i=0; i < LPC_ORDER; i++) buffer2[i] = coefs[i]; - refl[9] = bp2[9]; + refl[LPC_ORDER-1] = bp2[LPC_ORDER-1]; - if ((unsigned) bp2[9] + 0x1000 > 0x1fff) { + if ((unsigned) bp2[LPC_ORDER-1] + 0x1000 > 0x1fff) { av_log(avctx, AV_LOG_ERROR, "Overflow. Broken sample?\n"); return 1; } - for (i=8; i >= 0; i--) { + for (i = LPC_ORDER-2; i >= 0; i--) { b = 0x1000-((bp2[i+1] * bp2[i+1]) >> 12); if (!b) @@ -1584,12 +1584,12 @@ int ff_eval_refl(int *refl, const int16_t *coefs, AVCodecContext *avctx) */ void ff_eval_coefs(int *coefs, const int *refl) { - int buffer[10]; + int buffer[LPC_ORDER]; int *b1 = buffer; int *b2 = coefs; int i, j; - for (i=0; i < 10; i++) { + for (i=0; i < LPC_ORDER; i++) { b1[i] = refl[i] << 4; for (j=0; j < i; j++) @@ -1598,7 +1598,7 @@ void ff_eval_coefs(int *coefs, const int *refl) FFSWAP(int *, b1, b2); } - for (i=0; i < 10; i++) + for (i=0; i < LPC_ORDER; i++) coefs[i] >>= 4; } @@ -1606,7 +1606,7 @@ void ff_int_to_int16(int16_t *out, const int *inp) { int i; - for (i=0; i < 10; i++) + for (i = 0; i < LPC_ORDER; i++) *out++ = *inp++; } @@ -1629,9 +1629,9 @@ unsigned int ff_rms(const int *data) { int i; unsigned int res = 0x10000; - int b = 10; + int b = LPC_ORDER; - for (i=0; i < 10; i++) { + for (i = 0; i < LPC_ORDER; i++) { res = (((0x1000000 - data[i]*data[i]) >> 12) * res) >> 12; if (res == 0) @@ -1648,13 +1648,13 @@ unsigned int ff_rms(const int *data) int ff_interp(RA144Context *ractx, int16_t *out, int a, int copyold, int energy) { - int work[10]; + int work[LPC_ORDER]; int b = NBLOCKS - a; int i; // Interpolate block coefficients from the this frame's forth block and // last frame's forth block. - for (i=0; i<10; i++) + for (i = 0; i < LPC_ORDER; i++) out[i] = (a * ractx->lpc_coef[0][i] + b * ractx->lpc_coef[1][i])>> 2; if (ff_eval_refl(work, out, ractx->avctx)) { @@ -1690,7 +1690,7 @@ void ff_subblock_synthesis(RA144Context *ractx, const uint16_t *lpc_coefs, int cba_idx, int cb1_idx, int cb2_idx, int gval, int gain) { - uint16_t buffer_a[40]; + uint16_t buffer_a[BLOCKSIZE]; uint16_t *block; int m[3]; @@ -1711,10 +1711,10 @@ void ff_subblock_synthesis(RA144Context *ractx, const uint16_t *lpc_coefs, ff_add_wav(block, gain, cba_idx, m, cba_idx? buffer_a: NULL, ff_cb1_vects[cb1_idx], ff_cb2_vects[cb2_idx]); - memcpy(ractx->curr_sblock, ractx->curr_sblock + 40, - 10*sizeof(*ractx->curr_sblock)); + memcpy(ractx->curr_sblock, ractx->curr_sblock + BLOCKSIZE, + LPC_ORDER*sizeof(*ractx->curr_sblock)); - if (ff_celp_lp_synthesis_filter(ractx->curr_sblock + 10, lpc_coefs, - block, BLOCKSIZE, 10, 1, 0xfff)) - memset(ractx->curr_sblock, 0, 50*sizeof(*ractx->curr_sblock)); + if (ff_celp_lp_synthesis_filter(ractx->curr_sblock + LPC_ORDER, lpc_coefs, + block, BLOCKSIZE, LPC_ORDER, 1, 0xfff)) + memset(ractx->curr_sblock, 0, (LPC_ORDER+BLOCKSIZE)*sizeof(*ractx->curr_sblock)); } diff --git a/libavcodec/ra144dec.c b/libavcodec/ra144dec.c index f026e24ccd..5fff696d83 100644 --- a/libavcodec/ra144dec.c +++ b/libavcodec/ra144dec.c @@ -59,10 +59,10 @@ static int ra144_decode_frame(AVCodecContext * avctx, void *vdata, { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; - static const uint8_t sizes[10] = {6, 5, 5, 4, 4, 3, 3, 3, 3, 2}; - unsigned int refl_rms[4]; // RMS of the reflection coefficients - uint16_t block_coefs[4][10]; // LPC coefficients of each sub-block - unsigned int lpc_refl[10]; // LPC reflection coefficients of the frame + static const uint8_t sizes[LPC_ORDER] = {6, 5, 5, 4, 4, 3, 3, 3, 3, 2}; + unsigned int refl_rms[NBLOCKS]; // RMS of the reflection coefficients + uint16_t block_coefs[NBLOCKS][LPC_ORDER]; // LPC coefficients of each sub-block + unsigned int lpc_refl[LPC_ORDER]; // LPC reflection coefficients of the frame int i, j; int out_size; int16_t *data = vdata; @@ -77,15 +77,15 @@ static int ra144_decode_frame(AVCodecContext * avctx, void *vdata, return AVERROR(EINVAL); } - if(buf_size < 20) { + if(buf_size < FRAMESIZE) { av_log(avctx, AV_LOG_ERROR, "Frame too small (%d bytes). Truncated file?\n", buf_size); *data_size = 0; return buf_size; } - init_get_bits(&gb, buf, 20 * 8); + init_get_bits(&gb, buf, FRAMESIZE * 8); - for (i=0; i<10; i++) + for (i = 0; i < LPC_ORDER; i++) lpc_refl[i] = ff_lpc_refl_cb[i][get_bits(&gb, sizes[i])]; ff_eval_coefs(ractx->lpc_coef[0], lpc_refl); @@ -102,7 +102,7 @@ static int ra144_decode_frame(AVCodecContext * avctx, void *vdata, ff_int_to_int16(block_coefs[3], ractx->lpc_coef[0]); - for (i=0; i < 4; i++) { + for (i=0; i < NBLOCKS; i++) { do_output_subblock(ractx, block_coefs[i], refl_rms[i], &gb); for (j=0; j < BLOCKSIZE; j++) @@ -115,7 +115,7 @@ static int ra144_decode_frame(AVCodecContext * avctx, void *vdata, FFSWAP(unsigned int *, ractx->lpc_coef[0], ractx->lpc_coef[1]); *data_size = out_size; - return 20; + return FRAMESIZE; } AVCodec ff_ra_144_decoder = { From fa6be04bf7121042ccac24bae2c2dfffba400920 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 14 Sep 2011 14:46:02 -0400 Subject: [PATCH 11/34] ra288: use a more descriptive calculation for output data size --- libavcodec/ra288.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/libavcodec/ra288.c b/libavcodec/ra288.c index a0b86a2bf0..f14c28dc8d 100644 --- a/libavcodec/ra288.c +++ b/libavcodec/ra288.c @@ -31,6 +31,9 @@ #define MAX_BACKWARD_FILTER_LEN 40 #define MAX_BACKWARD_FILTER_NONREC 35 +#define RA288_BLOCK_SIZE 5 +#define RA288_BLOCKS_PER_FRAME 32 + typedef struct { float sp_lpc[36]; ///< LPC coefficients for speech data (spec: A) float gain_lpc[10]; ///< LPC coefficients for gain (spec: GB) @@ -165,7 +168,7 @@ static int ra288_decode_frame(AVCodecContext * avctx, void *data, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; float *out = data; - int i, j; + int i, j, out_size; RA288Context *ractx = avctx->priv_data; GetBitContext gb; @@ -176,18 +179,20 @@ static int ra288_decode_frame(AVCodecContext * avctx, void *data, return 0; } - if (*data_size < 32*5*4) + out_size = RA288_BLOCK_SIZE * RA288_BLOCKS_PER_FRAME * + av_get_bytes_per_sample(avctx->sample_fmt); + if (*data_size < out_size) return -1; init_get_bits(&gb, buf, avctx->block_align * 8); - for (i=0; i < 32; i++) { + for (i=0; i < RA288_BLOCKS_PER_FRAME; i++) { float gain = amptable[get_bits(&gb, 3)]; int cb_coef = get_bits(&gb, 6 + (i&1)); decode(ractx, gain, cb_coef); - for (j=0; j < 5; j++) + for (j=0; j < RA288_BLOCK_SIZE; j++) *(out++) = ractx->sp_hist[70 + 36 + j]; if ((i & 7) == 3) { @@ -199,7 +204,7 @@ static int ra288_decode_frame(AVCodecContext * avctx, void *data, } } - *data_size = (char *)out - (char *)data; + *data_size = out_size; return avctx->block_align; } From 8f8f5ae9918460c358d8d8212e8c19cf3bdad374 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 14 Sep 2011 14:46:50 -0400 Subject: [PATCH 12/34] ra288: log an error message when output buffer is too small. also return AVERROR(EINVAL) instead of -1. --- libavcodec/ra288.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libavcodec/ra288.c b/libavcodec/ra288.c index f14c28dc8d..2166d8ca61 100644 --- a/libavcodec/ra288.c +++ b/libavcodec/ra288.c @@ -181,8 +181,10 @@ static int ra288_decode_frame(AVCodecContext * avctx, void *data, out_size = RA288_BLOCK_SIZE * RA288_BLOCKS_PER_FRAME * av_get_bytes_per_sample(avctx->sample_fmt); - if (*data_size < out_size) - return -1; + if (*data_size < out_size) { + av_log(avctx, AV_LOG_ERROR, "Output buffer is too small\n"); + return AVERROR(EINVAL); + } init_get_bits(&gb, buf, avctx->block_align * 8); From 109d8aa1e61b17421d04ce67b806c2e909d8d49e Mon Sep 17 00:00:00 2001 From: Kostya Shishkov Date: Mon, 10 Oct 2011 16:04:58 +0200 Subject: [PATCH 13/34] vc1: K&R reformatting cosmetics Signed-off-by: Diego Biurrun --- libavcodec/vc1.c | 633 +++++++++++++++++++++++------------------------ 1 file changed, 315 insertions(+), 318 deletions(-) diff --git a/libavcodec/vc1.c b/libavcodec/vc1.c index 11d1d58e44..9d36811c2c 100644 --- a/libavcodec/vc1.c +++ b/libavcodec/vc1.c @@ -26,6 +26,7 @@ * VC-1 and WMV3 decoder common code * */ + #include "internal.h" #include "dsputil.h" #include "avcodec.h" @@ -67,14 +68,16 @@ enum Imode { * @param[in] height Height of this buffer * @param[in] stride of this buffer */ -static void decode_rowskip(uint8_t* plane, int width, int height, int stride, GetBitContext *gb){ +static void decode_rowskip(uint8_t* plane, int width, int height, int stride, + GetBitContext *gb) +{ int x, y; - for (y=0; ys.mb_width; + width = v->s.mb_width; height = v->s.mb_height >> v->field_mode; stride = v->s.mb_stride; invert = get_bits1(gb); imode = get_vlc2(gb, ff_vc1_imode_vlc.table, VC1_IMODE_VLC_BITS, 1); *raw_flag = 0; - switch (imode) - { + switch (imode) { case IMODE_RAW: //Data is actually read in the MB layer (same for all tests == "raw") *raw_flag = 1; //invert ignored return invert; case IMODE_DIFF2: case IMODE_NORM2: - if ((height * width) & 1) - { + if ((height * width) & 1) { *planep++ = get_bits1(gb); - offset = 1; + offset = 1; } - else offset = 0; + else + offset = 0; // decode bitplane as one long line for (y = offset; y < height * width; y += 2) { code = get_vlc2(gb, ff_vc1_norm2_vlc.table, VC1_NORM2_VLC_BITS, 1); *planep++ = code & 1; offset++; - if(offset == width) { - offset = 0; + if (offset == width) { + offset = 0; planep += stride - width; } *planep++ = code >> 1; offset++; - if(offset == width) { - offset = 0; + if (offset == width) { + offset = 0; planep += stride - width; } } break; case IMODE_DIFF6: case IMODE_NORM6: - if(!(height % 3) && (width % 3)) { // use 2x3 decoding - for(y = 0; y < height; y+= 3) { - for(x = width & 1; x < width; x += 2) { + if (!(height % 3) && (width % 3)) { // use 2x3 decoding + for (y = 0; y < height; y += 3) { + for (x = width & 1; x < width; x += 2) { code = get_vlc2(gb, ff_vc1_norm6_vlc.table, VC1_NORM6_VLC_BITS, 2); - if(code < 0){ + if (code < 0) { av_log(v->s.avctx, AV_LOG_DEBUG, "invalid NORM-6 VLC\n"); return -1; } - planep[x + 0] = (code >> 0) & 1; - planep[x + 1] = (code >> 1) & 1; - planep[x + 0 + stride] = (code >> 2) & 1; - planep[x + 1 + stride] = (code >> 3) & 1; + planep[x + 0] = (code >> 0) & 1; + planep[x + 1] = (code >> 1) & 1; + planep[x + 0 + stride] = (code >> 2) & 1; + planep[x + 1 + stride] = (code >> 3) & 1; planep[x + 0 + stride * 2] = (code >> 4) & 1; planep[x + 1 + stride * 2] = (code >> 5) & 1; } planep += stride * 3; } - if(width & 1) decode_colskip(data, 1, height, stride, &v->s.gb); + if (width & 1) + decode_colskip(data, 1, height, stride, &v->s.gb); } else { // 3x2 planep += (height & 1) * stride; - for(y = height & 1; y < height; y += 2) { - for(x = width % 3; x < width; x += 3) { + for (y = height & 1; y < height; y += 2) { + for (x = width % 3; x < width; x += 3) { code = get_vlc2(gb, ff_vc1_norm6_vlc.table, VC1_NORM6_VLC_BITS, 2); - if(code < 0){ + if (code < 0) { av_log(v->s.avctx, AV_LOG_DEBUG, "invalid NORM-6 VLC\n"); return -1; } - planep[x + 0] = (code >> 0) & 1; - planep[x + 1] = (code >> 1) & 1; - planep[x + 2] = (code >> 2) & 1; + planep[x + 0] = (code >> 0) & 1; + planep[x + 1] = (code >> 1) & 1; + planep[x + 2] = (code >> 2) & 1; planep[x + 0 + stride] = (code >> 3) & 1; planep[x + 1 + stride] = (code >> 4) & 1; planep[x + 2 + stride] = (code >> 5) & 1; @@ -193,8 +198,10 @@ static int bitplane_decoding(uint8_t* data, int *raw_flag, VC1Context *v) planep += stride * 2; } x = width % 3; - if(x) decode_colskip(data , x, height , stride, &v->s.gb); - if(height & 1) decode_rowskip(data+x, width - x, 1, stride, &v->s.gb); + if (x) + decode_colskip(data, x, height, stride, &v->s.gb); + if (height & 1) + decode_rowskip(data + x, width - x, 1, stride, &v->s.gb); } break; case IMODE_ROWSKIP: @@ -203,33 +210,30 @@ static int bitplane_decoding(uint8_t* data, int *raw_flag, VC1Context *v) case IMODE_COLSKIP: decode_colskip(data, width, height, stride, &v->s.gb); break; - default: break; + default: + break; } /* Applying diff operator */ - if (imode == IMODE_DIFF2 || imode == IMODE_DIFF6) - { + if (imode == IMODE_DIFF2 || imode == IMODE_DIFF6) { planep = data; planep[0] ^= invert; - for (x=1; xdquant == 2) - { + if (v->dquant == 2) { pqdiff = get_bits(gb, 3); - if (pqdiff == 7) v->altpq = get_bits(gb, 5); - else v->altpq = v->pq + pqdiff + 1; - } - else - { + if (pqdiff == 7) + v->altpq = get_bits(gb, 5); + else + v->altpq = v->pq + pqdiff + 1; + } else { v->dquantfrm = get_bits1(gb); - if ( v->dquantfrm ) - { + if (v->dquantfrm) { v->dqprofile = get_bits(gb, 2); - switch (v->dqprofile) - { + switch (v->dqprofile) { case DQPROFILE_SINGLE_EDGE: case DQPROFILE_DOUBLE_EDGES: v->dqsbedge = get_bits(gb, 2); break; case DQPROFILE_ALL_MBS: v->dqbilevel = get_bits1(gb); - if(!v->dqbilevel) + if (!v->dqbilevel) v->halfpq = 0; - default: break; //Forbidden ? + default: + break; //Forbidden ? } - if (v->dqbilevel || v->dqprofile != DQPROFILE_ALL_MBS) - { + if (v->dqbilevel || v->dqprofile != DQPROFILE_ALL_MBS) { pqdiff = get_bits(gb, 3); - if (pqdiff == 7) v->altpq = get_bits(gb, 5); - else v->altpq = v->pq + pqdiff + 1; + if (pqdiff == 7) + v->altpq = get_bits(gb, 5); + else + v->altpq = v->pq + pqdiff + 1; } } } @@ -292,25 +295,20 @@ int vc1_decode_sequence_header(AVCodecContext *avctx, VC1Context *v, GetBitConte { av_log(avctx, AV_LOG_DEBUG, "Header: %0X\n", show_bits(gb, 32)); v->profile = get_bits(gb, 2); - if (v->profile == PROFILE_COMPLEX) - { + if (v->profile == PROFILE_COMPLEX) { av_log(avctx, AV_LOG_WARNING, "WMV3 Complex Profile is not fully supported\n"); } - if (v->profile == PROFILE_ADVANCED) - { + if (v->profile == PROFILE_ADVANCED) { v->zz_8x4 = ff_vc1_adv_progressive_8x4_zz; v->zz_4x8 = ff_vc1_adv_progressive_4x8_zz; return decode_sequence_header_adv(v, gb); - } - else - { + } else { v->zz_8x4 = wmv2_scantableA; v->zz_4x8 = wmv2_scantableB; v->res_y411 = get_bits1(gb); v->res_sprite = get_bits1(gb); - if (v->res_y411) - { + if (v->res_y411) { av_log(avctx, AV_LOG_ERROR, "Old interlaced mode is not supported\n"); return -1; @@ -321,48 +319,45 @@ int vc1_decode_sequence_header(AVCodecContext *avctx, VC1Context *v, GetBitConte v->frmrtq_postproc = get_bits(gb, 3); //common // (bitrate-32kbps)/64kbps v->bitrtq_postproc = get_bits(gb, 5); //common - v->s.loop_filter = get_bits1(gb); //common - if(v->s.loop_filter == 1 && v->profile == PROFILE_SIMPLE) - { + v->s.loop_filter = get_bits1(gb); //common + if (v->s.loop_filter == 1 && v->profile == PROFILE_SIMPLE) { av_log(avctx, AV_LOG_ERROR, "LOOPFILTER shall not be enabled in Simple Profile\n"); } - if(v->s.avctx->skip_loop_filter >= AVDISCARD_ALL) + if (v->s.avctx->skip_loop_filter >= AVDISCARD_ALL) v->s.loop_filter = 0; - v->res_x8 = get_bits1(gb); //reserved - v->multires = get_bits1(gb); - v->res_fasttx = get_bits1(gb); - if (!v->res_fasttx) - { - v->vc1dsp.vc1_inv_trans_8x8 = ff_simple_idct_8; - v->vc1dsp.vc1_inv_trans_8x4 = ff_simple_idct84_add; - v->vc1dsp.vc1_inv_trans_4x8 = ff_simple_idct48_add; - v->vc1dsp.vc1_inv_trans_4x4 = ff_simple_idct44_add; + v->res_x8 = get_bits1(gb); //reserved + v->multires = get_bits1(gb); + v->res_fasttx = get_bits1(gb); + if (!v->res_fasttx) { + v->vc1dsp.vc1_inv_trans_8x8 = ff_simple_idct_8; + v->vc1dsp.vc1_inv_trans_8x4 = ff_simple_idct84_add; + v->vc1dsp.vc1_inv_trans_4x8 = ff_simple_idct48_add; + v->vc1dsp.vc1_inv_trans_4x4 = ff_simple_idct44_add; v->vc1dsp.vc1_inv_trans_8x8_dc = ff_simple_idct_add_8; v->vc1dsp.vc1_inv_trans_8x4_dc = ff_simple_idct84_add; v->vc1dsp.vc1_inv_trans_4x8_dc = ff_simple_idct48_add; v->vc1dsp.vc1_inv_trans_4x4_dc = ff_simple_idct44_add; } - v->fastuvmc = get_bits1(gb); //common - if (!v->profile && !v->fastuvmc) - { + v->fastuvmc = get_bits1(gb); //common + if (!v->profile && !v->fastuvmc) { av_log(avctx, AV_LOG_ERROR, "FASTUVMC unavailable in Simple Profile\n"); return -1; } - v->extended_mv = get_bits1(gb); //common + v->extended_mv = get_bits1(gb); //common if (!v->profile && v->extended_mv) { av_log(avctx, AV_LOG_ERROR, "Extended MVs unavailable in Simple Profile\n"); return -1; } - v->dquant = get_bits(gb, 2); //common - v->vstransform = get_bits1(gb); //common + v->dquant = get_bits(gb, 2); //common + v->vstransform = get_bits1(gb); //common - v->res_transtab = get_bits1(gb); + v->res_transtab = get_bits1(gb); if (v->res_transtab) { av_log(avctx, AV_LOG_ERROR, @@ -370,12 +365,11 @@ int vc1_decode_sequence_header(AVCodecContext *avctx, VC1Context *v, GetBitConte return -1; } - v->overlap = get_bits1(gb); //common + v->overlap = get_bits1(gb); //common v->s.resync_marker = get_bits1(gb); - v->rangered = get_bits1(gb); - if (v->rangered && v->profile == PROFILE_SIMPLE) - { + v->rangered = get_bits1(gb); + if (v->rangered && v->profile == PROFILE_SIMPLE) { av_log(avctx, AV_LOG_INFO, "RANGERED should be set to 0 in Simple Profile\n"); } @@ -399,8 +393,7 @@ int vc1_decode_sequence_header(AVCodecContext *avctx, VC1Context *v, GetBitConte } else { v->res_rtm_flag = get_bits1(gb); //reserved } - if (!v->res_rtm_flag) - { + if (!v->res_rtm_flag) { // av_log(avctx, AV_LOG_ERROR, // "0 for reserved RES_RTM_FLAG is forbidden\n"); av_log(avctx, AV_LOG_ERROR, @@ -408,17 +401,17 @@ int vc1_decode_sequence_header(AVCodecContext *avctx, VC1Context *v, GetBitConte //return -1; } //TODO: figure out what they mean (always 0x402F) - if(!v->res_fasttx) skip_bits(gb, 16); + if (!v->res_fasttx) + skip_bits(gb, 16); av_log(avctx, AV_LOG_DEBUG, - "Profile %i:\nfrmrtq_postproc=%i, bitrtq_postproc=%i\n" - "LoopFilter=%i, MultiRes=%i, FastUVMC=%i, Extended MV=%i\n" - "Rangered=%i, VSTransform=%i, Overlap=%i, SyncMarker=%i\n" - "DQuant=%i, Quantizer mode=%i, Max B frames=%i\n", - v->profile, v->frmrtq_postproc, v->bitrtq_postproc, - v->s.loop_filter, v->multires, v->fastuvmc, v->extended_mv, - v->rangered, v->vstransform, v->overlap, v->s.resync_marker, - v->dquant, v->quantizer_mode, avctx->max_b_frames - ); + "Profile %i:\nfrmrtq_postproc=%i, bitrtq_postproc=%i\n" + "LoopFilter=%i, MultiRes=%i, FastUVMC=%i, Extended MV=%i\n" + "Rangered=%i, VSTransform=%i, Overlap=%i, SyncMarker=%i\n" + "DQuant=%i, Quantizer mode=%i, Max B frames=%i\n", + v->profile, v->frmrtq_postproc, v->bitrtq_postproc, + v->s.loop_filter, v->multires, v->fastuvmc, v->extended_mv, + v->rangered, v->vstransform, v->overlap, v->s.resync_marker, + v->dquant, v->quantizer_mode, avctx->max_b_frames); return 0; } @@ -426,60 +419,57 @@ static int decode_sequence_header_adv(VC1Context *v, GetBitContext *gb) { v->res_rtm_flag = 1; v->level = get_bits(gb, 3); - if(v->level >= 5) - { + if (v->level >= 5) { av_log(v->s.avctx, AV_LOG_ERROR, "Reserved LEVEL %i\n",v->level); } v->chromaformat = get_bits(gb, 2); - if (v->chromaformat != 1) - { + if (v->chromaformat != 1) { av_log(v->s.avctx, AV_LOG_ERROR, "Only 4:2:0 chroma format supported\n"); return -1; } // (fps-2)/4 (->30) - v->frmrtq_postproc = get_bits(gb, 3); //common + v->frmrtq_postproc = get_bits(gb, 3); //common // (bitrate-32kbps)/64kbps - v->bitrtq_postproc = get_bits(gb, 5); //common - v->postprocflag = get_bits1(gb); //common + 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_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; - v->broadcast = get_bits1(gb); - v->interlace = get_bits1(gb); - v->tfcntrflag = get_bits1(gb); - v->finterpflag = get_bits1(gb); + v->s.avctx->width = v->s.avctx->coded_width; + v->s.avctx->height = v->s.avctx->coded_height; + v->broadcast = get_bits1(gb); + v->interlace = get_bits1(gb); + v->tfcntrflag = get_bits1(gb); + v->finterpflag = get_bits1(gb); skip_bits1(gb); // reserved av_log(v->s.avctx, AV_LOG_DEBUG, - "Advanced Profile level %i:\nfrmrtq_postproc=%i, bitrtq_postproc=%i\n" - "LoopFilter=%i, ChromaFormat=%i, Pulldown=%i, Interlace: %i\n" - "TFCTRflag=%i, FINTERPflag=%i\n", - v->level, v->frmrtq_postproc, v->bitrtq_postproc, - v->s.loop_filter, v->chromaformat, v->broadcast, v->interlace, - v->tfcntrflag, v->finterpflag - ); + "Advanced Profile level %i:\nfrmrtq_postproc=%i, bitrtq_postproc=%i\n" + "LoopFilter=%i, ChromaFormat=%i, Pulldown=%i, Interlace: %i\n" + "TFCTRflag=%i, FINTERPflag=%i\n", + v->level, v->frmrtq_postproc, v->bitrtq_postproc, + v->s.loop_filter, v->chromaformat, v->broadcast, v->interlace, + v->tfcntrflag, v->finterpflag); v->psf = get_bits1(gb); - if(v->psf) { //PsF, 6.1.13 + if (v->psf) { //PsF, 6.1.13 av_log(v->s.avctx, AV_LOG_ERROR, "Progressive Segmented Frame mode: not supported (yet)\n"); return -1; } 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; av_log(v->s.avctx, AV_LOG_DEBUG, "Display extended info:\n"); w = get_bits(gb, 14) + 1; h = get_bits(gb, 14) + 1; av_log(v->s.avctx, AV_LOG_DEBUG, "Display dimensions: %ix%i\n", w, h); - if(get_bits1(gb)) + if (get_bits1(gb)) ar = get_bits(gb, 4); - if(ar && ar < 14){ + if (ar && ar < 14) { v->s.avctx->sample_aspect_ratio = ff_vc1_pixel_aspect[ar]; - }else if(ar == 15){ + } else if (ar == 15) { w = get_bits(gb, 8) + 1; h = get_bits(gb, 8) + 1; v->s.avctx->sample_aspect_ratio = (AVRational){w, h}; @@ -488,43 +478,45 @@ static int decode_sequence_header_adv(VC1Context *v, GetBitContext *gb) &v->s.avctx->sample_aspect_ratio.den, v->s.avctx->height * w, v->s.avctx->width * h, - 1<<30); + 1 << 30); } - av_log(v->s.avctx, AV_LOG_DEBUG, "Aspect: %i:%i\n", v->s.avctx->sample_aspect_ratio.num, v->s.avctx->sample_aspect_ratio.den); + av_log(v->s.avctx, AV_LOG_DEBUG, "Aspect: %i:%i\n", + v->s.avctx->sample_aspect_ratio.num, + v->s.avctx->sample_aspect_ratio.den); - if(get_bits1(gb)){ //framerate stuff - if(get_bits1(gb)) { + if (get_bits1(gb)) { //framerate stuff + if (get_bits1(gb)) { v->s.avctx->time_base.num = 32; v->s.avctx->time_base.den = get_bits(gb, 16) + 1; } else { int nr, dr; nr = get_bits(gb, 8); dr = get_bits(gb, 4); - if(nr && nr < 8 && dr && dr < 3){ + if (nr && nr < 8 && dr && dr < 3) { v->s.avctx->time_base.num = ff_vc1_fps_dr[dr - 1]; v->s.avctx->time_base.den = ff_vc1_fps_nr[nr - 1] * 1000; } } - if(v->broadcast) { // Pulldown may be present - v->s.avctx->time_base.den *= 2; + if (v->broadcast) { // Pulldown may be present + v->s.avctx->time_base.den *= 2; v->s.avctx->ticks_per_frame = 2; } } - if(get_bits1(gb)){ - v->color_prim = get_bits(gb, 8); + if (get_bits1(gb)) { + v->color_prim = get_bits(gb, 8); v->transfer_char = get_bits(gb, 8); - v->matrix_coef = get_bits(gb, 8); + v->matrix_coef = get_bits(gb, 8); } } v->hrd_param_flag = get_bits1(gb); - if(v->hrd_param_flag) { + if (v->hrd_param_flag) { int i; v->hrd_num_leaky_buckets = get_bits(gb, 5); skip_bits(gb, 4); //bitrate exponent skip_bits(gb, 4); //buffer size exponent - for(i = 0; i < v->hrd_num_leaky_buckets; i++) { + for (i = 0; i < v->hrd_num_leaky_buckets; i++) { skip_bits(gb, 16); //hrd_rate[n] skip_bits(gb, 16); //hrd_buffer[n] } @@ -537,45 +529,45 @@ int vc1_decode_entry_point(AVCodecContext *avctx, VC1Context *v, GetBitContext * int i; av_log(avctx, AV_LOG_DEBUG, "Entry point: %08X\n", show_bits_long(gb, 32)); - v->broken_link = get_bits1(gb); - v->closed_entry = get_bits1(gb); - v->panscanflag = get_bits1(gb); - v->refdist_flag = get_bits1(gb); - v->s.loop_filter = get_bits1(gb); - v->fastuvmc = get_bits1(gb); - v->extended_mv = get_bits1(gb); - v->dquant = get_bits(gb, 2); - v->vstransform = get_bits1(gb); - v->overlap = get_bits1(gb); + v->broken_link = get_bits1(gb); + v->closed_entry = get_bits1(gb); + v->panscanflag = get_bits1(gb); + v->refdist_flag = get_bits1(gb); + v->s.loop_filter = get_bits1(gb); + v->fastuvmc = get_bits1(gb); + v->extended_mv = get_bits1(gb); + v->dquant = get_bits(gb, 2); + v->vstransform = get_bits1(gb); + v->overlap = get_bits1(gb); v->quantizer_mode = get_bits(gb, 2); - if(v->hrd_param_flag){ - for(i = 0; i < v->hrd_num_leaky_buckets; i++) { + if (v->hrd_param_flag) { + for (i = 0; i < v->hrd_num_leaky_buckets; i++) { skip_bits(gb, 8); //hrd_full[n] } } - if(get_bits1(gb)){ - avctx->width = avctx->coded_width = (get_bits(gb, 12)+1)<<1; - avctx->height = avctx->coded_height = (get_bits(gb, 12)+1)<<1; + if (get_bits1(gb)) { + avctx->width = avctx->coded_width = (get_bits(gb, 12) + 1) << 1; + avctx->height = avctx->coded_height = (get_bits(gb, 12) + 1) << 1; } - if(v->extended_mv) + if (v->extended_mv) v->extended_dmv = get_bits1(gb); - if((v->range_mapy_flag = get_bits1(gb))) { + if ((v->range_mapy_flag = get_bits1(gb))) { av_log(avctx, AV_LOG_ERROR, "Luma scaling is not supported, expect wrong picture\n"); v->range_mapy = get_bits(gb, 3); } - if((v->range_mapuv_flag = get_bits1(gb))) { + if ((v->range_mapuv_flag = get_bits1(gb))) { av_log(avctx, AV_LOG_ERROR, "Chroma scaling is not supported, expect wrong picture\n"); v->range_mapuv = get_bits(gb, 3); } av_log(avctx, AV_LOG_DEBUG, "Entry point info:\n" - "BrokenLink=%i, ClosedEntry=%i, PanscanFlag=%i\n" - "RefDist=%i, Postproc=%i, FastUVMC=%i, ExtMV=%i\n" - "DQuant=%i, VSTransform=%i, Overlap=%i, Qmode=%i\n", - v->broken_link, v->closed_entry, v->panscanflag, v->refdist_flag, v->s.loop_filter, - v->fastuvmc, v->extended_mv, v->dquant, v->vstransform, v->overlap, v->quantizer_mode); + "BrokenLink=%i, ClosedEntry=%i, PanscanFlag=%i\n" + "RefDist=%i, Postproc=%i, FastUVMC=%i, ExtMV=%i\n" + "DQuant=%i, VSTransform=%i, Overlap=%i, Qmode=%i\n", + v->broken_link, v->closed_entry, v->panscanflag, v->refdist_flag, v->s.loop_filter, + v->fastuvmc, v->extended_mv, v->dquant, v->vstransform, v->overlap, v->quantizer_mode); return 0; } @@ -584,41 +576,48 @@ int vc1_parse_frame_header(VC1Context *v, GetBitContext* gb) { int pqindex, lowquant, status; - if(v->finterpflag) v->interpfrm = get_bits1(gb); + if (v->finterpflag) + v->interpfrm = get_bits1(gb); skip_bits(gb, 2); //framecnt unused v->rangeredfrm = 0; - if (v->rangered) v->rangeredfrm = get_bits1(gb); + if (v->rangered) + v->rangeredfrm = get_bits1(gb); v->s.pict_type = get_bits1(gb); if (v->s.avctx->max_b_frames) { if (!v->s.pict_type) { - if (get_bits1(gb)) v->s.pict_type = AV_PICTURE_TYPE_I; - else v->s.pict_type = AV_PICTURE_TYPE_B; - } else v->s.pict_type = AV_PICTURE_TYPE_P; - } else v->s.pict_type = v->s.pict_type ? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I; + if (get_bits1(gb)) + v->s.pict_type = AV_PICTURE_TYPE_I; + else + v->s.pict_type = AV_PICTURE_TYPE_B; + } else + v->s.pict_type = AV_PICTURE_TYPE_P; + } else + v->s.pict_type = v->s.pict_type ? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I; v->bi_type = 0; - if(v->s.pict_type == AV_PICTURE_TYPE_B) { + if (v->s.pict_type == AV_PICTURE_TYPE_B) { v->bfraction_lut_index = get_vlc2(gb, ff_vc1_bfraction_vlc.table, VC1_BFRACTION_VLC_BITS, 1); - v->bfraction = ff_vc1_bfraction_lut[v->bfraction_lut_index]; - if(v->bfraction == 0) { + v->bfraction = ff_vc1_bfraction_lut[v->bfraction_lut_index]; + if (v->bfraction == 0) { v->s.pict_type = AV_PICTURE_TYPE_BI; } } - if(v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_BI) + if (v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_BI) skip_bits(gb, 7); // skip buffer fullness - if(v->parse_only) + if (v->parse_only) return 0; /* calculate RND */ - if(v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_BI) + if (v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_BI) v->rnd = 1; - if(v->s.pict_type == AV_PICTURE_TYPE_P) + if (v->s.pict_type == AV_PICTURE_TYPE_P) v->rnd ^= 1; /* Quantizer stuff */ pqindex = get_bits(gb, 5); - if(!pqindex) return -1; + if (!pqindex) + return -1; if (v->quantizer_mode == QUANT_FRAME_IMPLICIT) v->pq = ff_vc1_pquant_table[0][pqindex]; else @@ -630,64 +629,69 @@ int vc1_parse_frame_header(VC1Context *v, GetBitContext* gb) if (v->quantizer_mode == QUANT_NON_UNIFORM) v->pquantizer = 0; v->pqindex = pqindex; - if (pqindex < 9) v->halfpq = get_bits1(gb); - else v->halfpq = 0; + if (pqindex < 9) + v->halfpq = get_bits1(gb); + else + v->halfpq = 0; if (v->quantizer_mode == QUANT_FRAME_EXPLICIT) v->pquantizer = get_bits1(gb); v->dquantfrm = 0; - if (v->extended_mv == 1) v->mvrange = get_unary(gb, 0, 3); + if (v->extended_mv == 1) + v->mvrange = get_unary(gb, 0, 3); v->k_x = v->mvrange + 9 + (v->mvrange >> 1); //k_x can be 9 10 12 13 v->k_y = v->mvrange + 8; //k_y can be 8 9 10 11 v->range_x = 1 << (v->k_x - 1); v->range_y = 1 << (v->k_y - 1); - if (v->multires && v->s.pict_type != AV_PICTURE_TYPE_B) v->respic = get_bits(gb, 2); + if (v->multires && v->s.pict_type != AV_PICTURE_TYPE_B) + v->respic = get_bits(gb, 2); - if(v->res_x8 && (v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_BI)){ + if (v->res_x8 && (v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_BI)) { v->x8_type = get_bits1(gb); - }else v->x8_type = 0; + } else + v->x8_type = 0; //av_log(v->s.avctx, AV_LOG_INFO, "%c Frame: QP=[%i]%i (+%i/2) %i\n", // (v->s.pict_type == AV_PICTURE_TYPE_P) ? 'P' : ((v->s.pict_type == AV_PICTURE_TYPE_I) ? 'I' : 'B'), pqindex, v->pq, v->halfpq, v->rangeredfrm); - if(v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_P) v->use_ic = 0; + if (v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_P) + v->use_ic = 0; - switch(v->s.pict_type) { + switch (v->s.pict_type) { case AV_PICTURE_TYPE_P: - if (v->pq < 5) v->tt_index = 0; - else if(v->pq < 13) v->tt_index = 1; - else v->tt_index = 2; + if (v->pq < 5) v->tt_index = 0; + else if (v->pq < 13) v->tt_index = 1; + else v->tt_index = 2; 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) - { + 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); - v->use_ic = 1; + v->use_ic = 1; /* fill lookup tables for intensity compensation */ - if(!v->lumscale) { + if (!v->lumscale) { scale = -64; shift = (255 - v->lumshift * 2) << 6; - if(v->lumshift > 31) + if (v->lumshift > 31) shift += 128 << 6; } else { scale = v->lumscale + 32; - if(v->lumshift > 31) + 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); + 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); } } v->qs_last = v->s.quarter_sample; - if(v->mv_mode == MV_PMODE_1MV_HPEL || v->mv_mode == MV_PMODE_1MV_HPEL_BILIN) + if (v->mv_mode == MV_PMODE_1MV_HPEL || v->mv_mode == MV_PMODE_1MV_HPEL_BILIN) v->s.quarter_sample = 0; - else if(v->mv_mode == MV_PMODE_INTENSITY_COMP) { - if(v->mv_mode2 == MV_PMODE_1MV_HPEL || v->mv_mode2 == MV_PMODE_1MV_HPEL_BILIN) + else if (v->mv_mode == MV_PMODE_INTENSITY_COMP) { + if (v->mv_mode2 == MV_PMODE_1MV_HPEL || v->mv_mode2 == MV_PMODE_1MV_HPEL_BILIN) v->s.quarter_sample = 0; else v->s.quarter_sample = 1; @@ -695,12 +699,12 @@ int vc1_parse_frame_header(VC1Context *v, GetBitContext* gb) v->s.quarter_sample = 1; v->s.mspel = !(v->mv_mode == MV_PMODE_1MV_HPEL_BILIN || (v->mv_mode == MV_PMODE_INTENSITY_COMP && v->mv_mode2 == MV_PMODE_1MV_HPEL_BILIN)); - if ((v->mv_mode == MV_PMODE_INTENSITY_COMP && - v->mv_mode2 == MV_PMODE_MIXED_MV) - || v->mv_mode == MV_PMODE_MIXED_MV) - { + if ((v->mv_mode == MV_PMODE_INTENSITY_COMP && + v->mv_mode2 == MV_PMODE_MIXED_MV) || + v->mv_mode == MV_PMODE_MIXED_MV) { status = bitplane_decoding(v->mv_type_mb_plane, &v->mv_type_is_raw, v); - if (status < 0) return -1; + if (status < 0) + return -1; av_log(v->s.avctx, AV_LOG_DEBUG, "MB MV Type plane encoding: " "Imode: %i, Invert: %i\n", status>>1, status&1); } else { @@ -708,7 +712,8 @@ int vc1_parse_frame_header(VC1Context *v, GetBitContext* gb) memset(v->mv_type_mb_plane, 0, v->s.mb_stride * v->s.mb_height); } status = bitplane_decoding(v->s.mbskip_table, &v->skip_is_raw, v); - if (status < 0) return -1; + if (status < 0) + return -1; av_log(v->s.avctx, AV_LOG_DEBUG, "MB Skip plane encoding: " "Imode: %i, Invert: %i\n", status>>1, status&1); @@ -716,18 +721,15 @@ int vc1_parse_frame_header(VC1Context *v, GetBitContext* gb) v->s.mv_table_index = get_bits(gb, 2); //but using ff_vc1_ tables v->cbpcy_vlc = &ff_vc1_cbpcy_p_vlc[get_bits(gb, 2)]; - if (v->dquant) - { + if (v->dquant) { av_log(v->s.avctx, AV_LOG_DEBUG, "VOP DQuant info\n"); vop_dquant_decoding(v); } v->ttfrm = 0; //FIXME Is that so ? - if (v->vstransform) - { + if (v->vstransform) { v->ttmbf = get_bits1(gb); - if (v->ttmbf) - { + if (v->ttmbf) { v->ttfrm = ff_vc1_ttfrm_to_tt[get_bits(gb, 2)]; } } else { @@ -736,39 +738,38 @@ int vc1_parse_frame_header(VC1Context *v, GetBitContext* gb) } break; case AV_PICTURE_TYPE_B: - if (v->pq < 5) v->tt_index = 0; - else if(v->pq < 13) v->tt_index = 1; - else v->tt_index = 2; + if (v->pq < 5) v->tt_index = 0; + else if (v->pq < 13) v->tt_index = 1; + else v->tt_index = 2; - v->mv_mode = get_bits1(gb) ? MV_PMODE_1MV : MV_PMODE_1MV_HPEL_BILIN; - v->qs_last = v->s.quarter_sample; + v->mv_mode = get_bits1(gb) ? MV_PMODE_1MV : MV_PMODE_1MV_HPEL_BILIN; + v->qs_last = v->s.quarter_sample; v->s.quarter_sample = (v->mv_mode == MV_PMODE_1MV); - v->s.mspel = v->s.quarter_sample; + v->s.mspel = v->s.quarter_sample; status = bitplane_decoding(v->direct_mb_plane, &v->dmb_is_raw, v); - if (status < 0) return -1; + if (status < 0) + return -1; av_log(v->s.avctx, AV_LOG_DEBUG, "MB Direct Type plane encoding: " "Imode: %i, Invert: %i\n", status>>1, status&1); status = bitplane_decoding(v->s.mbskip_table, &v->skip_is_raw, v); - if (status < 0) return -1; + if (status < 0) + return -1; av_log(v->s.avctx, AV_LOG_DEBUG, "MB Skip plane encoding: " "Imode: %i, Invert: %i\n", status>>1, status&1); v->s.mv_table_index = get_bits(gb, 2); - v->cbpcy_vlc = &ff_vc1_cbpcy_p_vlc[get_bits(gb, 2)]; + v->cbpcy_vlc = &ff_vc1_cbpcy_p_vlc[get_bits(gb, 2)]; - if (v->dquant) - { + if (v->dquant) { av_log(v->s.avctx, AV_LOG_DEBUG, "VOP DQuant info\n"); vop_dquant_decoding(v); } v->ttfrm = 0; - if (v->vstransform) - { + if (v->vstransform) { v->ttmbf = get_bits1(gb); - if (v->ttmbf) - { + if (v->ttmbf) { v->ttfrm = ff_vc1_ttfrm_to_tt[get_bits(gb, 2)]; } } else { @@ -778,21 +779,19 @@ int vc1_parse_frame_header(VC1Context *v, GetBitContext* gb) break; } - if(!v->x8_type) - { + if (!v->x8_type) { /* AC Syntax */ v->c_ac_table_index = decode012(gb); - if (v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_BI) - { + if (v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_BI) { v->y_ac_table_index = decode012(gb); } /* DC Syntax */ v->s.dc_table_index = get_bits1(gb); } - if(v->s.pict_type == AV_PICTURE_TYPE_BI) { + if (v->s.pict_type == AV_PICTURE_TYPE_BI) { v->s.pict_type = AV_PICTURE_TYPE_B; - v->bi_type = 1; + v->bi_type = 1; } return 0; } @@ -833,15 +832,16 @@ int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) goto parse_common_info; } - if(v->interlace){ + if (v->interlace) { v->fcm = decode012(gb); - if(v->fcm){ + if (v->fcm) { if (v->fcm == 2) v->field_mode = 1; else v->field_mode = 0; if (!v->warn_interlaced++) - av_log(v->s.avctx, AV_LOG_ERROR, "Interlaced frames/fields support is incomplete\n"); + av_log(v->s.avctx, AV_LOG_ERROR, + "Interlaced frames/fields support is incomplete\n"); } } @@ -851,7 +851,7 @@ int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) if (v->fptype & 4) // B-picture v->s.pict_type = (v->fptype & 2) ? AV_PICTURE_TYPE_BI : AV_PICTURE_TYPE_B; } else { - switch(get_unary(gb, 0, 4)) { + switch (get_unary(gb, 0, 4)) { case 0: v->s.pict_type = AV_PICTURE_TYPE_P; break; @@ -870,25 +870,25 @@ int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) break; } } - if(v->tfcntrflag) + if (v->tfcntrflag) skip_bits(gb, 8); - if(v->broadcast) { - if(!v->interlace || v->psf) { + if (v->broadcast) { + if (!v->interlace || v->psf) { v->rptfrm = get_bits(gb, 2); } else { v->tff = get_bits1(gb); v->rff = get_bits1(gb); } } - if(v->panscanflag) { + if (v->panscanflag) { av_log_missing_feature(v->s.avctx, "Pan-scan", 0); //... } - if(v->p_frame_skipped) { + if (v->p_frame_skipped) { return 0; } v->rnd = get_bits1(gb); - if(v->interlace) + if (v->interlace) v->uvsamp = get_bits1(gb); if (v->field_mode) { if (!v->refdist_flag) @@ -901,7 +901,7 @@ int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) v->refdist += get_unary(gb, 0, 16); } else { v->bfraction_lut_index = get_vlc2(gb, ff_vc1_bfraction_vlc.table, VC1_BFRACTION_VLC_BITS, 1); - v->bfraction = ff_vc1_bfraction_lut[v->bfraction_lut_index]; + v->bfraction = ff_vc1_bfraction_lut[v->bfraction_lut_index]; v->frfd = (v->bfraction * v->refdist) >> 8; v->brfd = v->refdist - v->frfd - 1; if (v->brfd < 0) @@ -910,11 +910,12 @@ int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) } goto parse_common_info; } - if(v->finterpflag) v->interpfrm = get_bits1(gb); - if(v->s.pict_type == AV_PICTURE_TYPE_B) { + if (v->finterpflag) + v->interpfrm = get_bits1(gb); + if (v->s.pict_type == AV_PICTURE_TYPE_B) { v->bfraction_lut_index = get_vlc2(gb, ff_vc1_bfraction_vlc.table, VC1_BFRACTION_VLC_BITS, 1); - v->bfraction = ff_vc1_bfraction_lut[v->bfraction_lut_index]; - if(v->bfraction == 0) { + v->bfraction = ff_vc1_bfraction_lut[v->bfraction_lut_index]; + if (v->bfraction == 0) { v->s.pict_type = AV_PICTURE_TYPE_BI; /* XXX: should not happen here */ } } @@ -923,7 +924,8 @@ int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) if (v->field_mode) v->cur_field_type = !(v->tff ^ v->second_field); pqindex = get_bits(gb, 5); - if(!pqindex) return -1; + if (!pqindex) + return -1; v->pqindex = pqindex; if (v->quantizer_mode == QUANT_FRAME_IMPLICIT) v->pq = ff_vc1_pquant_table[0][pqindex]; @@ -942,16 +944,16 @@ int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) v->halfpq = 0; if (v->quantizer_mode == QUANT_FRAME_EXPLICIT) v->pquantizer = get_bits1(gb); - if(v->postprocflag) + if (v->postprocflag) v->postproc = get_bits(gb, 2); - if(v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_P) + if (v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_P) v->use_ic = 0; if (v->parse_only) return 0; - switch(v->s.pict_type) { + switch (v->s.pict_type) { case AV_PICTURE_TYPE_I: case AV_PICTURE_TYPE_BI: if (v->fcm == 1) { //interlace frame picture @@ -965,16 +967,16 @@ int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) if (status < 0) return -1; av_log(v->s.avctx, AV_LOG_DEBUG, "ACPRED plane encoding: " - "Imode: %i, Invert: %i\n", status>>1, status&1); + "Imode: %i, Invert: %i\n", status>>1, status&1); v->condover = CONDOVER_NONE; - if(v->overlap && v->pq <= 8) { + if (v->overlap && v->pq <= 8) { v->condover = decode012(gb); - if(v->condover == CONDOVER_SELECT) { + if (v->condover == CONDOVER_SELECT) { status = bitplane_decoding(v->over_flags_plane, &v->overflg_is_raw, v); if (status < 0) return -1; av_log(v->s.avctx, AV_LOG_DEBUG, "CONDOVER plane encoding: " - "Imode: %i, Invert: %i\n", status>>1, status&1); + "Imode: %i, Invert: %i\n", status>>1, status&1); } } break; @@ -982,7 +984,7 @@ int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) if (v->field_mode) { v->numref = get_bits1(gb); if (!v->numref) { - v->reffield = get_bits1(gb); + v->reffield = get_bits1(gb); v->ref_field_type[0] = v->reffield ^ !v->cur_field_type; } } @@ -997,7 +999,7 @@ int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) v->dmvrange = 0; if (v->fcm == 1) { // interlaced frame picture v->fourmvswitch = get_bits1(gb); - v->intcomp = get_bits1(gb); + v->intcomp = get_bits1(gb); if (v->intcomp) { v->lumscale = get_bits(gb, 6); v->lumshift = get_bits(gb, 6); @@ -1005,21 +1007,21 @@ int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) } status = bitplane_decoding(v->s.mbskip_table, &v->skip_is_raw, v); av_log(v->s.avctx, AV_LOG_DEBUG, "SKIPMB plane encoding: " - "Imode: %i, Invert: %i\n", status>>1, status&1); + "Imode: %i, Invert: %i\n", status>>1, status&1); mbmodetab = get_bits(gb, 2); if (v->fourmvswitch) v->mbmode_vlc = &ff_vc1_intfr_4mv_mbmode_vlc[mbmodetab]; else v->mbmode_vlc = &ff_vc1_intfr_non4mv_mbmode_vlc[mbmodetab]; - imvtab = get_bits(gb, 2); - v->imv_vlc = &ff_vc1_1ref_mvdata_vlc[imvtab]; + imvtab = get_bits(gb, 2); + v->imv_vlc = &ff_vc1_1ref_mvdata_vlc[imvtab]; // interlaced p-picture cbpcy range is [1, 63] - icbptab = get_bits(gb, 3); - v->cbpcy_vlc = &ff_vc1_icbpcy_vlc[icbptab]; - twomvbptab = get_bits(gb, 2); + icbptab = get_bits(gb, 3); + v->cbpcy_vlc = &ff_vc1_icbpcy_vlc[icbptab]; + twomvbptab = get_bits(gb, 2); v->twomvbp_vlc = &ff_vc1_2mv_block_pattern_vlc[twomvbptab]; if (v->fourmvswitch) { - fourmvbptab = get_bits(gb, 2); + fourmvbptab = get_bits(gb, 2); v->fourmvbp_vlc = &ff_vc1_4mv_block_pattern_vlc[fourmvbptab]; } } @@ -1031,14 +1033,14 @@ int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) if (v->pq < 5) v->tt_index = 0; - else if(v->pq < 13) + else if (v->pq < 13) v->tt_index = 1; else v->tt_index = 2; if (v->fcm != 1) { int mvmode; - mvmode = get_unary(gb, 1, 4); - lowquant = (v->pq > 12) ? 0 : 1; + mvmode = get_unary(gb, 1, 4); + lowquant = (v->pq > 12) ? 0 : 1; v->mv_mode = ff_vc1_mv_pmode_table[lowquant][mvmode]; if (v->mv_mode == MV_PMODE_INTENSITY_COMP) { int mvmode2; @@ -1057,27 +1059,28 @@ int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) v->use_ic = 1; } v->qs_last = v->s.quarter_sample; - if(v->mv_mode == MV_PMODE_1MV_HPEL || v->mv_mode == MV_PMODE_1MV_HPEL_BILIN) + if (v->mv_mode == MV_PMODE_1MV_HPEL || v->mv_mode == MV_PMODE_1MV_HPEL_BILIN) v->s.quarter_sample = 0; - else if(v->mv_mode == MV_PMODE_INTENSITY_COMP) { - if(v->mv_mode2 == MV_PMODE_1MV_HPEL || v->mv_mode2 == MV_PMODE_1MV_HPEL_BILIN) + else if (v->mv_mode == MV_PMODE_INTENSITY_COMP) { + if (v->mv_mode2 == MV_PMODE_1MV_HPEL || v->mv_mode2 == MV_PMODE_1MV_HPEL_BILIN) v->s.quarter_sample = 0; else v->s.quarter_sample = 1; } else v->s.quarter_sample = 1; - v->s.mspel = !(v->mv_mode == MV_PMODE_1MV_HPEL_BILIN || (v->mv_mode == MV_PMODE_INTENSITY_COMP && v->mv_mode2 == MV_PMODE_1MV_HPEL_BILIN)); + v->s.mspel = !(v->mv_mode == MV_PMODE_1MV_HPEL_BILIN + || (v->mv_mode == MV_PMODE_INTENSITY_COMP + && v->mv_mode2 == MV_PMODE_1MV_HPEL_BILIN)); } if (v->fcm == 0) { // progressive if ((v->mv_mode == MV_PMODE_INTENSITY_COMP && - v->mv_mode2 == MV_PMODE_MIXED_MV) - || v->mv_mode == MV_PMODE_MIXED_MV) - { + v->mv_mode2 == MV_PMODE_MIXED_MV) + || v->mv_mode == MV_PMODE_MIXED_MV) { status = bitplane_decoding(v->mv_type_mb_plane, &v->mv_type_is_raw, v); if (status < 0) return -1; av_log(v->s.avctx, AV_LOG_DEBUG, "MB MV Type plane encoding: " - "Imode: %i, Invert: %i\n", status>>1, status&1); + "Imode: %i, Invert: %i\n", status>>1, status&1); } else { v->mv_type_is_raw = 0; memset(v->mv_type_mb_plane, 0, v->s.mb_stride * v->s.mb_height); @@ -1086,15 +1089,15 @@ int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) if (status < 0) return -1; av_log(v->s.avctx, AV_LOG_DEBUG, "MB Skip plane encoding: " - "Imode: %i, Invert: %i\n", status>>1, status&1); + "Imode: %i, Invert: %i\n", status>>1, status&1); /* Hopefully this is correct for P frames */ v->s.mv_table_index = get_bits(gb, 2); //but using ff_vc1_ tables - v->cbpcy_vlc = &ff_vc1_cbpcy_p_vlc[get_bits(gb, 2)]; + v->cbpcy_vlc = &ff_vc1_cbpcy_p_vlc[get_bits(gb, 2)]; } else if (v->fcm == 1) { // frame interlaced - v->qs_last = v->s.quarter_sample; + v->qs_last = v->s.quarter_sample; v->s.quarter_sample = 1; - v->s.mspel = 1; + v->s.mspel = 1; } else { // field interlaced mbmodetab = get_bits(gb, 3); imvtab = get_bits(gb, 2 + v->numref); @@ -1106,25 +1109,22 @@ int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) v->cbpcy_vlc = &ff_vc1_icbpcy_vlc[icbptab]; if ((v->mv_mode == MV_PMODE_INTENSITY_COMP && v->mv_mode2 == MV_PMODE_MIXED_MV) || v->mv_mode == MV_PMODE_MIXED_MV) { - fourmvbptab = get_bits(gb, 2); + fourmvbptab = get_bits(gb, 2); v->fourmvbp_vlc = &ff_vc1_4mv_block_pattern_vlc[fourmvbptab]; v->mbmode_vlc = &ff_vc1_if_mmv_mbmode_vlc[mbmodetab]; } else { v->mbmode_vlc = &ff_vc1_if_1mv_mbmode_vlc[mbmodetab]; } } - if (v->dquant) - { + if (v->dquant) { av_log(v->s.avctx, AV_LOG_DEBUG, "VOP DQuant info\n"); vop_dquant_decoding(v); } v->ttfrm = 0; //FIXME Is that so ? - if (v->vstransform) - { + if (v->vstransform) { v->ttmbf = get_bits1(gb); - if (v->ttmbf) - { + if (v->ttmbf) { v->ttfrm = ff_vc1_ttfrm_to_tt[get_bits(gb, 2)]; } } else { @@ -1140,14 +1140,14 @@ int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) v->mvrange = get_unary(gb, 0, 3); else v->mvrange = 0; - v->k_x = v->mvrange + 9 + (v->mvrange >> 1); //k_x can be 9 10 12 13 - v->k_y = v->mvrange + 8; //k_y can be 8 9 10 11 + v->k_x = v->mvrange + 9 + (v->mvrange >> 1); //k_x can be 9 10 12 13 + v->k_y = v->mvrange + 8; //k_y can be 8 9 10 11 v->range_x = 1 << (v->k_x - 1); v->range_y = 1 << (v->k_y - 1); if (v->pq < 5) v->tt_index = 0; - else if(v->pq < 13) + else if (v->pq < 13) v->tt_index = 1; else v->tt_index = 2; @@ -1158,10 +1158,10 @@ int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) v->dmvrange = get_unary(gb, 0, 3); mvmode = get_unary(gb, 1, 3); lowquant = (v->pq > 12) ? 0 : 1; - v->mv_mode = ff_vc1_mv_pmode_table2[lowquant][mvmode]; - v->qs_last = v->s.quarter_sample; + v->mv_mode = ff_vc1_mv_pmode_table2[lowquant][mvmode]; + v->qs_last = v->s.quarter_sample; v->s.quarter_sample = (v->mv_mode == MV_PMODE_1MV || v->mv_mode == MV_PMODE_MIXED_MV); - v->s.mspel = !(v->mv_mode == MV_PMODE_1MV_HPEL_BILIN || v->mv_mode == MV_PMODE_1MV_HPEL); + v->s.mspel = !(v->mv_mode == MV_PMODE_1MV_HPEL_BILIN || v->mv_mode == MV_PMODE_1MV_HPEL); status = bitplane_decoding(v->forward_mb_plane, &v->fmb_is_raw, v); if (status < 0) return -1; @@ -1172,21 +1172,21 @@ int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) v->mbmode_vlc = &ff_vc1_if_mmv_mbmode_vlc[mbmodetab]; else v->mbmode_vlc = &ff_vc1_if_1mv_mbmode_vlc[mbmodetab]; - imvtab = get_bits(gb, 3); - v->imv_vlc = &ff_vc1_2ref_mvdata_vlc[imvtab]; - icbptab = get_bits(gb, 3); + imvtab = get_bits(gb, 3); + v->imv_vlc = &ff_vc1_2ref_mvdata_vlc[imvtab]; + icbptab = get_bits(gb, 3); v->cbpcy_vlc = &ff_vc1_icbpcy_vlc[icbptab]; if (v->mv_mode == MV_PMODE_MIXED_MV) { - fourmvbptab = get_bits(gb, 2); + fourmvbptab = get_bits(gb, 2); v->fourmvbp_vlc = &ff_vc1_4mv_block_pattern_vlc[fourmvbptab]; } v->numref = 1; // interlaced field B pictures are always 2-ref } else { - v->mv_mode = get_bits1(gb) ? MV_PMODE_1MV : MV_PMODE_1MV_HPEL_BILIN; - v->qs_last = v->s.quarter_sample; + v->mv_mode = get_bits1(gb) ? MV_PMODE_1MV : MV_PMODE_1MV_HPEL_BILIN; + v->qs_last = v->s.quarter_sample; v->s.quarter_sample = (v->mv_mode == MV_PMODE_1MV); - v->s.mspel = v->s.quarter_sample; - status = bitplane_decoding(v->direct_mb_plane, &v->dmb_is_raw, v); + v->s.mspel = v->s.quarter_sample; + status = bitplane_decoding(v->direct_mb_plane, &v->dmb_is_raw, v); if (status < 0) return -1; av_log(v->s.avctx, AV_LOG_DEBUG, "MB Direct Type plane encoding: " @@ -1200,18 +1200,15 @@ int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) v->cbpcy_vlc = &ff_vc1_cbpcy_p_vlc[get_bits(gb, 2)]; } - if (v->dquant) - { + if (v->dquant) { av_log(v->s.avctx, AV_LOG_DEBUG, "VOP DQuant info\n"); vop_dquant_decoding(v); } v->ttfrm = 0; - if (v->vstransform) - { + if (v->vstransform) { v->ttmbf = get_bits1(gb); - if (v->ttmbf) - { + if (v->ttmbf) { v->ttfrm = ff_vc1_ttfrm_to_tt[get_bits(gb, 2)]; } } else { @@ -1223,19 +1220,19 @@ int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) /* AC Syntax */ v->c_ac_table_index = decode012(gb); - if (v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_BI) - { + if (v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_BI) { v->y_ac_table_index = decode012(gb); } /* DC Syntax */ v->s.dc_table_index = get_bits1(gb); - if ((v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_BI) && v->dquant) { + if ((v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_BI) + && v->dquant) { av_log(v->s.avctx, AV_LOG_DEBUG, "VOP DQuant info\n"); vop_dquant_decoding(v); } v->bi_type = 0; - if(v->s.pict_type == AV_PICTURE_TYPE_BI) { + if (v->s.pict_type == AV_PICTURE_TYPE_BI) { v->s.pict_type = AV_PICTURE_TYPE_B; v->bi_type = 1; } From 11a32d53caa2c41b9f8c18a906a18b349e4e5cfd Mon Sep 17 00:00:00 2001 From: Baptiste Coudurier Date: Sun, 26 Jun 2011 14:08:22 -0700 Subject: [PATCH 14/34] dnxhddec: handle cid change in bitstream. --- libavcodec/dnxhddec.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/libavcodec/dnxhddec.c b/libavcodec/dnxhddec.c index 48932783c3..956196ce64 100644 --- a/libavcodec/dnxhddec.c +++ b/libavcodec/dnxhddec.c @@ -70,7 +70,7 @@ static av_cold int dnxhd_decode_init(AVCodecContext *avctx) static int dnxhd_init_vlc(DNXHDContext *ctx, int cid) { - if (!ctx->cid_table) { + if (cid != ctx->cid) { int index; if ((index = ff_dnxhd_get_cid_table(cid)) < 0) { @@ -78,6 +78,11 @@ static int dnxhd_init_vlc(DNXHDContext *ctx, int cid) return -1; } ctx->cid_table = &ff_dnxhd_cid_table[index]; + + free_vlc(&ctx->ac_vlc); + free_vlc(&ctx->dc_vlc); + free_vlc(&ctx->run_vlc); + init_vlc(&ctx->ac_vlc, DNXHD_VLC_BITS, 257, ctx->cid_table->ac_bits, 1, 1, ctx->cid_table->ac_codes, 2, 2, 0); @@ -89,6 +94,7 @@ static int dnxhd_init_vlc(DNXHDContext *ctx, int cid) ctx->cid_table->run_codes, 2, 2, 0); ff_init_scantable(ctx->dsp.idct_permutation, &ctx->scantable, ff_zigzag_direct); + ctx->cid = cid; } return 0; } @@ -96,7 +102,7 @@ static int dnxhd_init_vlc(DNXHDContext *ctx, int cid) static int dnxhd_decode_header(DNXHDContext *ctx, const uint8_t *buf, int buf_size, int first_field) { static const uint8_t header_prefix[] = { 0x00, 0x00, 0x02, 0x80, 0x01 }; - int i; + int i, cid; if (buf_size < 0x280) return -1; @@ -135,10 +141,10 @@ static int dnxhd_decode_header(DNXHDContext *ctx, const uint8_t *buf, int buf_si } } - ctx->cid = AV_RB32(buf + 0x28); - av_dlog(ctx->avctx, "compression id %d\n", ctx->cid); + cid = AV_RB32(buf + 0x28); + av_dlog(ctx->avctx, "compression id %d\n", cid); - if (dnxhd_init_vlc(ctx, ctx->cid) < 0) + if (dnxhd_init_vlc(ctx, cid) < 0) return -1; if (buf_size < ctx->cid_table->coding_unit_size) { From 0c46e958d1fd3817b8e9fa048d0450d509c80378 Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Fri, 7 Oct 2011 18:41:06 -0700 Subject: [PATCH 15/34] mxfdec: Fix some buffer overreads caused by the misuse of AVPacket related functions. --- libavformat/mxfdec.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c index 8906bdd78f..d0a8a3afe2 100644 --- a/libavformat/mxfdec.c +++ b/libavformat/mxfdec.c @@ -224,12 +224,13 @@ static int mxf_get_d10_aes3_packet(AVIOContext *pb, AVStream *st, AVPacket *pkt, if (length > 61444) /* worst case PAL 1920 samples 8 channels */ return -1; - av_new_packet(pkt, length); - avio_read(pb, pkt->data, length); + length = av_get_packet(pb, pkt, length); + if (length < 0) + return length; data_ptr = pkt->data; end_ptr = pkt->data + length; buf_ptr = pkt->data + 4; /* skip SMPTE 331M header */ - for (; buf_ptr < end_ptr; ) { + for (; buf_ptr + st->codec->channels*4 < end_ptr; ) { for (i = 0; i < st->codec->channels; i++) { uint32_t sample = bytestream_get_le32(&buf_ptr); if (st->codec->bits_per_coded_sample == 24) @@ -239,7 +240,7 @@ static int mxf_get_d10_aes3_packet(AVIOContext *pb, AVStream *st, AVPacket *pkt, } buf_ptr += 32 - st->codec->channels*4; // always 8 channels stored SMPTE 331M } - pkt->size = data_ptr - pkt->data; + av_shrink_packet(pkt, data_ptr - pkt->data); return 0; } @@ -291,12 +292,16 @@ static int mxf_decrypt_triplet(AVFormatContext *s, AVPacket *pkt, KLVPacket *klv if (memcmp(tmpbuf, checkv, 16)) av_log(s, AV_LOG_ERROR, "probably incorrect decryption key\n"); size -= 32; - av_get_packet(pb, pkt, size); + size = av_get_packet(pb, pkt, size); + if (size < 0) + return size; + else if (size < plaintext_size) + return AVERROR_INVALIDDATA; size -= plaintext_size; if (mxf->aesc) av_aes_crypt(mxf->aesc, &pkt->data[plaintext_size], &pkt->data[plaintext_size], size >> 4, ivec, 1); - pkt->size = orig_size; + av_shrink_packet(pkt, orig_size); pkt->stream_index = index; avio_skip(pb, end - avio_tell(pb)); return 0; @@ -333,8 +338,11 @@ static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt) av_log(s, AV_LOG_ERROR, "error reading D-10 aes3 frame\n"); return -1; } - } else - av_get_packet(s->pb, pkt, klv.length); + } else { + int ret = av_get_packet(s->pb, pkt, klv.length); + if (ret < 0) + return ret; + } pkt->stream_index = index; pkt->pos = klv.offset; return 0; From 1703013cb7f06bb6304cbf3c5fd650d8076ee295 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Sat, 8 Oct 2011 01:51:37 +0100 Subject: [PATCH 16/34] avidec: fix signed overflow in avi_sync() Keeping byte values read from the file as unsigned is consistent with how they are subsequently used and avoids an undefined left shift by 24 when bit 7 is set. Signed-off-by: Mans Rullgard --- libavformat/avidec.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libavformat/avidec.c b/libavformat/avidec.c index 81f72d336f..da92353b00 100644 --- a/libavformat/avidec.c +++ b/libavformat/avidec.c @@ -843,7 +843,8 @@ static int avi_sync(AVFormatContext *s, int exit_early) { AVIContext *avi = s->priv_data; AVIOContext *pb = s->pb; - int n, d[8]; + int n; + unsigned int d[8]; unsigned int size; int64_t i, sync; @@ -860,7 +861,7 @@ start_sync: n= get_stream_idx(d+2); //av_log(s, AV_LOG_DEBUG, "%X %X %X %X %X %X %X %X %"PRId64" %d %d\n", d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], i, size, n); - if(i + (uint64_t)size > avi->fsize || d[0]<0) + if(i + (uint64_t)size > avi->fsize || d[0] > 127) continue; //parse ix## From c8d787d2ef1c6dc0af29acb8bac97a6ae67d0520 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Tue, 23 Aug 2011 10:23:57 +0200 Subject: [PATCH 17/34] AVOptions: split av_set_string3 into opt type-specific functions Also stop attempting to honor the alloc parameter, as things break horribly in that case. It will be removed in upcoming successor to av_set_string3. --- libavutil/opt.c | 179 +++++++++++++++++++++++++++--------------------- libavutil/opt.h | 4 +- 2 files changed, 102 insertions(+), 81 deletions(-) diff --git a/libavutil/opt.c b/libavutil/opt.c index 1dec9a67d4..876ea4c511 100644 --- a/libavutil/opt.c +++ b/libavutil/opt.c @@ -116,10 +116,98 @@ static int hexchar2int(char c) { return -1; } +static int set_string_binary(void *obj, const AVOption *o, const char *val, uint8_t **dst) +{ + int *lendst = (int *)(dst + 1); + uint8_t *bin, *ptr; + int len = strlen(val); + + av_freep(dst); + *lendst = 0; + + if (len & 1) + return AVERROR(EINVAL); + len /= 2; + + ptr = bin = av_malloc(len); + while (*val) { + int a = hexchar2int(*val++); + int b = hexchar2int(*val++); + if (a < 0 || b < 0) { + av_free(bin); + return AVERROR(EINVAL); + } + *ptr++ = (a << 4) | b; + } + *dst = bin; + *lendst = len; + + return 0; +} + +static int set_string(void *obj, const AVOption *o, const char *val, uint8_t **dst) +{ + av_freep(dst); + *dst = av_strdup(val); + return 0; +} + +static int set_string_number(void *obj, const AVOption *o, const char *val, void *dst) +{ + int ret = 0, notfirst = 0; + for (;;) { + int i; + char buf[256]; + int cmd = 0; + double d; + + if (*val == '+' || *val == '-') + cmd = *(val++); + + for (i = 0; i < sizeof(buf) - 1 && val[i] && val[i] != '+' && val[i] != '-'; i++) + buf[i] = val[i]; + buf[i] = 0; + + { + const AVOption *o_named = av_opt_find(obj, buf, o->unit, 0, 0); + if (o_named && o_named->type == FF_OPT_TYPE_CONST) + d = o_named->default_val.dbl; + else if (!strcmp(buf, "default")) d = o->default_val.dbl; + else if (!strcmp(buf, "max" )) d = o->max; + else if (!strcmp(buf, "min" )) d = o->min; + else if (!strcmp(buf, "none" )) d = 0; + else if (!strcmp(buf, "all" )) d = ~0; + else { + int res = av_expr_parse_and_eval(&d, buf, const_names, const_values, NULL, NULL, NULL, NULL, NULL, 0, obj); + if (res < 0) { + av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\"\n", val); + return res; + } + } + } + if (o->type == FF_OPT_TYPE_FLAGS) { + if (cmd == '+') d = av_get_int(obj, o->name, NULL) | (int64_t)d; + else if (cmd == '-') d = av_get_int(obj, o->name, NULL) &~(int64_t)d; + } else { + if (cmd == '+') d = notfirst*av_get_double(obj, o->name, NULL) + d; + else if (cmd == '-') d = notfirst*av_get_double(obj, o->name, NULL) - d; + } + + if ((ret = av_set_number2(obj, o->name, d, 1, 1, NULL)) < 0) + return ret; + val += i; + if (!*val) + return 0; + notfirst = 1; + } + + return 0; +} + int av_set_string3(void *obj, const char *name, const char *val, int alloc, const AVOption **o_out) { - int ret; const AVOption *o = av_opt_find(obj, name, NULL, 0, 0); + void *dst; if (o_out) *o_out = o; if (!o) @@ -127,85 +215,20 @@ int av_set_string3(void *obj, const char *name, const char *val, int alloc, cons if (!val) return AVERROR(EINVAL); - if (o->type == FF_OPT_TYPE_BINARY) { - uint8_t **dst = (uint8_t **)(((uint8_t*)obj) + o->offset); - int *lendst = (int *)(dst + 1); - uint8_t *bin, *ptr; - int len = strlen(val); - av_freep(dst); - *lendst = 0; - if (len & 1) return AVERROR(EINVAL); - len /= 2; - ptr = bin = av_malloc(len); - while (*val) { - int a = hexchar2int(*val++); - int b = hexchar2int(*val++); - if (a < 0 || b < 0) { - av_free(bin); - return AVERROR(EINVAL); - } - *ptr++ = (a << 4) | b; - } - *dst = bin; - *lendst = len; - return 0; - } - if (o->type != FF_OPT_TYPE_STRING) { - int notfirst=0; - for (;;) { - int i; - char buf[256]; - int cmd=0; - double d; - - if (*val == '+' || *val == '-') - cmd= *(val++); - - for (i=0; iunit, 0, 0); - if (o_named && o_named->type == FF_OPT_TYPE_CONST) - d= o_named->default_val.dbl; - else if (!strcmp(buf, "default")) d= o->default_val.dbl; - else if (!strcmp(buf, "max" )) d= o->max; - else if (!strcmp(buf, "min" )) d= o->min; - else if (!strcmp(buf, "none" )) d= 0; - else if (!strcmp(buf, "all" )) d= ~0; - else { - int res = av_expr_parse_and_eval(&d, buf, const_names, const_values, NULL, NULL, NULL, NULL, NULL, 0, obj); - if (res < 0) { - av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\"\n", val); - return res; - } - } - } - if (o->type == FF_OPT_TYPE_FLAGS) { - if (cmd=='+') d= av_get_int(obj, name, NULL) | (int64_t)d; - else if (cmd=='-') d= av_get_int(obj, name, NULL) &~(int64_t)d; - } else { - if (cmd=='+') d= notfirst*av_get_double(obj, name, NULL) + d; - else if (cmd=='-') d= notfirst*av_get_double(obj, name, NULL) - d; - } - - if ((ret = av_set_number2(obj, name, d, 1, 1, o_out)) < 0) - return ret; - val+= i; - if (!*val) - return 0; - notfirst=1; - } + dst = ((uint8_t*)obj) + o->offset; + switch (o->type) { + case FF_OPT_TYPE_STRING: return set_string(obj, o, val, dst); + case FF_OPT_TYPE_BINARY: return set_string_binary(obj, o, val, dst); + case FF_OPT_TYPE_FLAGS: + case FF_OPT_TYPE_INT: + case FF_OPT_TYPE_INT64: + case FF_OPT_TYPE_FLOAT: + case FF_OPT_TYPE_DOUBLE: + case FF_OPT_TYPE_RATIONAL: return set_string_number(obj, o, val, dst); } - if (alloc) { - av_free(*(void**)(((uint8_t*)obj) + o->offset)); - val= av_strdup(val); - } - - memcpy(((uint8_t*)obj) + o->offset, &val, sizeof(val)); - return 0; + av_log(obj, AV_LOG_ERROR, "Invalid option type.\n"); + return AVERROR(EINVAL); } const AVOption *av_set_double(void *obj, const char *name, double n) diff --git a/libavutil/opt.h b/libavutil/opt.h index c6a59196be..50c0a33bc7 100644 --- a/libavutil/opt.h +++ b/libavutil/opt.h @@ -129,9 +129,7 @@ const AVOption *av_find_opt(void *obj, const char *name, const char *unit, int m * similarly, '-' unsets a flag. * @param[out] o_out if non-NULL put here a pointer to the AVOption * found - * @param alloc when 1 then the old value will be av_freed() and the - * new av_strduped() - * when 0 then no av_free() nor av_strdup() will be used + * @param alloc this parameter is currently ignored * @return 0 if the value has been set, or an AVERROR code in case of * error: * AVERROR_OPTION_NOT_FOUND if no matching option exists From b003d0be5b332fa1dcac0549c80c02676c245024 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Tue, 23 Aug 2011 13:03:42 +0200 Subject: [PATCH 18/34] AVOptions: cosmetics, move and rename static av_set_number(). --- libavutil/opt.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/libavutil/opt.c b/libavutil/opt.c index 876ea4c511..2ff9166931 100644 --- a/libavutil/opt.c +++ b/libavutil/opt.c @@ -86,15 +86,6 @@ static int av_set_number2(void *obj, const char *name, double num, int den, int6 return 0; } -static const AVOption *av_set_number(void *obj, const char *name, double num, int den, int64_t intnum) -{ - const AVOption *o = NULL; - if (av_set_number2(obj, name, num, den, intnum, &o) < 0) - return NULL; - else - return o; -} - static const double const_values[] = { M_PI, M_E, @@ -231,19 +222,28 @@ int av_set_string3(void *obj, const char *name, const char *val, int alloc, cons return AVERROR(EINVAL); } +static const AVOption *set_number(void *obj, const char *name, double num, int den, int64_t intnum) +{ + const AVOption *o = NULL; + if (av_set_number2(obj, name, num, den, intnum, &o) < 0) + return NULL; + else + return o; +} + const AVOption *av_set_double(void *obj, const char *name, double n) { - return av_set_number(obj, name, n, 1, 1); + return set_number(obj, name, n, 1, 1); } const AVOption *av_set_q(void *obj, const char *name, AVRational n) { - return av_set_number(obj, name, n.num, n.den, 1); + return set_number(obj, name, n.num, n.den, 1); } const AVOption *av_set_int(void *obj, const char *name, int64_t n) { - return av_set_number(obj, name, 1, 1, n); + return set_number(obj, name, 1, 1, n); } /** From cf10095f0b8bb0963dd895d2825a035fcb7e1bb5 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Tue, 23 Aug 2011 13:07:17 +0200 Subject: [PATCH 19/34] AVOptions: cosmetics, rename static av_set_number2() to write_number(). --- libavutil/opt.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavutil/opt.c b/libavutil/opt.c index 2ff9166931..b3f29a5b89 100644 --- a/libavutil/opt.c +++ b/libavutil/opt.c @@ -54,7 +54,7 @@ const AVOption *av_next_option(void *obj, const AVOption *last) else return (*(AVClass**)obj)->option; } -static int av_set_number2(void *obj, const char *name, double num, int den, int64_t intnum, const AVOption **o_out) +static int write_number(void *obj, const char *name, double num, int den, int64_t intnum, const AVOption **o_out) { const AVOption *o = av_opt_find(obj, name, NULL, 0, 0); void *dst; @@ -184,7 +184,7 @@ static int set_string_number(void *obj, const AVOption *o, const char *val, void else if (cmd == '-') d = notfirst*av_get_double(obj, o->name, NULL) - d; } - if ((ret = av_set_number2(obj, o->name, d, 1, 1, NULL)) < 0) + if ((ret = write_number(obj, o->name, d, 1, 1, NULL)) < 0) return ret; val += i; if (!*val) @@ -225,7 +225,7 @@ int av_set_string3(void *obj, const char *name, const char *val, int alloc, cons static const AVOption *set_number(void *obj, const char *name, double num, int den, int64_t intnum) { const AVOption *o = NULL; - if (av_set_number2(obj, name, num, den, intnum, &o) < 0) + if (write_number(obj, name, num, den, intnum, &o) < 0) return NULL; else return o; From 7bb1807c2dd9623842f1c6d454e7f2892b5bc8d7 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Tue, 23 Aug 2011 12:58:49 +0200 Subject: [PATCH 20/34] AVOptions: refactor set_number/write_number write_number() does the actual writing of the supplied number to destination. Move finding the option and choosing destination address out of it. --- libavutil/opt.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/libavutil/opt.c b/libavutil/opt.c index b3f29a5b89..78fdf63a32 100644 --- a/libavutil/opt.c +++ b/libavutil/opt.c @@ -54,22 +54,13 @@ const AVOption *av_next_option(void *obj, const AVOption *last) else return (*(AVClass**)obj)->option; } -static int write_number(void *obj, const char *name, double num, int den, int64_t intnum, const AVOption **o_out) +static int write_number(void *obj, const AVOption *o, void *dst, double num, int den, int64_t intnum) { - const AVOption *o = av_opt_find(obj, name, NULL, 0, 0); - void *dst; - if (o_out) - *o_out= o; - if (!o) - return AVERROR_OPTION_NOT_FOUND; - if (o->max*den < num*intnum || o->min*den > num*intnum) { - av_log(obj, AV_LOG_ERROR, "Value %lf for parameter '%s' out of range\n", num, name); + av_log(obj, AV_LOG_ERROR, "Value %lf for parameter '%s' out of range\n", num, o->name); return AVERROR(ERANGE); } - dst= ((uint8_t*)obj) + o->offset; - switch (o->type) { case FF_OPT_TYPE_FLAGS: case FF_OPT_TYPE_INT: *(int *)dst= llrint(num/den)*intnum; break; @@ -184,7 +175,7 @@ static int set_string_number(void *obj, const AVOption *o, const char *val, void else if (cmd == '-') d = notfirst*av_get_double(obj, o->name, NULL) - d; } - if ((ret = write_number(obj, o->name, d, 1, 1, NULL)) < 0) + if ((ret = write_number(obj, o, dst, d, 1, 1)) < 0) return ret; val += i; if (!*val) @@ -224,8 +215,14 @@ int av_set_string3(void *obj, const char *name, const char *val, int alloc, cons static const AVOption *set_number(void *obj, const char *name, double num, int den, int64_t intnum) { - const AVOption *o = NULL; - if (write_number(obj, name, num, den, intnum, &o) < 0) + const AVOption *o = av_opt_find(obj, name, NULL, 0, 0); + void *dst; + + if (!o) + return NULL; + + dst = ((uint8_t*)obj) + o->offset; + if (write_number(obj, o, dst, num, den, intnum) < 0) return NULL; else return o; From 76c6971a6464705f263fc30e537b370a3a7c853b Mon Sep 17 00:00:00 2001 From: Laurent Aimar Date: Fri, 30 Sep 2011 23:42:31 +0000 Subject: [PATCH 21/34] avsdemux: check for corrupted data Signed-off-by: Janne Grunau --- libavformat/avs.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavformat/avs.c b/libavformat/avs.c index bf3d4f95bb..1c699fbf3c 100644 --- a/libavformat/avs.c +++ b/libavformat/avs.c @@ -163,6 +163,8 @@ static int avs_read_packet(AVFormatContext * s, AVPacket * pkt) sub_type = avio_r8(s->pb); type = avio_r8(s->pb); size = avio_rl16(s->pb); + if (size < 4) + return AVERROR_INVALIDDATA; avs->remaining_frame_size -= size; switch (type) { From de049a95f4a8089b2878c7fcef6cac7e88a8f1bf Mon Sep 17 00:00:00 2001 From: Laurent Aimar Date: Fri, 30 Sep 2011 23:42:31 +0000 Subject: [PATCH 22/34] avs: check for out of bound reads Signed-off-by: Janne Grunau --- libavcodec/avs.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/libavcodec/avs.c b/libavcodec/avs.c index 8221b7b766..3ccded3f8c 100644 --- a/libavcodec/avs.c +++ b/libavcodec/avs.c @@ -47,6 +47,7 @@ avs_decode_frame(AVCodecContext * avctx, void *data, int *data_size, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; + const uint8_t *buf_end = avpkt->data + avpkt->size; int buf_size = avpkt->size; AvsContext *const avs = avctx->priv_data; AVFrame *picture = data; @@ -69,6 +70,8 @@ avs_decode_frame(AVCodecContext * avctx, out = avs->picture.data[0]; stride = avs->picture.linesize[0]; + if (buf_end - buf < 4) + return AVERROR_INVALIDDATA; sub_type = buf[0]; type = buf[1]; buf += 4; @@ -79,6 +82,8 @@ avs_decode_frame(AVCodecContext * avctx, first = AV_RL16(buf); last = first + AV_RL16(buf + 2); + if (first >= 256 || last > 256 || buf_end - buf < 4 + 4 + 3 * (last - first)) + return AVERROR_INVALIDDATA; buf += 4; for (i=first; i Date: Fri, 30 Sep 2011 23:42:31 +0000 Subject: [PATCH 23/34] avsdemux: check for out of bound writes Signed-off-by: Janne Grunau --- libavformat/avs.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavformat/avs.c b/libavformat/avs.c index 1c699fbf3c..cc0e849bc2 100644 --- a/libavformat/avs.c +++ b/libavformat/avs.c @@ -169,6 +169,8 @@ static int avs_read_packet(AVFormatContext * s, AVPacket * pkt) switch (type) { case AVS_PALETTE: + if (size - 4 > sizeof(palette)) + return AVERROR_INVALIDDATA; ret = avio_read(s->pb, palette, size - 4); if (ret < size - 4) return AVERROR(EIO); From 2475f1a83ccf313d828b25f1769e3a37442ecf64 Mon Sep 17 00:00:00 2001 From: Laurent Aimar Date: Fri, 30 Sep 2011 23:42:32 +0000 Subject: [PATCH 24/34] anm: prevent infinite loop Signed-off-by: Janne Grunau --- libavcodec/anm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/anm.c b/libavcodec/anm.c index 94cac5e3ce..59de984301 100644 --- a/libavcodec/anm.c +++ b/libavcodec/anm.c @@ -81,6 +81,8 @@ static inline int op(uint8_t **dst, const uint8_t *dst_end, int striplen = FFMIN(count, remaining); if (buf) { striplen = FFMIN(striplen, buf_end - *buf); + if (*buf >= buf_end) + goto exhausted; memcpy(*dst, *buf, striplen); *buf += striplen; } else if (pixel >= 0) From c7f89064e2f0fef8198aadf64b0daf12787404ee Mon Sep 17 00:00:00 2001 From: Laurent Aimar Date: Fri, 30 Sep 2011 23:42:32 +0000 Subject: [PATCH 25/34] adpcm: fix out of bound reads due to integer overflow Signed-off-by: Janne Grunau --- libavcodec/adpcm.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index fadafafa3f..98da4591b0 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -630,10 +630,11 @@ static int adpcm_decode_frame(AVCodecContext *avctx, buf_size -= 128; } break; - case CODEC_ID_ADPCM_IMA_EA_EACS: + case CODEC_ID_ADPCM_IMA_EA_EACS: { + unsigned header_size = 4 + (8<> (1-st); - if (samples_in_chunk > buf_size-4-(8< buf_size - header_size) { src += buf_size - 4; break; } @@ -648,6 +649,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx, *samples++ = adpcm_ima_expand_nibble(&c->status[st], *src&0x0F, 3); } break; + } case CODEC_ID_ADPCM_IMA_EA_SEAD: for (; src < buf+buf_size; src++) { *samples++ = adpcm_ima_expand_nibble(&c->status[0], src[0] >> 4, 6); From 8df8a87e3fd5bd0c3dabc676aae8fd84992932dc Mon Sep 17 00:00:00 2001 From: Laurent Aimar Date: Fri, 30 Sep 2011 23:42:32 +0000 Subject: [PATCH 26/34] eacmv: fix potential pointer arithmetic overflows Signed-off-by: Janne Grunau --- libavcodec/eacmv.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavcodec/eacmv.c b/libavcodec/eacmv.c index 7449f7d47b..0a146f5347 100644 --- a/libavcodec/eacmv.c +++ b/libavcodec/eacmv.c @@ -52,7 +52,7 @@ static void cmv_decode_intra(CmvContext * s, const uint8_t *buf, const uint8_t * unsigned char *dst = s->frame.data[0]; int i; - for (i=0; i < s->avctx->height && buf+s->avctx->width<=buf_end; i++) { + for (i=0; i < s->avctx->height && buf_end - buf >= s->avctx->width; i++) { memcpy(dst, buf, s->avctx->width); dst += s->frame.linesize[0]; buf += s->avctx->width; @@ -84,7 +84,7 @@ static void cmv_decode_inter(CmvContext * s, const uint8_t *buf, const uint8_t * i = 0; for(y=0; yavctx->height/4; y++) - for(x=0; xavctx->width/4 && buf+iavctx->width/4 && buf_end - buf > i; x++) { if (buf[i]==0xFF) { unsigned char *dst = s->frame.data[0] + (y*4)*s->frame.linesize[0] + x*4; if (raw+16=buf_end) { + if(buf_end - buf < 16) { av_log(s->avctx, AV_LOG_WARNING, "truncated header\n"); return; } @@ -135,7 +135,7 @@ static void cmv_process_header(CmvContext *s, const uint8_t *buf, const uint8_t pal_count = AV_RL16(&buf[14]); buf += 16; - for (i=pal_start; i= 3; i++) { s->palette[i] = AV_RB24(buf); buf += 3; } From 46cb2f6a2928a7fa4bee3f09b0475ccb8cdd2064 Mon Sep 17 00:00:00 2001 From: Laurent Aimar Date: Fri, 30 Sep 2011 23:42:32 +0000 Subject: [PATCH 27/34] eacmv: check for out of bound reads Signed-off-by: Janne Grunau --- libavcodec/eacmv.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libavcodec/eacmv.c b/libavcodec/eacmv.c index 0a146f5347..085e2d8177 100644 --- a/libavcodec/eacmv.c +++ b/libavcodec/eacmv.c @@ -153,6 +153,9 @@ static int cmv_decode_frame(AVCodecContext *avctx, CmvContext *s = avctx->priv_data; const uint8_t *buf_end = buf + buf_size; + if (buf_end - buf < EA_PREAMBLE_SIZE) + return AVERROR_INVALIDDATA; + if (AV_RL32(buf)==MVIh_TAG||AV_RB32(buf)==MVIh_TAG) { cmv_process_header(s, buf+EA_PREAMBLE_SIZE, buf_end); return buf_size; From 04a845caa7cdcdd1457f8c0dde52a7b2085ed92f Mon Sep 17 00:00:00 2001 From: Laurent Aimar Date: Fri, 30 Sep 2011 23:42:33 +0000 Subject: [PATCH 28/34] tiffdec: fix out of bound reads/writes Signed-off-by: Janne Grunau --- libavcodec/tiff.c | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c index ab5f1ebd11..a88d0f988b 100644 --- a/libavcodec/tiff.c +++ b/libavcodec/tiff.c @@ -173,6 +173,8 @@ static int tiff_unpack_strip(TiffContext *s, uint8_t* dst, int stride, const uin } switch(s->compr){ case TIFF_RAW: + if (ssrc + size - src < width) + return AVERROR_INVALIDDATA; if (!s->fill_order) { memcpy(dst, src, width); } else { @@ -280,6 +282,8 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t * uint32_t *pal; const uint8_t *rp, *gp, *bp; + if (end_buf - buf < 12) + return -1; tag = tget_short(&buf, s->le); type = tget_short(&buf, s->le); count = tget_long(&buf, s->le); @@ -339,7 +343,7 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t * case TIFF_SHORT: case TIFF_LONG: s->bpp = 0; - for(i = 0; i < count; i++) s->bpp += tget(&buf, type, s->le); + for(i = 0; i < count && buf < end_buf; i++) s->bpp += tget(&buf, type, s->le); break; default: s->bpp = -1; @@ -453,6 +457,8 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t * case TIFF_PAL: pal = (uint32_t *) s->palette; off = type_sizes[type]; + if (count / 3 > 256 || end_buf - buf < count / 3 * off * 3) + return -1; rp = buf; gp = buf + count / 3 * off; bp = buf + count / 3 * off * 2; @@ -495,12 +501,16 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *picture = data; AVFrame * const p= (AVFrame*)&s->picture; const uint8_t *orig_buf = buf, *end_buf = buf + buf_size; - int id, le, off, ret; + unsigned off; + int id, le, ret; int i, j, entries; - int stride, soff, ssize; + int stride; + unsigned soff, ssize; uint8_t *dst; //parse image header + if (end_buf - buf < 8) + return AVERROR_INVALIDDATA; id = AV_RL16(buf); buf += 2; if(id == 0x4949) le = 1; else if(id == 0x4D4D) le = 0; @@ -520,9 +530,9 @@ static int decode_frame(AVCodecContext *avctx, } /* parse image file directory */ off = tget_long(&buf, le); - if(orig_buf + off + 14 >= end_buf){ + if (off >= UINT_MAX - 14 || end_buf - orig_buf < off + 14) { av_log(avctx, AV_LOG_ERROR, "IFD offset is greater than image size\n"); - return -1; + return AVERROR_INVALIDDATA; } buf = orig_buf + off; entries = tget_short(&buf, le); @@ -546,23 +556,23 @@ static int decode_frame(AVCodecContext *avctx, stride = p->linesize[0]; dst = p->data[0]; for(i = 0; i < s->height; i += s->rps){ - if(s->stripsizes) + if(s->stripsizes) { + if (s->stripsizes >= end_buf) + return AVERROR_INVALIDDATA; ssize = tget(&s->stripsizes, s->sstype, s->le); - else + } else ssize = s->stripsize; - if (ssize > buf_size) { - av_log(avctx, AV_LOG_ERROR, "Buffer size is smaller than strip size\n"); - return -1; - } - if(s->stripdata){ + if (s->stripdata >= end_buf) + return AVERROR_INVALIDDATA; soff = tget(&s->stripdata, s->sot, s->le); }else soff = s->stripoff; - if (soff < 0) { - av_log(avctx, AV_LOG_ERROR, "Invalid stripoff: %d\n", soff); - return AVERROR(EINVAL); + + if (soff > buf_size || ssize > buf_size - soff) { + av_log(avctx, AV_LOG_ERROR, "Invalid strip size/offset\n"); + return -1; } if(tiff_unpack_strip(s, dst, stride, orig_buf + soff, ssize, FFMIN(s->rps, s->height - i)) < 0) break; From dc64f203a62083c3d5f81e8201018279c29581af Mon Sep 17 00:00:00 2001 From: Laurent Aimar Date: Sun, 2 Oct 2011 00:48:12 +0000 Subject: [PATCH 29/34] ptx: check for out of bound reads Signed-off-by: Janne Grunau --- libavcodec/ptx.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libavcodec/ptx.c b/libavcodec/ptx.c index 5dadaf6ece..eee0d58994 100644 --- a/libavcodec/ptx.c +++ b/libavcodec/ptx.c @@ -39,12 +39,15 @@ static av_cold int ptx_init(AVCodecContext *avctx) { static int ptx_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; + const uint8_t *buf_end = avpkt->data + avpkt->size; PTXContext * const s = avctx->priv_data; AVFrame *picture = data; AVFrame * const p = &s->picture; unsigned int offset, w, h, y, stride, bytes_per_pixel; uint8_t *ptr; + if (buf_end - buf < 14) + return AVERROR_INVALIDDATA; offset = AV_RL16(buf); w = AV_RL16(buf+8); h = AV_RL16(buf+10); @@ -57,6 +60,8 @@ static int ptx_decode_frame(AVCodecContext *avctx, void *data, int *data_size, avctx->pix_fmt = PIX_FMT_RGB555; + if (buf_end - buf < offset) + return AVERROR_INVALIDDATA; if (offset != 0x2c) av_log_ask_for_sample(avctx, "offset != 0x2c\n"); @@ -80,6 +85,8 @@ static int ptx_decode_frame(AVCodecContext *avctx, void *data, int *data_size, stride = p->linesize[0]; for (y=0; y Date: Sun, 2 Oct 2011 00:48:11 +0000 Subject: [PATCH 30/34] 4xm: clear FF_INPUT_BUFFER_PADDING_SIZE bytes in temporary buffers Signed-off-by: Janne Grunau --- libavcodec/4xm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/4xm.c b/libavcodec/4xm.c index 847ebce2b6..d428f53275 100644 --- a/libavcodec/4xm.c +++ b/libavcodec/4xm.c @@ -399,6 +399,7 @@ static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length){ if (!f->bitstream_buffer) return AVERROR(ENOMEM); f->dsp.bswap_buf(f->bitstream_buffer, (const uint32_t*)(buf + extra), bitstream_size/4); + memset((uint8_t*)f->bitstream_buffer + bitstream_size, 0, FF_INPUT_BUFFER_PADDING_SIZE); init_get_bits(&f->gb, f->bitstream_buffer, 8*bitstream_size); f->wordstream= (const uint16_t*)(buf + extra + bitstream_size); @@ -679,6 +680,7 @@ static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length){ if (!f->bitstream_buffer) return AVERROR(ENOMEM); f->dsp.bswap_buf(f->bitstream_buffer, (const uint32_t*)prestream, prestream_size/4); + memset((uint8_t*)f->bitstream_buffer + prestream_size, 0, FF_INPUT_BUFFER_PADDING_SIZE); init_get_bits(&f->pre_gb, f->bitstream_buffer, 8*prestream_size); f->last_dc= 0*128*8*8; From 79964745b3ed5a700f4f0dda56c7360497328c88 Mon Sep 17 00:00:00 2001 From: Laurent Aimar Date: Sun, 2 Oct 2011 00:48:11 +0000 Subject: [PATCH 31/34] 4xmdemux: prevent use of uninitialized memory Signed-off-by: Janne Grunau --- libavformat/4xm.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libavformat/4xm.c b/libavformat/4xm.c index 6224134948..1557c5b5a4 100644 --- a/libavformat/4xm.c +++ b/libavformat/4xm.c @@ -173,13 +173,15 @@ static int fourxm_read_header(AVFormatContext *s, goto fail; } if (current_track + 1 > fourxm->track_count) { - fourxm->track_count = current_track + 1; fourxm->tracks = av_realloc(fourxm->tracks, - fourxm->track_count * sizeof(AudioTrack)); + (current_track + 1) * sizeof(AudioTrack)); if (!fourxm->tracks) { - ret= AVERROR(ENOMEM); + ret = AVERROR(ENOMEM); goto fail; } + memset(&fourxm->tracks[fourxm->track_count], 0, + sizeof(AudioTrack) * (current_track + 1 - fourxm->track_count)); + fourxm->track_count = current_track + 1; } fourxm->tracks[current_track].adpcm = AV_RL32(&header[i + 12]); fourxm->tracks[current_track].channels = AV_RL32(&header[i + 36]); From 1b1182ce97db7a97914bb7713eba66fee5d93937 Mon Sep 17 00:00:00 2001 From: Laurent Aimar Date: Sun, 2 Oct 2011 00:48:11 +0000 Subject: [PATCH 32/34] 4xm: prevent NULL dereference with invalid huffman table Signed-off-by: Janne Grunau --- libavcodec/4xm.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libavcodec/4xm.c b/libavcodec/4xm.c index d428f53275..21bde52fee 100644 --- a/libavcodec/4xm.c +++ b/libavcodec/4xm.c @@ -602,9 +602,10 @@ static const uint8_t *read_huffman_tables(FourXContext *f, const uint8_t * const len_tab[j]= len; } - init_vlc(&f->pre_vlc, ACDC_VLC_BITS, 257, - len_tab , 1, 1, - bits_tab, 4, 4, 0); + if (init_vlc(&f->pre_vlc, ACDC_VLC_BITS, 257, + len_tab , 1, 1, + bits_tab, 4, 4, 0)) + return NULL; return ptr; } From e8ac80fb2c587cc507d9533af8f4313924ee05a1 Mon Sep 17 00:00:00 2001 From: Laurent Aimar Date: Sun, 2 Oct 2011 00:48:12 +0000 Subject: [PATCH 33/34] error_resilience: fix the check for missing references in ff_er_frame_end() for H264 Signed-off-by: Janne Grunau --- libavcodec/error_resilience.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/error_resilience.c b/libavcodec/error_resilience.c index 11e2636242..23ac904c6c 100644 --- a/libavcodec/error_resilience.c +++ b/libavcodec/error_resilience.c @@ -652,7 +652,7 @@ static int is_intra_more_likely(MpegEncContext *s){ if(s->codec_id == CODEC_ID_H264){ H264Context *h= (void*)s; - if (h->ref_count[0] <= 0 || !h->ref_list[0][0].f.data[0]) + if (h->list_count <= 0 || h->ref_count[0] <= 0 || !h->ref_list[0][0].f.data[0]) return 1; } From 4c7a232fc81fdbdee279ab819a255f624a22b083 Mon Sep 17 00:00:00 2001 From: Laurent Aimar Date: Sun, 2 Oct 2011 14:03:47 +0000 Subject: [PATCH 34/34] h264: reset h->ref_count in case of errors in ff_h264_decode_ref_pic_list_reordering() Signed-off-by: Janne Grunau --- libavcodec/h264.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libavcodec/h264.c b/libavcodec/h264.c index aac1a15a92..4dbd06375b 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -2857,8 +2857,10 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ ff_h264_fill_default_ref_list(h); } - if(h->slice_type_nos!=AV_PICTURE_TYPE_I && ff_h264_decode_ref_pic_list_reordering(h) < 0) + if(h->slice_type_nos!=AV_PICTURE_TYPE_I && ff_h264_decode_ref_pic_list_reordering(h) < 0) { + h->ref_count[1]= h->ref_count[0]= 0; return -1; + } if(h->slice_type_nos!=AV_PICTURE_TYPE_I){ s->last_picture_ptr= &h->ref_list[0][0];