X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fvc1dec.c;h=403cbbc89aaf4d156b18005de365f6f30a664f68;hb=3aca10bf762a94d7de555cedf1ff0e4f6792bf41;hp=1151318a474ed18a0e85cc54db702c1116c2a1bd;hpb=4f820131fa9fbb0a64d7cc469fa471905fc91944;p=ffmpeg diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c index 1151318a474..403cbbc89aa 100644 --- a/libavcodec/vc1dec.c +++ b/libavcodec/vc1dec.c @@ -27,172 +27,29 @@ */ #include "internal.h" -#include "dsputil.h" #include "avcodec.h" +#include "error_resilience.h" #include "mpegvideo.h" #include "h263.h" +#include "h264chroma.h" #include "vc1.h" #include "vc1data.h" #include "vc1acdata.h" #include "msmpeg4data.h" #include "unary.h" -#include "simple_idct.h" #include "mathops.h" -#include "vdpau_internal.h" #undef NDEBUG #include #define MB_INTRA_VLC_BITS 9 #define DC_VLC_BITS 9 -#define AC_VLC_BITS 9 -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, 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 - * @return Status - */ -static int vc1_init_common(VC1Context *v) -{ - static int done = 0; - int i = 0; - static VLC_TYPE vlc_table[32372][2]; - - v->hrd_rate = v->hrd_buffer = NULL; - - /* VLC tables */ - if (!done) { - INIT_VLC_STATIC(&ff_vc1_bfraction_vlc, VC1_BFRACTION_VLC_BITS, 23, - ff_vc1_bfraction_bits, 1, 1, - ff_vc1_bfraction_codes, 1, 1, 1 << VC1_BFRACTION_VLC_BITS); - INIT_VLC_STATIC(&ff_vc1_norm2_vlc, VC1_NORM2_VLC_BITS, 4, - ff_vc1_norm2_bits, 1, 1, - ff_vc1_norm2_codes, 1, 1, 1 << VC1_NORM2_VLC_BITS); - INIT_VLC_STATIC(&ff_vc1_norm6_vlc, VC1_NORM6_VLC_BITS, 64, - ff_vc1_norm6_bits, 1, 1, - ff_vc1_norm6_codes, 2, 2, 556); - INIT_VLC_STATIC(&ff_vc1_imode_vlc, VC1_IMODE_VLC_BITS, 7, - ff_vc1_imode_bits, 1, 1, - ff_vc1_imode_codes, 1, 1, 1 << VC1_IMODE_VLC_BITS); - for (i = 0; i < 3; i++) { - ff_vc1_ttmb_vlc[i].table = &vlc_table[vlc_offs[i * 3 + 0]]; - ff_vc1_ttmb_vlc[i].table_allocated = vlc_offs[i * 3 + 1] - vlc_offs[i * 3 + 0]; - init_vlc(&ff_vc1_ttmb_vlc[i], VC1_TTMB_VLC_BITS, 16, - ff_vc1_ttmb_bits[i], 1, 1, - ff_vc1_ttmb_codes[i], 2, 2, INIT_VLC_USE_NEW_STATIC); - ff_vc1_ttblk_vlc[i].table = &vlc_table[vlc_offs[i * 3 + 1]]; - ff_vc1_ttblk_vlc[i].table_allocated = vlc_offs[i * 3 + 2] - vlc_offs[i * 3 + 1]; - init_vlc(&ff_vc1_ttblk_vlc[i], VC1_TTBLK_VLC_BITS, 8, - ff_vc1_ttblk_bits[i], 1, 1, - ff_vc1_ttblk_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC); - ff_vc1_subblkpat_vlc[i].table = &vlc_table[vlc_offs[i * 3 + 2]]; - ff_vc1_subblkpat_vlc[i].table_allocated = vlc_offs[i * 3 + 3] - vlc_offs[i * 3 + 2]; - init_vlc(&ff_vc1_subblkpat_vlc[i], VC1_SUBBLKPAT_VLC_BITS, 15, - ff_vc1_subblkpat_bits[i], 1, 1, - ff_vc1_subblkpat_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC); - } - for (i = 0; i < 4; i++) { - ff_vc1_4mv_block_pattern_vlc[i].table = &vlc_table[vlc_offs[i * 3 + 9]]; - ff_vc1_4mv_block_pattern_vlc[i].table_allocated = vlc_offs[i * 3 + 10] - vlc_offs[i * 3 + 9]; - init_vlc(&ff_vc1_4mv_block_pattern_vlc[i], VC1_4MV_BLOCK_PATTERN_VLC_BITS, 16, - ff_vc1_4mv_block_pattern_bits[i], 1, 1, - ff_vc1_4mv_block_pattern_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC); - ff_vc1_cbpcy_p_vlc[i].table = &vlc_table[vlc_offs[i * 3 + 10]]; - ff_vc1_cbpcy_p_vlc[i].table_allocated = vlc_offs[i * 3 + 11] - vlc_offs[i * 3 + 10]; - init_vlc(&ff_vc1_cbpcy_p_vlc[i], VC1_CBPCY_P_VLC_BITS, 64, - ff_vc1_cbpcy_p_bits[i], 1, 1, - ff_vc1_cbpcy_p_codes[i], 2, 2, INIT_VLC_USE_NEW_STATIC); - ff_vc1_mv_diff_vlc[i].table = &vlc_table[vlc_offs[i * 3 + 11]]; - ff_vc1_mv_diff_vlc[i].table_allocated = vlc_offs[i * 3 + 12] - vlc_offs[i * 3 + 11]; - init_vlc(&ff_vc1_mv_diff_vlc[i], VC1_MV_DIFF_VLC_BITS, 73, - ff_vc1_mv_diff_bits[i], 1, 1, - 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 * 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; - } - - /* Other defaults */ - v->pq = -1; - v->mvrange = 0; /* 7.1.1.18, p80 */ - - return 0; -} - /***********************************************************************/ /** * @name VC-1 Bitplane decoding @@ -215,6 +72,16 @@ enum Imode { }; /** @} */ //imode defines +static void init_block_index(VC1Context *v) +{ + MpegEncContext *s = &v->s; + ff_init_block_index(s); + if (v->field_mode && !(v->second_field ^ v->tff)) { + s->dest[0] += s->current_picture_ptr->f.linesize[0]; + s->dest[1] += s->current_picture_ptr->f.linesize[1]; + s->dest[2] += s->current_picture_ptr->f.linesize[2]; + } +} /** @} */ //Bitplane group @@ -222,7 +89,7 @@ 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 stride_y, fieldtx = 0; int v_dist; /* The put pixels loop is always one MB row behind the decoding loop, @@ -235,7 +102,8 @@ static void vc1_put_signed_blocks_clamped(VC1Context *v) 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]; + if (v->fcm == ILACE_FRAME) + 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], @@ -259,7 +127,8 @@ static void vc1_put_signed_blocks_clamped(VC1Context *v) } 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]; + if (v->fcm == ILACE_FRAME) + 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], @@ -473,12 +342,17 @@ static void vc1_smooth_overlap_filter_iblk(VC1Context *v) static void vc1_mc_1mv(VC1Context *v, int dir) { MpegEncContext *s = &v->s; - DSPContext *dsp = &v->s.dsp; + H264ChromaContext *h264chroma = &v->h264chroma; uint8_t *srcY, *srcU, *srcV; int dxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y; - int off, off_uv; int v_edge_pos = s->v_edge_pos >> v->field_mode; - if (!v->field_mode && !v->s.last_picture.f.data[0]) + int i; + uint8_t (*luty)[256], (*lutuv)[256]; + int use_ic; + + if ((!v->field_mode || + (v->ref_field_type[dir] == 1 && v->cur_field_type == 1)) && + !v->s.last_picture.f.data[0]) return; mx = s->mv[dir][0][0]; @@ -486,8 +360,10 @@ static void vc1_mc_1mv(VC1Context *v, int dir) // 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] + v->blocks_off][0] = mx; - s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][1] = my; + for (i = 0; i < 4; i++) { + s->current_picture.motion_val[1][s->block_index[i] + v->blocks_off][0] = mx; + s->current_picture.motion_val[1][s->block_index[i] + v->blocks_off][1] = my; + } } uvmx = (mx + ((mx & 3) == 3)) >> 1; @@ -506,32 +382,34 @@ static void vc1_mc_1mv(VC1Context *v, int dir) uvmx = uvmx + ((uvmx < 0) ? (uvmx & 1) : -(uvmx & 1)); uvmy = uvmy + ((uvmy < 0) ? (uvmy & 1) : -(uvmy & 1)); } - if (v->field_mode) { // interlaced field picture - if (!dir) { - if ((v->cur_field_type != v->ref_field_type[dir]) && v->cur_field_type) { - srcY = s->current_picture.f.data[0]; - srcU = s->current_picture.f.data[1]; - srcV = s->current_picture.f.data[2]; - } else { - srcY = s->last_picture.f.data[0]; - srcU = s->last_picture.f.data[1]; - srcV = s->last_picture.f.data[2]; - } + if (!dir) { + if (v->field_mode && (v->cur_field_type != v->ref_field_type[dir]) && v->second_field) { + srcY = s->current_picture.f.data[0]; + srcU = s->current_picture.f.data[1]; + srcV = s->current_picture.f.data[2]; + luty = v->curr_luty; + lutuv = v->curr_lutuv; + use_ic = v->curr_use_ic; } else { - srcY = s->next_picture.f.data[0]; - srcU = s->next_picture.f.data[1]; - srcV = s->next_picture.f.data[2]; - } - } else { - if (!dir) { srcY = s->last_picture.f.data[0]; srcU = s->last_picture.f.data[1]; srcV = s->last_picture.f.data[2]; - } else { - srcY = s->next_picture.f.data[0]; - srcU = s->next_picture.f.data[1]; - srcV = s->next_picture.f.data[2]; + luty = v->last_luty; + lutuv = v->last_lutuv; + use_ic = v->last_use_ic; } + } else { + srcY = s->next_picture.f.data[0]; + srcU = s->next_picture.f.data[1]; + srcV = s->next_picture.f.data[2]; + luty = v->next_luty; + lutuv = v->next_lutuv; + use_ic = v->next_use_ic; + } + + if (!srcY || !srcU) { + av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n"); + return; } src_x = s->mb_x * 16 + (mx >> 2); @@ -567,21 +445,27 @@ static void vc1_mc_1mv(VC1Context *v, int dir) srcV = s->edge_emu_buffer + 18 * s->linesize; } - if (v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP) + if (v->rangeredfrm || use_ic + || s->h_edge_pos < 22 || v_edge_pos < 22 || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx&3) - 16 - s->mspel * 3 - || (unsigned)(src_y - s->mspel) > v_edge_pos - (my&3) - 16 - s->mspel * 3) { + || (unsigned)(src_y - 1) > v_edge_pos - (my&3) - 16 - 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, v_edge_pos); + s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcY, + s->linesize, s->linesize, + 17 + s->mspel * 2, 17 + s->mspel * 2, + 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, 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, v_edge_pos >> 1); + s->vdsp.emulated_edge_mc(uvbuf, srcU, + s->uvlinesize, s->uvlinesize, + 8 + 1, 8 + 1, + uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, v_edge_pos >> 1); + s->vdsp.emulated_edge_mc(uvbuf + 16, srcV, + s->uvlinesize, s->uvlinesize, + 8 + 1, 8 + 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 */ @@ -607,22 +491,24 @@ static void vc1_mc_1mv(VC1Context *v, int dir) } } /* if we deal with intensity compensation we need to scale source blocks */ - if (v->mv_mode == MV_PMODE_INTENSITY_COMP) { + if (use_ic) { int i, j; uint8_t *src, *src2; src = srcY; for (j = 0; j < 17 + s->mspel * 2; j++) { + int f = v->field_mode ? v->ref_field_type[dir] : ((j + src_y - s->mspel) & 1) ; for (i = 0; i < 17 + s->mspel * 2; i++) - src[i] = v->luty[src[i]]; + src[i] = luty[f][src[i]]; src += s->linesize; } src = srcU; src2 = srcV; for (j = 0; j < 9; j++) { + int f = v->field_mode ? v->ref_field_type[dir] : ((j + uvsrc_y) & 1); for (i = 0; i < 9; i++) { - src[i] = v->lutuv[src[i]]; - src2[i] = v->lutuv[src2[i]]; + src[i] = lutuv[f][src[i]]; + src2[i] = lutuv[f][src2[i]]; } src += s->uvlinesize; src2 += s->uvlinesize; @@ -631,26 +517,19 @@ 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] + off , srcY , s->linesize, v->rnd); - v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + off + 8, srcY + 8, s->linesize, v->rnd); + v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] , srcY , s->linesize, v->rnd); + v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + 8, srcY + 8, s->linesize, v->rnd); srcY += s->linesize * 8; - v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + off + 8 * s->linesize , srcY , s->linesize, v->rnd); - v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + off + 8 * s->linesize + 8, srcY + 8, s->linesize, v->rnd); + v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + 8 * s->linesize , srcY , s->linesize, v->rnd); + v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + 8 * s->linesize + 8, srcY + 8, s->linesize, v->rnd); } else { // hpel mc - always used for luma dxy = (my & 2) | ((mx & 2) >> 1); if (!v->rnd) - dsp->put_pixels_tab[0][dxy](s->dest[0] + off, srcY, s->linesize, 16); + s->hdsp.put_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16); else - dsp->put_no_rnd_pixels_tab[0][dxy](s->dest[0] + off, srcY, s->linesize, 16); + s->hdsp.put_no_rnd_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16); } if (s->flags & CODEC_FLAG_GRAY) return; @@ -658,11 +537,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] + 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); + h264chroma->put_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy); + h264chroma->put_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy); } else { - v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1] + off_uv, srcU, s->uvlinesize, 8, uvmx, uvmy); - v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2] + off_uv, srcV, s->uvlinesize, 8, uvmx, uvmy); + v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy); + v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy); } } @@ -679,32 +558,45 @@ 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) +static void vc1_mc_4mv_luma(VC1Context *v, int n, int dir, int avg) { 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 == ILACE_FRAME) ? v->blk_mv_type[s->block_index[n]] : 0; int v_edge_pos = s->v_edge_pos >> v->field_mode; + uint8_t (*luty)[256]; + int use_ic; - if (!v->field_mode && !v->s.last_picture.f.data[0]) + if ((!v->field_mode || + (v->ref_field_type[dir] == 1 && v->cur_field_type == 1)) && + !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 + if (v->field_mode && (v->cur_field_type != v->ref_field_type[dir]) && v->second_field) { + srcY = s->current_picture.f.data[0]; + luty = v->curr_luty; + use_ic = v->curr_use_ic; + } else { srcY = s->last_picture.f.data[0]; - } else + luty = v->last_luty; + use_ic = v->last_use_ic; + } + } else { srcY = s->next_picture.f.data[0]; + luty = v->next_luty; + use_ic = v->next_use_ic; + } + + if (!srcY) { + av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n"); + return; + } if (v->field_mode) { if (v->cur_field_type != v->ref_field_type[dir]) @@ -739,8 +631,8 @@ static void vc1_mc_4mv_luma(VC1Context *v, int n, int dir) 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; + s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = tx; + s->current_picture.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; } @@ -749,6 +641,10 @@ static void vc1_mc_4mv_luma(VC1Context *v, int n, int dir) int qx, qy; int width = s->avctx->coded_width; int height = s->avctx->coded_height >> 1; + if (s->pict_type == AV_PICTURE_TYPE_P) { + s->current_picture.motion_val[1][s->block_index[n] + v->blocks_off][0] = mx; + s->current_picture.motion_val[1][s->block_index[n] + v->blocks_off][1] = my; + } qx = (s->mb_x * 16) + (mx >> 2); qy = (s->mb_y * 8) + (my >> 3); @@ -766,8 +662,6 @@ static void vc1_mc_4mv_luma(VC1Context *v, int n, int dir) off = ((n > 1) ? s->linesize : 0) + (n & 1) * 8; else off = s->linesize * 4 * (n & 2) + (n & 1) * 8; - if (v->field_mode && v->cur_field_type) - off += s->current_picture_ptr->f.linesize[0]; src_x = s->mb_x * 16 + (n & 1) * 8 + (mx >> 2); if (!fieldmv) @@ -798,15 +692,17 @@ static void vc1_mc_4mv_luma(VC1Context *v, int n, int dir) v_edge_pos--; if (fieldmv && (src_y & 1) && src_y < 4) src_y--; - if (v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP) + if (v->rangeredfrm || use_ic + || s->h_edge_pos < 13 || v_edge_pos < 23 || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx & 3) - 8 - s->mspel * 2 || (unsigned)(src_y - (s->mspel << fieldmv)) > v_edge_pos - (my & 3) - ((8 + s->mspel * 2) << fieldmv)) { srcY -= s->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); + s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcY, + s->linesize, 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) { @@ -821,14 +717,15 @@ static void vc1_mc_4mv_luma(VC1Context *v, int n, int dir) } } /* if we deal with intensity compensation we need to scale source blocks */ - if (v->mv_mode == MV_PMODE_INTENSITY_COMP) { + if (use_ic) { int i, j; uint8_t *src; src = srcY; for (j = 0; j < 9 + s->mspel * 2; j++) { + int f = v->field_mode ? v->ref_field_type[dir] : (((j<mspel << fieldmv)) & 1); for (i = 0; i < 9 + s->mspel * 2; i++) - src[i] = v->luty[src[i]]; + src[i] = luty[f][src[i]]; src += s->linesize << fieldmv; } } @@ -837,13 +734,16 @@ static void vc1_mc_4mv_luma(VC1Context *v, int n, int dir) 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); + if (avg) + v->vc1dsp.avg_vc1_mspel_pixels_tab[dxy](s->dest[0] + off, srcY, s->linesize << fieldmv, v->rnd); + else + 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); + s->hdsp.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); + s->hdsp.put_no_rnd_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize, 8); } } @@ -905,14 +805,16 @@ static av_always_inline int get_chroma_mv(int *mvx, int *mvy, int *a, int flag, static void vc1_mc_4mv_chroma(VC1Context *v, int dir) { MpegEncContext *s = &v->s; - DSPContext *dsp = &v->s.dsp; + H264ChromaContext *h264chroma = &v->h264chroma; uint8_t *srcU, *srcV; int uvmx, uvmy, uvsrc_x, uvsrc_y; int k, tx = 0, ty = 0; int mvx[4], mvy[4], intra[4], mv_f[4]; int valid_count; - int chroma_ref_type = v->cur_field_type, off = 0; + int chroma_ref_type = v->cur_field_type; int v_edge_pos = s->v_edge_pos >> v->field_mode; + uint8_t (*lutuv)[256]; + int use_ic; if (!v->field_mode && !v->s.last_picture.f.data[0]) return; @@ -930,9 +832,10 @@ static void vc1_mc_4mv_chroma(VC1Context *v, int dir) /* calculate chroma MV vector from four luma MVs */ if (!v->field_mode || (v->field_mode && !v->numref)) { valid_count = get_chroma_mv(mvx, mvy, intra, 0, &tx, &ty); + chroma_ref_type = v->reffield; if (!valid_count) { - 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.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0; + s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0; v->luma_mv[s->mb_x][0] = v->luma_mv[s->mb_x][1] = 0; return; //no need to do MC for intra blocks } @@ -944,8 +847,10 @@ static void vc1_mc_4mv_chroma(VC1Context *v, int dir) if (dominant) chroma_ref_type = !v->cur_field_type; } - 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; + if (v->field_mode && chroma_ref_type == 1 && v->cur_field_type == 1 && !v->s.last_picture.f.data[0]) + return; + s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = tx; + s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = ty; uvmx = (tx + ((tx & 3) == 3)) >> 1; uvmy = (ty + ((ty & 3) == 3)) >> 1; @@ -972,40 +877,51 @@ static void vc1_mc_4mv_chroma(VC1Context *v, int dir) } if (!dir) { - if (v->field_mode) { - if ((v->cur_field_type != chroma_ref_type) && v->cur_field_type) { - srcU = s->current_picture.f.data[1] + uvsrc_y * s->uvlinesize + uvsrc_x; - srcV = s->current_picture.f.data[2] + uvsrc_y * s->uvlinesize + uvsrc_x; - } 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; - } + if (v->field_mode && (v->cur_field_type != chroma_ref_type) && v->second_field) { + srcU = s->current_picture.f.data[1]; + srcV = s->current_picture.f.data[2]; + lutuv = v->curr_lutuv; + use_ic = v->curr_use_ic; } else { - srcU = s->last_picture.f.data[1] + uvsrc_y * s->uvlinesize + uvsrc_x; - srcV = s->last_picture.f.data[2] + uvsrc_y * s->uvlinesize + uvsrc_x; + srcU = s->last_picture.f.data[1]; + srcV = s->last_picture.f.data[2]; + lutuv = v->last_lutuv; + use_ic = v->last_use_ic; } } else { - srcU = s->next_picture.f.data[1] + uvsrc_y * s->uvlinesize + uvsrc_x; - srcV = s->next_picture.f.data[2] + uvsrc_y * s->uvlinesize + uvsrc_x; + srcU = s->next_picture.f.data[1]; + srcV = s->next_picture.f.data[2]; + lutuv = v->next_lutuv; + use_ic = v->next_use_ic; + } + + if (!srcU) { + av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n"); + return; } + srcU += uvsrc_y * s->uvlinesize + uvsrc_x; + srcV += uvsrc_y * s->uvlinesize + uvsrc_x; + if (v->field_mode) { if (chroma_ref_type) { srcU += s->current_picture_ptr->f.linesize[1]; 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) + if (v->rangeredfrm || use_ic + || s->h_edge_pos < 18 || v_edge_pos < 18 || (unsigned)uvsrc_x > (s->h_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, 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, v_edge_pos >> 1); + s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcU, + s->uvlinesize, s->uvlinesize, + 8 + 1, 8 + 1, uvsrc_x, uvsrc_y, + s->h_edge_pos >> 1, v_edge_pos >> 1); + s->vdsp.emulated_edge_mc(s->edge_emu_buffer + 16, srcV, + s->uvlinesize, s->uvlinesize, + 8 + 1, 8 + 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; @@ -1026,16 +942,17 @@ static void vc1_mc_4mv_chroma(VC1Context *v, int dir) } } /* if we deal with intensity compensation we need to scale source blocks */ - if (v->mv_mode == MV_PMODE_INTENSITY_COMP) { + if (use_ic) { int i, j; uint8_t *src, *src2; src = srcU; src2 = srcV; for (j = 0; j < 9; j++) { + int f = v->field_mode ? chroma_ref_type : ((j + uvsrc_y) & 1); for (i = 0; i < 9; i++) { - src[i] = v->lutuv[src[i]]; - src2[i] = v->lutuv[src2[i]]; + src[i] = lutuv[f][src[i]]; + src2[i] = lutuv[f][src2[i]]; } src += s->uvlinesize; src2 += s->uvlinesize; @@ -1047,20 +964,20 @@ static void vc1_mc_4mv_chroma(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] + off, srcU, s->uvlinesize, 8, uvmx, uvmy); - dsp->put_h264_chroma_pixels_tab[0](s->dest[2] + off, srcV, s->uvlinesize, 8, uvmx, uvmy); + h264chroma->put_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy); + h264chroma->put_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy); } else { - v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1] + off, srcU, s->uvlinesize, 8, uvmx, uvmy); - v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2] + off, srcV, s->uvlinesize, 8, uvmx, uvmy); + v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy); + v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy); } } -/** Do motion compensation for 4-MV field chroma macroblock (both U and V) +/** Do motion compensation for 4-MV interlaced frame chroma macroblock (both U and V) */ -static void vc1_mc_4mv_chroma4(VC1Context *v) +static void vc1_mc_4mv_chroma4(VC1Context *v, int dir, int dir2, int avg) { MpegEncContext *s = &v->s; - DSPContext *dsp = &v->s.dsp; + H264ChromaContext *h264chroma = &v->h264chroma; uint8_t *srcU, *srcV; int uvsrc_x, uvsrc_y; int uvmx_field[4], uvmy_field[4]; @@ -1069,16 +986,17 @@ static void vc1_mc_4mv_chroma4(VC1Context *v) 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; + int use_ic; + uint8_t (*lutuv)[256]; - 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]; + int d = i < 2 ? dir: dir2; + tx = s->mv[d][i][0]; uvmx_field[i] = (tx + ((tx & 3) == 3)) >> 1; - ty = s->mv[0][i][1]; + ty = s->mv[d][i][1]; if (fieldmv) uvmy_field[i] = (ty >> 4) * 8 + s_rndtblfield[ty & 0xF]; else @@ -1092,8 +1010,17 @@ static void vc1_mc_4mv_chroma4(VC1Context *v) // 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; + if (i < 2 ? dir : dir2) { + 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; + lutuv = v->next_lutuv; + use_ic = v->next_use_ic; + } 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; + lutuv = v->last_lutuv; + use_ic = v->last_use_ic; + } uvmx_field[i] = (uvmx_field[i] & 3) << 1; uvmy_field[i] = (uvmy_field[i] & 3) << 1; @@ -1101,41 +1028,55 @@ static void vc1_mc_4mv_chroma4(VC1Context *v) v_edge_pos--; if (fieldmv && (uvsrc_y & 1) && uvsrc_y < 2) uvsrc_y--; - if ((v->mv_mode == MV_PMODE_INTENSITY_COMP) + if (use_ic + || s->h_edge_pos < 10 || v_edge_pos < (5 << fieldmv) || (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); + s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcU, + s->uvlinesize, s->uvlinesize, + 5, (5 << fieldmv), uvsrc_x, uvsrc_y, + s->h_edge_pos >> 1, v_edge_pos); + s->vdsp.emulated_edge_mc(s->edge_emu_buffer + 16, srcV, + s->uvlinesize, 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) { + if (use_ic) { int i, j; uint8_t *src, *src2; src = srcU; src2 = srcV; for (j = 0; j < 5; j++) { + int f = (uvsrc_y + (j << fieldmv)) & 1; for (i = 0; i < 5; i++) { - src[i] = v->lutuv[src[i]]; - src2[i] = v->lutuv[src2[i]]; + src[i] = lutuv[f][src[i]]; + src2[i] = lutuv[f][src2[i]]; } - src += s->uvlinesize << 1; - src2 += s->uvlinesize << 1; + src += s->uvlinesize << fieldmv; + src2 += s->uvlinesize << fieldmv; } } } - 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]); + if (avg) { + if (!v->rnd) { + h264chroma->avg_h264_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]); + h264chroma->avg_h264_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]); + } else { + v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]); + v->vc1dsp.avg_no_rnd_vc1_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]); + if (!v->rnd) { + h264chroma->put_h264_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]); + h264chroma->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]); + } } } } @@ -1179,6 +1120,11 @@ static void vc1_mc_4mv_chroma4(VC1Context *v) mquant = v->altpq; \ if ((edges&8) && s->mb_y == (s->mb_height - 1)) \ mquant = v->altpq; \ + if (!mquant || mquant > 31) { \ + av_log(v->s.avctx, AV_LOG_ERROR, \ + "Overriding invalid mquant %d\n", mquant); \ + mquant = 1; \ + } \ } /** @@ -1259,8 +1205,12 @@ static av_always_inline void get_mvdata_interlaced(VC1Context *v, int *dmv_x, *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; + if (pred_flag) { + *pred_flag = *dmv_y & 1; + *dmv_y = (*dmv_y + *pred_flag) >> 1; + } else { + *dmv_y = (*dmv_y + (*dmv_y & 1)) >> 1; + } } } else { @@ -1286,7 +1236,7 @@ static av_always_inline void get_mvdata_interlaced(VC1Context *v, int *dmv_x, *dmv_y = (sign ^ ((val >> 1) + offs_tab[index1 >> v->numref])) - sign; } else *dmv_y = 0; - if (v->numref) + if (v->numref && pred_flag) *pred_flag = index1 & 1; } } @@ -1304,10 +1254,10 @@ static av_always_inline int scaleforsame_x(VC1Context *v, int n /* MV */, int di refdist = dir ? v->brfd : v->frfd; if (refdist > 3) refdist = 3; - scalesame1 = vc1_field_mvpred_scales[table_index][1][refdist]; - scalesame2 = vc1_field_mvpred_scales[table_index][2][refdist]; - scalezone1_x = vc1_field_mvpred_scales[table_index][3][refdist]; - zone1offset_x = vc1_field_mvpred_scales[table_index][5][refdist]; + scalesame1 = ff_vc1_field_mvpred_scales[table_index][1][refdist]; + scalesame2 = ff_vc1_field_mvpred_scales[table_index][2][refdist]; + scalezone1_x = ff_vc1_field_mvpred_scales[table_index][3][refdist]; + zone1offset_x = ff_vc1_field_mvpred_scales[table_index][5][refdist]; if (FFABS(n) > 255) scaledvalue = n; @@ -1337,10 +1287,10 @@ static av_always_inline int scaleforsame_y(VC1Context *v, int i, int n /* MV */, refdist = dir ? v->brfd : v->frfd; if (refdist > 3) refdist = 3; - scalesame1 = vc1_field_mvpred_scales[table_index][1][refdist]; - scalesame2 = vc1_field_mvpred_scales[table_index][2][refdist]; - scalezone1_y = vc1_field_mvpred_scales[table_index][4][refdist]; - zone1offset_y = vc1_field_mvpred_scales[table_index][6][refdist]; + scalesame1 = ff_vc1_field_mvpred_scales[table_index][1][refdist]; + scalesame2 = ff_vc1_field_mvpred_scales[table_index][2][refdist]; + scalezone1_y = ff_vc1_field_mvpred_scales[table_index][4][refdist]; + zone1offset_y = ff_vc1_field_mvpred_scales[table_index][6][refdist]; if (FFABS(n) > 63) scaledvalue = n; @@ -1368,10 +1318,10 @@ static av_always_inline int scaleforopp_x(VC1Context *v, int n /* MV */) 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]; + scalezone1_x = ff_vc1_b_field_mvpred_scales[3][brfd]; + zone1offset_x = ff_vc1_b_field_mvpred_scales[5][brfd]; + scaleopp1 = ff_vc1_b_field_mvpred_scales[1][brfd]; + scaleopp2 = ff_vc1_b_field_mvpred_scales[2][brfd]; if (FFABS(n) > 255) scaledvalue = n; @@ -1395,10 +1345,10 @@ static av_always_inline int scaleforopp_y(VC1Context *v, int n /* MV */, int dir 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]; + scalezone1_y = ff_vc1_b_field_mvpred_scales[4][brfd]; + zone1offset_y = ff_vc1_b_field_mvpred_scales[6][brfd]; + scaleopp1 = ff_vc1_b_field_mvpred_scales[1][brfd]; + scaleopp2 = ff_vc1_b_field_mvpred_scales[2][brfd]; if (FFABS(n) > 63) scaledvalue = n; @@ -1434,7 +1384,7 @@ static av_always_inline int scaleforsame(VC1Context *v, int i, int n /* MV */, return n; } brfd = FFMIN(v->brfd, 3); - scalesame = vc1_b_field_mvpred_scales[0][brfd]; + scalesame = ff_vc1_b_field_mvpred_scales[0][brfd]; n = (n * scalesame >> 8) << hpel; return n; @@ -1458,7 +1408,7 @@ static av_always_inline int scaleforopp(VC1Context *v, int n /* MV */, refdist = FFMIN(v->refdist, 3); else refdist = dir ? v->brfd : v->frfd; - scaleopp = vc1_field_mvpred_scales[dir ^ v->second_field][0][refdist]; + scaleopp = ff_vc1_field_mvpred_scales[dir ^ v->second_field][0][refdist]; n = (n * scaleopp >> 8) << hpel; return n; @@ -1476,7 +1426,7 @@ static inline void vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y, int px, py; int sum; int mixedmv_pic, num_samefield = 0, num_oppfield = 0; - int opposit, a_f, b_f, c_f; + int opposite, a_f, b_f, c_f; int16_t field_predA[2]; int16_t field_predB[2]; int16_t field_predC[2]; @@ -1496,30 +1446,30 @@ static inline void vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y, xy = s->block_index[n]; if (s->mb_intra) { - 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; + s->mv[0][n][0] = s->current_picture.motion_val[0][xy + v->blocks_off][0] = 0; + s->mv[0][n][1] = s->current_picture.motion_val[0][xy + v->blocks_off][1] = 0; + s->current_picture.motion_val[1][xy + v->blocks_off][0] = 0; + s->current_picture.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 + 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; + s->current_picture.motion_val[0][xy + 1 + v->blocks_off][0] = 0; + s->current_picture.motion_val[0][xy + 1 + v->blocks_off][1] = 0; + s->current_picture.motion_val[0][xy + wrap + v->blocks_off][0] = 0; + s->current_picture.motion_val[0][xy + wrap + v->blocks_off][1] = 0; + s->current_picture.motion_val[0][xy + wrap + 1 + v->blocks_off][0] = 0; + s->current_picture.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 + 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; + s->current_picture.motion_val[1][xy + 1 + v->blocks_off][0] = 0; + s->current_picture.motion_val[1][xy + 1 + v->blocks_off][1] = 0; + s->current_picture.motion_val[1][xy + wrap][0] = 0; + s->current_picture.motion_val[1][xy + wrap + v->blocks_off][1] = 0; + s->current_picture.motion_val[1][xy + wrap + 1 + v->blocks_off][0] = 0; + s->current_picture.motion_val[1][xy + wrap + 1 + v->blocks_off][1] = 0; } return; } - 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]; + C = s->current_picture.motion_val[dir][xy - 1 + v->blocks_off]; + A = s->current_picture.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; @@ -1541,7 +1491,7 @@ static inline void vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y, off = -1; } } - B = s->current_picture.f.motion_val[dir][xy - wrap + off + v->blocks_off]; + B = s->current_picture.motion_val[dir][xy - wrap + off + v->blocks_off]; a_valid = !s->first_slice_line || (n == 2 || n == 3); b_valid = a_valid && (s->mb_width > 1); @@ -1584,13 +1534,19 @@ static inline void vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y, } if (v->field_mode) { - if (num_samefield <= num_oppfield) - opposit = 1 - pred_flag; - else - opposit = pred_flag; + if (!v->numref) + // REFFIELD determines if the last field or the second-last field is + // to be used as reference + opposite = 1 - v->reffield; + else { + if (num_samefield <= num_oppfield) + opposite = 1 - pred_flag; + else + opposite = pred_flag; + } } else - opposit = 0; - if (opposit) { + opposite = 0; + if (opposite) { if (a_valid && !a_f) { field_predA[0] = scaleforopp(v, field_predA[0], 0, dir); field_predA[1] = scaleforopp(v, field_predA[1], 1, dir); @@ -1693,24 +1649,20 @@ static inline void vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y, } } - 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; + s->mv[dir][n][0] = s->current_picture.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.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]; + s->current_picture.motion_val[dir][xy + 1 + v->blocks_off][0] = s->current_picture.motion_val[dir][xy + v->blocks_off][0]; + s->current_picture.motion_val[dir][xy + 1 + v->blocks_off][1] = s->current_picture.motion_val[dir][xy + v->blocks_off][1]; + s->current_picture.motion_val[dir][xy + wrap + v->blocks_off][0] = s->current_picture.motion_val[dir][xy + v->blocks_off][0]; + s->current_picture.motion_val[dir][xy + wrap + v->blocks_off][1] = s->current_picture.motion_val[dir][xy + v->blocks_off][1]; + s->current_picture.motion_val[dir][xy + wrap + 1 + v->blocks_off][0] = s->current_picture.motion_val[dir][xy + v->blocks_off][0]; + s->current_picture.motion_val[dir][xy + wrap + 1 + v->blocks_off][1] = s->current_picture.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]; } @@ -1719,7 +1671,7 @@ static inline void vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y, /** 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) + int mvn, int r_x, int r_y, uint8_t* is_intra, int dir) { MpegEncContext *s = &v->s; int xy, wrap, off = 0; @@ -1734,24 +1686,24 @@ static inline void vc1_pred_mv_intfr(VC1Context *v, int n, int dmv_x, int dmv_y, 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.motion_val[0][xy][0] = 0; + s->mv[0][n][1] = s->current_picture.motion_val[0][xy][1] = 0; + s->current_picture.motion_val[1][xy][0] = 0; + s->current_picture.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; + s->current_picture.motion_val[0][xy + 1][0] = 0; + s->current_picture.motion_val[0][xy + 1][1] = 0; + s->current_picture.motion_val[0][xy + wrap][0] = 0; + s->current_picture.motion_val[0][xy + wrap][1] = 0; + s->current_picture.motion_val[0][xy + wrap + 1][0] = 0; + s->current_picture.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; + s->current_picture.motion_val[1][xy + 1][0] = 0; + s->current_picture.motion_val[1][xy + 1][1] = 0; + s->current_picture.motion_val[1][xy + wrap][0] = 0; + s->current_picture.motion_val[1][xy + wrap][1] = 0; + s->current_picture.motion_val[1][xy + wrap + 1][0] = 0; + s->current_picture.motion_val[1][xy + wrap + 1][1] = 0; } return; } @@ -1761,14 +1713,14 @@ static inline void vc1_pred_mv_intfr(VC1Context *v, int n, int dmv_x, int dmv_y, 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[0] = s->current_picture.motion_val[dir][xy - 1][0]; + A[1] = s->current_picture.motion_val[dir][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[0] = (s->current_picture.motion_val[dir][xy - 1][0] + + s->current_picture.motion_val[dir][xy - 1 + off * wrap][0] + 1) >> 1; + A[1] = (s->current_picture.motion_val[dir][xy - 1][1] + + s->current_picture.motion_val[dir][xy - 1 + off * wrap][1] + 1) >> 1; a_valid = 1; } if (!(n & 1) && v->is_intra[s->mb_x - 1]) { @@ -1788,11 +1740,11 @@ static inline void vc1_pred_mv_intfr(VC1Context *v, int n, int dmv_x, int dmv_y, 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]; + B[0] = s->current_picture.motion_val[dir][s->block_index[n_adj] - 2 * wrap][0]; + B[1] = s->current_picture.motion_val[dir][s->block_index[n_adj] - 2 * wrap][1]; if (v->blk_mv_type[pos_b] && !v->blk_mv_type[xy]) { - B[0] = (B[0] + s->current_picture.f.motion_val[0][s->block_index[n_adj ^ 2] - 2 * wrap][0] + 1) >> 1; - B[1] = (B[1] + s->current_picture.f.motion_val[0][s->block_index[n_adj ^ 2] - 2 * wrap][1] + 1) >> 1; + B[0] = (B[0] + s->current_picture.motion_val[dir][s->block_index[n_adj ^ 2] - 2 * wrap][0] + 1) >> 1; + B[1] = (B[1] + s->current_picture.motion_val[dir][s->block_index[n_adj ^ 2] - 2 * wrap][1] + 1) >> 1; } } if (s->mb_width > 1) { @@ -1803,11 +1755,11 @@ static inline void vc1_pred_mv_intfr(VC1Context *v, int n, int dmv_x, int dmv_y, 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]; + C[0] = s->current_picture.motion_val[dir][s->block_index[n_adj] - 2 * wrap + 2][0]; + C[1] = s->current_picture.motion_val[dir][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; + C[0] = (1 + C[0] + (s->current_picture.motion_val[dir][s->block_index[n_adj ^ 2] - 2 * wrap + 2][0])) >> 1; + C[1] = (1 + C[1] + (s->current_picture.motion_val[dir][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]) { @@ -1817,11 +1769,11 @@ static inline void vc1_pred_mv_intfr(VC1Context *v, int n, int dmv_x, int dmv_y, 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]; + C[0] = s->current_picture.motion_val[dir][s->block_index[n_adj] - 2 * wrap - 2][0]; + C[1] = s->current_picture.motion_val[dir][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; + C[0] = (1 + C[0] + s->current_picture.motion_val[dir][s->block_index[1] - 2 * wrap - 2][0]) >> 1; + C[1] = (1 + C[1] + s->current_picture.motion_val[dir][s->block_index[1] - 2 * wrap - 2][1]) >> 1; } } else c_valid = 0; @@ -1832,12 +1784,12 @@ static inline void vc1_pred_mv_intfr(VC1Context *v, int n, int dmv_x, int dmv_y, } 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]; + B[0] = s->current_picture.motion_val[dir][pos_b][0]; + B[1] = s->current_picture.motion_val[dir][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]; + C[0] = s->current_picture.motion_val[dir][pos_c][0]; + C[1] = s->current_picture.motion_val[dir][pos_c][1]; } total_valid = a_valid + b_valid + c_valid; @@ -1925,20 +1877,20 @@ static inline void vc1_pred_mv_intfr(VC1Context *v, int n, int dmv_x, int dmv_y, } /* 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; + s->mv[dir][n][0] = s->current_picture.motion_val[dir][xy][0] = ((px + dmv_x + r_x) & ((r_x << 1) - 1)) - r_x; + s->mv[dir][n][1] = s->current_picture.motion_val[dir][xy][1] = ((py + dmv_y + r_y) & ((r_y << 1) - 1)) - r_y; 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]; + s->current_picture.motion_val[dir][xy + 1 ][0] = s->current_picture.motion_val[dir][xy][0]; + s->current_picture.motion_val[dir][xy + 1 ][1] = s->current_picture.motion_val[dir][xy][1]; + s->current_picture.motion_val[dir][xy + wrap ][0] = s->current_picture.motion_val[dir][xy][0]; + s->current_picture.motion_val[dir][xy + wrap ][1] = s->current_picture.motion_val[dir][xy][1]; + s->current_picture.motion_val[dir][xy + wrap + 1][0] = s->current_picture.motion_val[dir][xy][0]; + s->current_picture.motion_val[dir][xy + wrap + 1][1] = s->current_picture.motion_val[dir][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]; + s->current_picture.motion_val[dir][xy + 1][0] = s->current_picture.motion_val[dir][xy][0]; + s->current_picture.motion_val[dir][xy + 1][1] = s->current_picture.motion_val[dir][xy][1]; + s->mv[dir][n + 1][0] = s->mv[dir][n][0]; + s->mv[dir][n + 1][1] = s->mv[dir][n][1]; } } @@ -1947,11 +1899,12 @@ static inline void vc1_pred_mv_intfr(VC1Context *v, int n, int dmv_x, int dmv_y, static void vc1_interp_mc(VC1Context *v) { MpegEncContext *s = &v->s; - DSPContext *dsp = &v->s.dsp; + H264ChromaContext *h264chroma = &v->h264chroma; uint8_t *srcY, *srcU, *srcV; int dxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y; int off, off_uv; int v_edge_pos = s->v_edge_pos >> v->field_mode; + int use_ic = v->next_use_ic; if (!v->field_mode && !v->s.next_picture.f.data[0]) return; @@ -2006,21 +1959,26 @@ static void vc1_interp_mc(VC1Context *v) srcV = s->edge_emu_buffer + 18 * s->linesize; } - if (v->rangeredfrm - || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx & 3) - 16 - s->mspel * 3 - || (unsigned)(src_y - s->mspel) > v_edge_pos - (my & 3) - 16 - s->mspel * 3) { + if (v->rangeredfrm || s->h_edge_pos < 22 || v_edge_pos < 22 || use_ic + || (unsigned)(src_x - 1) > s->h_edge_pos - (mx & 3) - 16 - 3 + || (unsigned)(src_y - 1) > v_edge_pos - (my & 3) - 16 - 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, v_edge_pos); + s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcY, + s->linesize, s->linesize, + 17 + s->mspel * 2, 17 + s->mspel * 2, + 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, 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, v_edge_pos >> 1); + s->vdsp.emulated_edge_mc(uvbuf, srcU, + s->uvlinesize, s->uvlinesize, + 8 + 1, 8 + 1, + uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, v_edge_pos >> 1); + s->vdsp.emulated_edge_mc(uvbuf + 16, srcV, + s->uvlinesize, s->uvlinesize, + 8 + 1, 8 + 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 */ @@ -2045,16 +2003,37 @@ static void vc1_interp_mc(VC1Context *v) src2 += s->uvlinesize; } } + + if (use_ic) { + uint8_t (*luty )[256] = v->next_luty; + uint8_t (*lutuv)[256] = v->next_lutuv; + int i, j; + uint8_t *src, *src2; + + src = srcY; + for (j = 0; j < 17 + s->mspel * 2; j++) { + int f = v->field_mode ? v->ref_field_type[1] : ((j+src_y - s->mspel) & 1); + for (i = 0; i < 17 + s->mspel * 2; i++) + src[i] = luty[f][src[i]]; + src += s->linesize; + } + src = srcU; + src2 = srcV; + for (j = 0; j < 9; j++) { + int f = v->field_mode ? v->ref_field_type[1] : ((j+uvsrc_y) & 1); + for (i = 0; i < 9; i++) { + src[i] = lutuv[f][src[i]]; + src2[i] = lutuv[f][src2[i]]; + } + src += s->uvlinesize; + src2 += s->uvlinesize; + } + } srcY += s->mspel * (1 + s->linesize); } - if (v->field_mode && v->cur_field_type) { - off = s->current_picture_ptr->f.linesize[0]; - off_uv = s->current_picture_ptr->f.linesize[1]; - } else { - off = 0; - off_uv = 0; - } + off = 0; + off_uv = 0; if (s->mspel) { dxy = ((my & 3) << 2) | (mx & 3); @@ -2067,9 +2046,9 @@ static void vc1_interp_mc(VC1Context *v) dxy = (my & 2) | ((mx & 2) >> 1); if (!v->rnd) - dsp->avg_pixels_tab[0][dxy](s->dest[0] + off, srcY, s->linesize, 16); + s->hdsp.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] + off, srcY, s->linesize, 16); + s->hdsp.avg_no_rnd_pixels_tab[dxy](s->dest[0] + off, srcY, s->linesize, 16); } if (s->flags & CODEC_FLAG_GRAY) return; @@ -2077,8 +2056,8 @@ 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] + 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); + h264chroma->avg_h264_chroma_pixels_tab[0](s->dest[1] + off_uv, srcU, s->uvlinesize, 8, uvmx, uvmy); + h264chroma->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] + 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); @@ -2104,49 +2083,23 @@ 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) { - if (v->use_ic) { - v->mv_mode2 = v->mv_mode; - v->mv_mode = MV_PMODE_INTENSITY_COMP; - } if (direct) { vc1_mc_1mv(v, 0); vc1_interp_mc(v); - if (v->use_ic) - v->mv_mode = v->mv_mode2; return; } if (mode == BMV_TYPE_INTERPOLATED) { vc1_mc_1mv(v, 0); vc1_interp_mc(v); - if (v->use_ic) - v->mv_mode = v->mv_mode2; return; } - if (v->use_ic && (mode == BMV_TYPE_BACKWARD)) - v->mv_mode = v->mv_mode2; vc1_mc_1mv(v, (mode == BMV_TYPE_BACKWARD)); - if (v->use_ic) - v->mv_mode = v->mv_mode2; } static inline void vc1_pred_b_mv(VC1Context *v, int dmv_x[2], int dmv_y[2], @@ -2172,17 +2125,17 @@ static inline void vc1_pred_b_mv(VC1Context *v, int dmv_x[2], int dmv_y[2], xy = s->block_index[0]; if (s->mb_intra) { - 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; + s->current_picture.motion_val[0][xy + v->blocks_off][0] = + s->current_picture.motion_val[0][xy + v->blocks_off][1] = + s->current_picture.motion_val[1][xy + v->blocks_off][0] = + s->current_picture.motion_val[1][xy + v->blocks_off][1] = 0; return; } 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); + s->mv[0][0][0] = scale_mv(s->next_picture.motion_val[1][xy][0], v->bfraction, 0, s->quarter_sample); + s->mv[0][0][1] = scale_mv(s->next_picture.motion_val[1][xy][1], v->bfraction, 0, s->quarter_sample); + s->mv[1][0][0] = scale_mv(s->next_picture.motion_val[1][xy][0], v->bfraction, 1, s->quarter_sample); + s->mv[1][0][1] = scale_mv(s->next_picture.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)); @@ -2191,18 +2144,18 @@ static inline void vc1_pred_b_mv(VC1Context *v, int dmv_x[2], int dmv_y[2], 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 + 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]; + s->current_picture.motion_val[0][xy + v->blocks_off][0] = s->mv[0][0][0]; + s->current_picture.motion_val[0][xy + v->blocks_off][1] = s->mv[0][0][1]; + s->current_picture.motion_val[1][xy + v->blocks_off][0] = s->mv[1][0][0]; + s->current_picture.motion_val[1][xy + v->blocks_off][1] = s->mv[1][0][1]; return; } if ((mvtype == BMV_TYPE_FORWARD) || (mvtype == BMV_TYPE_INTERPOLATED)) { - C = s->current_picture.f.motion_val[0][xy - 2]; - A = s->current_picture.f.motion_val[0][xy - wrap * 2]; + C = s->current_picture.motion_val[0][xy - 2]; + A = s->current_picture.motion_val[0][xy - wrap * 2]; off = (s->mb_x == (s->mb_width - 1)) ? -2 : 2; - B = s->current_picture.f.motion_val[0][xy - wrap * 2 + off]; + B = s->current_picture.motion_val[0][xy - wrap * 2 + off]; if (!s->mb_x) C[0] = C[1] = 0; if (!s->first_slice_line) { // predictor A is not out of bounds @@ -2277,10 +2230,10 @@ static inline void vc1_pred_b_mv(VC1Context *v, int dmv_x[2], int dmv_y[2], s->mv[0][0][1] = ((py + dmv_y[0] + r_y) & ((r_y << 1) - 1)) - r_y; } if ((mvtype == BMV_TYPE_BACKWARD) || (mvtype == BMV_TYPE_INTERPOLATED)) { - C = s->current_picture.f.motion_val[1][xy - 2]; - A = s->current_picture.f.motion_val[1][xy - wrap * 2]; + C = s->current_picture.motion_val[1][xy - 2]; + A = s->current_picture.motion_val[1][xy - wrap * 2]; off = (s->mb_x == (s->mb_width - 1)) ? -2 : 2; - B = s->current_picture.f.motion_val[1][xy - wrap * 2 + off]; + B = s->current_picture.motion_val[1][xy - wrap * 2 + off]; if (!s->mb_x) C[0] = C[1] = 0; @@ -2356,10 +2309,10 @@ static inline void vc1_pred_b_mv(VC1Context *v, int dmv_x[2], int dmv_y[2], s->mv[1][0][0] = ((px + dmv_x[1] + r_x) & ((r_x << 1) - 1)) - r_x; s->mv[1][0][1] = ((py + dmv_y[1] + r_y) & ((r_y << 1) - 1)) - r_y; } - 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.motion_val[0][xy][0] = s->mv[0][0][0]; + s->current_picture.motion_val[0][xy][1] = s->mv[0][0][1]; + s->current_picture.motion_val[1][xy][0] = s->mv[1][0][0]; + s->current_picture.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) @@ -2370,15 +2323,15 @@ static inline void vc1_pred_b_mv_intfi(VC1Context *v, int n, int *dmv_x, int *dm 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); + if (s->next_picture.mb_type[mb_pos + v->mb_off] != MB_TYPE_INTRA) { + s->mv[0][0][0] = scale_mv(s->next_picture.motion_val[1][s->block_index[0] + v->blocks_off][0], + v->bfraction, 0, s->quarter_sample); + s->mv[0][0][1] = scale_mv(s->next_picture.motion_val[1][s->block_index[0] + v->blocks_off][1], + v->bfraction, 0, s->quarter_sample); + s->mv[1][0][0] = scale_mv(s->next_picture.motion_val[1][s->block_index[0] + v->blocks_off][0], + v->bfraction, 1, s->quarter_sample); + s->mv[1][0][1] = scale_mv(s->next_picture.motion_val[1][s->block_index[0] + v->blocks_off][1], + v->bfraction, 1, s->quarter_sample); 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] @@ -2392,10 +2345,10 @@ static inline void vc1_pred_b_mv_intfi(VC1Context *v, int n, int *dmv_x, int *dm } 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]; + s->current_picture.motion_val[0][s->block_index[k] + v->blocks_off][0] = s->mv[0][0][0]; + s->current_picture.motion_val[0][s->block_index[k] + v->blocks_off][1] = s->mv[0][0][1]; + s->current_picture.motion_val[1][s->block_index[k] + v->blocks_off][0] = s->mv[1][0][0]; + s->current_picture.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; } @@ -2501,6 +2454,7 @@ static inline int vc1_pred_dc(MpegEncContext *s, int overlap, int pq, int n, int16_t *dc_val; int mb_pos = s->mb_x + s->mb_y * s->mb_stride; int q1, q2 = 0; + int dqscale_index; wrap = s->block_wrap[n]; dc_val = s->dc_val[0] + s->block_index[n]; @@ -2512,16 +2466,19 @@ static inline int vc1_pred_dc(MpegEncContext *s, int overlap, int pq, int n, b = dc_val[ - 1 - wrap]; a = dc_val[ - wrap]; /* scale predictors if needed */ - q1 = s->current_picture.f.qscale_table[mb_pos]; + q1 = s->current_picture.qscale_table[mb_pos]; + dqscale_index = s->y_dc_scale_table[q1] - 1; + if (dqscale_index < 0) + return 0; if (c_avail && (n != 1 && n != 3)) { - q2 = s->current_picture.f.qscale_table[mb_pos - 1]; + q2 = s->current_picture.qscale_table[mb_pos - 1]; if (q2 && q2 != q1) - c = (c * s->y_dc_scale_table[q2] * ff_vc1_dqscale[s->y_dc_scale_table[q1] - 1] + 0x20000) >> 18; + c = (c * s->y_dc_scale_table[q2] * ff_vc1_dqscale[dqscale_index] + 0x20000) >> 18; } if (a_avail && (n != 2 && n != 3)) { - q2 = s->current_picture.f.qscale_table[mb_pos - s->mb_stride]; + q2 = s->current_picture.qscale_table[mb_pos - s->mb_stride]; if (q2 && q2 != q1) - a = (a * s->y_dc_scale_table[q2] * ff_vc1_dqscale[s->y_dc_scale_table[q1] - 1] + 0x20000) >> 18; + a = (a * s->y_dc_scale_table[q2] * ff_vc1_dqscale[dqscale_index] + 0x20000) >> 18; } if (a_avail && c_avail && (n != 3)) { int off = mb_pos; @@ -2529,9 +2486,9 @@ static inline int vc1_pred_dc(MpegEncContext *s, int overlap, int pq, int n, off--; if (n != 2) off -= s->mb_stride; - q2 = s->current_picture.f.qscale_table[off]; + q2 = s->current_picture.qscale_table[off]; if (q2 && q2 != q1) - b = (b * s->y_dc_scale_table[q2] * ff_vc1_dqscale[s->y_dc_scale_table[q1] - 1] + 0x20000) >> 18; + b = (b * s->y_dc_scale_table[q2] * ff_vc1_dqscale[dqscale_index] + 0x20000) >> 18; } if (a_avail && c_avail) { @@ -2609,7 +2566,7 @@ static void vc1_decode_ac_coeff(VC1Context *v, int *last, int *skip, int index, escape, run = 0, level = 0, lst = 0; index = get_vlc2(gb, ff_vc1_ac_coeff_table[codingset].table, AC_VLC_BITS, 3); - if (index != vc1_ac_sizes[codingset] - 1) { + if (index != ff_vc1_ac_sizes[codingset] - 1) { run = vc1_index_decode_table[codingset][index][0]; level = vc1_index_decode_table[codingset][index][1]; lst = index >= vc1_last_decode_table[codingset] || get_bits_left(gb) < 0; @@ -2668,7 +2625,7 @@ static void vc1_decode_ac_coeff(VC1Context *v, int *last, int *skip, * @param coded are AC coeffs present or not * @param codingset set of VLC to decode data */ -static int vc1_decode_i_block(VC1Context *v, DCTELEM block[64], int n, +static int vc1_decode_i_block(VC1Context *v, int16_t block[64], int n, int coded, int codingset) { GetBitContext *gb = &v->s.gb; @@ -2831,7 +2788,7 @@ not_coded: * @param codingset set of VLC to decode data * @param mquant quantizer value for this macroblock */ -static int vc1_decode_i_block_adv(VC1Context *v, DCTELEM block[64], int n, +static int vc1_decode_i_block_adv(VC1Context *v, int16_t block[64], int n, int coded, int codingset, int mquant) { GetBitContext *gb = &v->s.gb; @@ -2900,11 +2857,11 @@ static int vc1_decode_i_block_adv(VC1Context *v, DCTELEM block[64], int n, else // top ac_val -= 16 * s->block_wrap[n]; - q1 = s->current_picture.f.qscale_table[mb_pos]; + q1 = s->current_picture.qscale_table[mb_pos]; if ( dc_pred_dir && c_avail && mb_pos) - q2 = s->current_picture.f.qscale_table[mb_pos - 1]; + q2 = s->current_picture.qscale_table[mb_pos - 1]; if (!dc_pred_dir && a_avail && mb_pos >= s->mb_stride) - q2 = s->current_picture.f.qscale_table[mb_pos - s->mb_stride]; + q2 = s->current_picture.qscale_table[mb_pos - s->mb_stride]; if ( dc_pred_dir && n == 1) q2 = q1; if (!dc_pred_dir && n == 2) @@ -2948,6 +2905,8 @@ static int vc1_decode_i_block_adv(VC1Context *v, DCTELEM block[64], int n, q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1; q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1; + if (q1 < 1) + return AVERROR_INVALIDDATA; if (dc_pred_dir) { // left for (k = 1; k < 8; k++) block[k << v->left_blk_sh] += (ac_val[k] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18; @@ -2990,6 +2949,8 @@ static int vc1_decode_i_block_adv(VC1Context *v, DCTELEM block[64], int n, if (q2 && q1 != q2) { q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1; q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1; + if (q1 < 1) + return AVERROR_INVALIDDATA; for (k = 1; k < 8; k++) ac_val2[k] = (ac_val2[k] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18; } @@ -3000,6 +2961,8 @@ static int vc1_decode_i_block_adv(VC1Context *v, DCTELEM block[64], int n, if (q2 && q1 != q2) { q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1; q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1; + if (q1 < 1) + return AVERROR_INVALIDDATA; for (k = 1; k < 8; k++) ac_val2[k + 8] = (ac_val2[k + 8] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18; } @@ -3037,7 +3000,7 @@ static int vc1_decode_i_block_adv(VC1Context *v, DCTELEM block[64], int n, * @param mquant block quantizer * @param codingset set of VLC to decode data */ -static int vc1_decode_intra_block(VC1Context *v, DCTELEM block[64], int n, +static int vc1_decode_intra_block(VC1Context *v, int16_t block[64], int n, int coded, int mquant, int codingset) { GetBitContext *gb = &v->s.gb; @@ -3117,11 +3080,11 @@ static int vc1_decode_intra_block(VC1Context *v, DCTELEM block[64], int n, else //top ac_val -= 16 * s->block_wrap[n]; - q1 = s->current_picture.f.qscale_table[mb_pos]; + q1 = s->current_picture.qscale_table[mb_pos]; if (dc_pred_dir && c_avail && mb_pos) - q2 = s->current_picture.f.qscale_table[mb_pos - 1]; + q2 = s->current_picture.qscale_table[mb_pos - 1]; if (!dc_pred_dir && a_avail && mb_pos >= s->mb_stride) - q2 = s->current_picture.f.qscale_table[mb_pos - s->mb_stride]; + q2 = s->current_picture.qscale_table[mb_pos - s->mb_stride]; if ( dc_pred_dir && n == 1) q2 = q1; if (!dc_pred_dir && n == 2) @@ -3158,6 +3121,8 @@ static int vc1_decode_intra_block(VC1Context *v, DCTELEM block[64], int n, q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1; q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1; + if (q1 < 1) + return AVERROR_INVALIDDATA; if (dc_pred_dir) { // left for (k = 1; k < 8; k++) block[k << v->left_blk_sh] += (ac_val[k] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18; @@ -3200,6 +3165,8 @@ static int vc1_decode_intra_block(VC1Context *v, DCTELEM block[64], int n, if (q2 && q1 != q2) { q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1; q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1; + if (q1 < 1) + return AVERROR_INVALIDDATA; for (k = 1; k < 8; k++) ac_val2[k] = (ac_val2[k] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18; } @@ -3210,6 +3177,8 @@ static int vc1_decode_intra_block(VC1Context *v, DCTELEM block[64], int n, if (q2 && q1 != q2) { q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1; q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1; + if (q1 < 1) + return AVERROR_INVALIDDATA; for (k = 1; k < 8; k++) ac_val2[k + 8] = (ac_val2[k + 8] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18; } @@ -3241,7 +3210,7 @@ static int vc1_decode_intra_block(VC1Context *v, DCTELEM block[64], int n, /** Decode P block */ -static int vc1_decode_p_block(VC1Context *v, DCTELEM block[64], int n, +static int vc1_decode_p_block(VC1Context *v, int16_t block[64], int n, int mquant, int ttmb, int first_block, uint8_t *dst, int linesize, int skip_block, int *ttmb_out) @@ -3433,7 +3402,7 @@ static av_always_inline void vc1_apply_p_v_loop_filter(VC1Context *v, int block_ bottom_is_intra = (block_num < 2) ? (mb_is_intra >> ((block_num + 2) * 4)) : (v->is_intra[s->mb_x] >> ((block_num - 2) * 4)); mv_stride = s->b8_stride; - mv = &s->current_picture.f.motion_val[0][s->block_index[block_num] - 2 * mv_stride]; + mv = &s->current_picture.motion_val[0][s->block_index[block_num] - 2 * mv_stride]; } if (bottom_is_intra & 1 || block_is_intra & 1 || @@ -3495,7 +3464,7 @@ static av_always_inline void vc1_apply_p_h_loop_filter(VC1Context *v, int block_ : (mb_cbp >> ((block_num + 1) * 4)); right_is_intra = (block_num & 1) ? (v->is_intra[s->mb_x - s->mb_stride] >> ((block_num - 1) * 4)) : (mb_is_intra >> ((block_num + 1) * 4)); - mv = &s->current_picture.f.motion_val[0][s->block_index[block_num] - s->b8_stride * 2 - 2]; + mv = &s->current_picture.motion_val[0][s->block_index[block_num] - s->b8_stride * 2 - 2]; } if (block_is_intra & 1 || right_is_intra & 1 || mv[0][0] != mv[1][0] || mv[0][1] != mv[1][1]) { v->vc1dsp.vc1_h_loop_filter8(dst, linesize, v->pq); @@ -3589,10 +3558,10 @@ static int vc1_decode_p_mb(VC1Context *v) GET_MVDATA(dmv_x, dmv_y); if (s->mb_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.motion_val[1][s->block_index[0]][0] = 0; + s->current_picture.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; + s->current_picture.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], 0, 0); /* FIXME Set DC val for inter block ? */ @@ -3609,7 +3578,7 @@ static int vc1_decode_p_mb(VC1Context *v) mquant = v->pq; cbp = 0; } - s->current_picture.f.qscale_table[mb_pos] = mquant; + s->current_picture.qscale_table[mb_pos] = mquant; if (!v->ttmbf && !s->mb_intra && mb_has_coeffs) ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, @@ -3663,8 +3632,8 @@ static int vc1_decode_p_mb(VC1Context *v) 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; + s->current_picture.mb_type[mb_pos] = MB_TYPE_SKIP; + s->current_picture.qscale_table[mb_pos] = 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); } @@ -3687,7 +3656,7 @@ static int vc1_decode_p_mb(VC1Context *v) } 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); + vc1_mc_4mv_luma(v, i, 0, 0); intra_count += s->mb_intra; is_intra[i] = s->mb_intra; is_coded[i] = mb_has_coeffs; @@ -3707,7 +3676,7 @@ static int vc1_decode_p_mb(VC1Context *v) if (!intra_count && !coded_inter) goto end; GET_MQUANT(); - s->current_picture.f.qscale_table[mb_pos] = mquant; + s->current_picture.qscale_table[mb_pos] = mquant; /* test if block is intra and has pred */ { int intrapred = 0; @@ -3770,17 +3739,17 @@ static int vc1_decode_p_mb(VC1Context *v) } } else { // skipped MB s->mb_intra = 0; - s->current_picture.f.qscale_table[mb_pos] = 0; + s->current_picture.qscale_table[mb_pos] = 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; } for (i = 0; i < 4; 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_luma(v, i, 0, 0); } vc1_mc_4mv_chroma(v, 0); - s->current_picture.f.qscale_table[mb_pos] = 0; + s->current_picture.qscale_table[mb_pos] = 0; } } end: @@ -3855,9 +3824,11 @@ static int vc1_decode_p_mb_intfr(VC1Context *v) 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; + for (i = 0; i < 4; i++) { + s->current_picture.motion_val[1][s->block_index[i]][0] = 0; + s->current_picture.motion_val[1][s->block_index[i]][1] = 0; + } + s->current_picture.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; @@ -3867,7 +3838,7 @@ static int vc1_decode_p_mb_intfr(VC1Context *v) 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; + s->current_picture.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]; @@ -3925,10 +3896,10 @@ static int vc1_decode_p_mb_intfr(VC1Context *v) 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); + vc1_pred_mv_intfr(v, i, dmv_x, dmv_y, 0, v->range_x, v->range_y, v->mb_type[0], 0); + vc1_mc_4mv_luma(v, i, 0, 0); } else if (i == 4) { - vc1_mc_4mv_chroma4(v); + vc1_mc_4mv_chroma4(v, 0, 0, 0); } } } else if (twomv) { @@ -3937,28 +3908,29 @@ static int vc1_decode_p_mb_intfr(VC1Context *v) 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); + vc1_pred_mv_intfr(v, 0, dmv_x, dmv_y, 2, v->range_x, v->range_y, v->mb_type[0], 0); + vc1_mc_4mv_luma(v, 0, 0, 0); + vc1_mc_4mv_luma(v, 1, 0, 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); + vc1_pred_mv_intfr(v, 2, dmv_x, dmv_y, 2, v->range_x, v->range_y, v->mb_type[0], 0); + vc1_mc_4mv_luma(v, 2, 0, 0); + vc1_mc_4mv_luma(v, 3, 0, 0); + vc1_mc_4mv_chroma4(v, 0, 0, 0); } else { mvbp = ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][2]; + dmv_x = dmv_y = 0; 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_pred_mv_intfr(v, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0], 0); vc1_mc_1mv(v, 0); } if (cbp) GET_MQUANT(); // p. 227 - s->current_picture.f.qscale_table[mb_pos] = mquant; + s->current_picture.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++) { @@ -3987,13 +3959,13 @@ static int vc1_decode_p_mb_intfr(VC1Context *v) 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; + s->current_picture.mb_type[mb_pos] = MB_TYPE_SKIP; + s->current_picture.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_pred_mv_intfr(v, 0, 0, 0, 1, v->range_x, v->range_y, v->mb_type[0], 0); vc1_mc_1mv(v, 0); } if (s->mb_x == s->mb_width - 1) @@ -4025,11 +3997,11 @@ static int vc1_decode_p_mb_intfi(VC1Context *v) 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; + s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0; + s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0; + s->current_picture.mb_type[mb_pos + v->mb_off] = MB_TYPE_INTRA; GET_MQUANT(); - s->current_picture.f.qscale_table[mb_pos] = mquant; + s->current_picture.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]; @@ -4055,16 +4027,15 @@ static int vc1_decode_p_mb_intfi(VC1Context *v) continue; v->vc1dsp.vc1_inv_trans_8x8(s->block[i]); off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize); - off += v->cur_field_type ? ((i & 4) ? s->current_picture_ptr->f.linesize[1] : s->current_picture_ptr->f.linesize[0]) : 0; s->dsp.put_signed_pixels_clamped(s->block[i], s->dest[dst_idx] + off, (i & 4) ? s->uvlinesize : s->linesize); // TODO: loop filter } } 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; + s->current_picture.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; + dmv_x = dmv_y = pred_flag = 0; if (idx_mbmode & 1) { get_mvdata_interlaced(v, &dmv_x, &dmv_y, &pred_flag); } @@ -4081,7 +4052,7 @@ static int vc1_decode_p_mb_intfi(VC1Context *v) 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); + vc1_mc_4mv_luma(v, i, 0, 0); } else if (i == 4) vc1_mc_4mv_chroma(v, 0); } @@ -4092,7 +4063,7 @@ static int vc1_decode_p_mb_intfi(VC1Context *v) if (cbp) { GET_MQUANT(); } - s->current_picture.f.qscale_table[mb_pos] = mquant; + s->current_picture.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); } @@ -4102,8 +4073,6 @@ static int vc1_decode_p_mb_intfi(VC1Context *v) dst_idx += i >> 2; val = ((cbp >> (5 - i)) & 1); off = (i & 4) ? 0 : (i & 1) * 8 + (i & 2) * 4 * s->linesize; - if (v->cur_field_type) - off += (i & 4) ? s->current_picture_ptr->f.linesize[1] : s->current_picture_ptr->f.linesize[0]; if (val) { pat = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, first_block, s->dest[dst_idx] + off, @@ -4158,7 +4127,7 @@ static void vc1_decode_b_mb(VC1Context *v) v->mb_type[0][s->block_index[i]] = 0; s->dc_val[0][s->block_index[i]] = 0; } - s->current_picture.f.qscale_table[mb_pos] = 0; + s->current_picture.qscale_table[mb_pos] = 0; if (!direct) { if (!skipped) { @@ -4195,7 +4164,7 @@ static void vc1_decode_b_mb(VC1Context *v) cbp = get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2); GET_MQUANT(); s->mb_intra = 0; - s->current_picture.f.qscale_table[mb_pos] = mquant; + s->current_picture.qscale_table[mb_pos] = mquant; if (!v->ttmbf) ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2); dmv_x[0] = dmv_y[0] = dmv_x[1] = dmv_y[1] = 0; @@ -4210,7 +4179,7 @@ static void vc1_decode_b_mb(VC1Context *v) } if (s->mb_intra && !mb_has_coeffs) { GET_MQUANT(); - s->current_picture.f.qscale_table[mb_pos] = mquant; + s->current_picture.qscale_table[mb_pos] = mquant; s->ac_pred = get_bits1(gb); cbp = 0; vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype); @@ -4232,7 +4201,7 @@ static void vc1_decode_b_mb(VC1Context *v) s->ac_pred = get_bits1(gb); cbp = get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2); GET_MQUANT(); - s->current_picture.f.qscale_table[mb_pos] = mquant; + s->current_picture.qscale_table[mb_pos] = mquant; if (!v->ttmbf && !s->mb_intra && mb_has_coeffs) ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2); } @@ -4299,11 +4268,11 @@ static void vc1_decode_b_mb_intfi(VC1Context *v) 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; + s->current_picture.motion_val[1][s->block_index[0]][0] = 0; + s->current_picture.motion_val[1][s->block_index[0]][1] = 0; + s->current_picture.mb_type[mb_pos + v->mb_off] = MB_TYPE_INTRA; GET_MQUANT(); - s->current_picture.f.qscale_table[mb_pos] = mquant; + s->current_picture.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]; @@ -4332,13 +4301,12 @@ static void vc1_decode_b_mb_intfi(VC1Context *v) for (j = 0; j < 64; j++) s->block[i][j] <<= 1; off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize); - off += v->cur_field_type ? ((i & 4) ? s->current_picture_ptr->f.linesize[1] : s->current_picture_ptr->f.linesize[0]) : 0; s->dsp.put_signed_pixels_clamped(s->block[i], s->dest[dst_idx] + off, (i & 4) ? s->uvlinesize : s->linesize); // TODO: yet to perform loop filter } } 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; + s->current_picture.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); @@ -4393,7 +4361,7 @@ static void vc1_decode_b_mb_intfi(VC1Context *v) &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); + vc1_mc_4mv_luma(v, i, bmvtype == BMV_TYPE_BACKWARD, 0); } else if (i == 4) vc1_mc_4mv_chroma(v, bmvtype == BMV_TYPE_BACKWARD); } @@ -4404,7 +4372,7 @@ static void vc1_decode_b_mb_intfi(VC1Context *v) if (cbp) { GET_MQUANT(); } - s->current_picture.f.qscale_table[mb_pos] = mquant; + s->current_picture.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); } @@ -4414,8 +4382,6 @@ static void vc1_decode_b_mb_intfi(VC1Context *v) dst_idx += i >> 2; val = ((cbp >> (5 - i)) & 1); off = (i & 4) ? 0 : (i & 1) * 8 + (i & 2) * 4 * s->linesize; - if (v->cur_field_type) - off += (i & 4) ? s->current_picture_ptr->f.linesize[1] : s->current_picture_ptr->f.linesize[0]; if (val) { vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, first_block, s->dest[dst_idx] + off, @@ -4429,6 +4395,350 @@ static void vc1_decode_b_mb_intfi(VC1Context *v) } } +/** Decode one B-frame MB (in interlaced frame B picture) + */ +static int vc1_decode_b_mb_intfr(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 mvsw = 0; /* motion vector switch */ + 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, direct, twomv = 0; + int block_cbp = 0, pat, block_tt = 0; + int idx_mbmode = 0, mvbp; + int stride_y, fieldtx; + int bmvtype = BMV_TYPE_BACKWARD; + int dir, dir2; + + mquant = v->pq; /* Lossy initialization */ + s->mb_intra = 0; + if (v->skip_is_raw) + skipped = get_bits1(gb); + else + skipped = v->s.mbskip_table[mb_pos]; + + if (!skipped) { + idx_mbmode = get_vlc2(gb, v->mbmode_vlc->table, VC1_INTFR_NON4MV_MBMODE_VLC_BITS, 2); + if (ff_vc1_mbmode_intfrp[0][idx_mbmode][0] == 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; + } else { + 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; + } + } + + if (v->dmb_is_raw) + direct = get_bits1(gb); + else + direct = v->direct_mb_plane[mb_pos]; + + if (direct) { + s->mv[0][0][0] = s->current_picture.motion_val[0][s->block_index[0]][0] = scale_mv(s->next_picture.motion_val[1][s->block_index[0]][0], v->bfraction, 0, s->quarter_sample); + s->mv[0][0][1] = s->current_picture.motion_val[0][s->block_index[0]][1] = scale_mv(s->next_picture.motion_val[1][s->block_index[0]][1], v->bfraction, 0, s->quarter_sample); + s->mv[1][0][0] = s->current_picture.motion_val[1][s->block_index[0]][0] = scale_mv(s->next_picture.motion_val[1][s->block_index[0]][0], v->bfraction, 1, s->quarter_sample); + s->mv[1][0][1] = s->current_picture.motion_val[1][s->block_index[0]][1] = scale_mv(s->next_picture.motion_val[1][s->block_index[0]][1], v->bfraction, 1, s->quarter_sample); + + if (twomv) { + s->mv[0][2][0] = s->current_picture.motion_val[0][s->block_index[2]][0] = scale_mv(s->next_picture.motion_val[1][s->block_index[2]][0], v->bfraction, 0, s->quarter_sample); + s->mv[0][2][1] = s->current_picture.motion_val[0][s->block_index[2]][1] = scale_mv(s->next_picture.motion_val[1][s->block_index[2]][1], v->bfraction, 0, s->quarter_sample); + s->mv[1][2][0] = s->current_picture.motion_val[1][s->block_index[2]][0] = scale_mv(s->next_picture.motion_val[1][s->block_index[2]][0], v->bfraction, 1, s->quarter_sample); + s->mv[1][2][1] = s->current_picture.motion_val[1][s->block_index[2]][1] = scale_mv(s->next_picture.motion_val[1][s->block_index[2]][1], v->bfraction, 1, s->quarter_sample); + + for (i = 1; i < 4; i += 2) { + s->mv[0][i][0] = s->current_picture.motion_val[0][s->block_index[i]][0] = s->mv[0][i-1][0]; + s->mv[0][i][1] = s->current_picture.motion_val[0][s->block_index[i]][1] = s->mv[0][i-1][1]; + s->mv[1][i][0] = s->current_picture.motion_val[1][s->block_index[i]][0] = s->mv[1][i-1][0]; + s->mv[1][i][1] = s->current_picture.motion_val[1][s->block_index[i]][1] = s->mv[1][i-1][1]; + } + } else { + for (i = 1; i < 4; i++) { + s->mv[0][i][0] = s->current_picture.motion_val[0][s->block_index[i]][0] = s->mv[0][0][0]; + s->mv[0][i][1] = s->current_picture.motion_val[0][s->block_index[i]][1] = s->mv[0][0][1]; + s->mv[1][i][0] = s->current_picture.motion_val[1][s->block_index[i]][0] = s->mv[1][0][0]; + s->mv[1][i][1] = s->current_picture.motion_val[1][s->block_index[i]][1] = s->mv[1][0][1]; + } + } + } + + if (ff_vc1_mbmode_intfrp[0][idx_mbmode][0] == MV_PMODE_INTFR_INTRA) { // intra MB + for (i = 0; i < 4; i++) { + s->mv[0][i][0] = s->current_picture.motion_val[0][s->block_index[i]][0] = 0; + s->mv[0][i][1] = s->current_picture.motion_val[0][s->block_index[i]][1] = 0; + s->mv[1][i][0] = s->current_picture.motion_val[1][s->block_index[i]][0] = 0; + s->mv[1][i][1] = s->current_picture.motion_val[1][s->block_index[i]][1] = 0; + } + s->current_picture.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.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); + } + } else { + s->mb_intra = v->is_intra[s->mb_x] = 0; + if (!direct) { + if (skipped || !s->mb_intra) { + bmvtype = decode012(gb); + switch (bmvtype) { + case 0: + bmvtype = (v->bfraction >= (B_FRACTION_DEN/2)) ? BMV_TYPE_BACKWARD : BMV_TYPE_FORWARD; + break; + case 1: + bmvtype = (v->bfraction >= (B_FRACTION_DEN/2)) ? BMV_TYPE_FORWARD : BMV_TYPE_BACKWARD; + break; + case 2: + bmvtype = BMV_TYPE_INTERPOLATED; + } + } + + if (twomv && bmvtype != BMV_TYPE_INTERPOLATED) + mvsw = get_bits1(gb); + } + + if (!skipped) { // inter MB + mb_has_coeffs = ff_vc1_mbmode_intfrp[0][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 (!direct) { + if (bmvtype == BMV_TYPE_INTERPOLATED & twomv) { + v->fourmvbp = get_vlc2(gb, v->fourmvbp_vlc->table, VC1_4MV_BLOCK_PATTERN_VLC_BITS, 1); + } else if (bmvtype == BMV_TYPE_INTERPOLATED | twomv) { + v->twomvbp = get_vlc2(gb, v->twomvbp_vlc->table, VC1_2MV_BLOCK_PATTERN_VLC_BITS, 1); + } + } + + 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[0][idx_mbmode][1]; + /* for all motion vector read MVDATA and motion compensate each block */ + dst_idx = 0; + if (direct) { + if (twomv) { + for (i = 0; i < 4; i++) { + vc1_mc_4mv_luma(v, i, 0, 0); + vc1_mc_4mv_luma(v, i, 1, 1); + } + vc1_mc_4mv_chroma4(v, 0, 0, 0); + vc1_mc_4mv_chroma4(v, 1, 1, 1); + } else { + vc1_mc_1mv(v, 0); + vc1_interp_mc(v); + } + } else if (twomv && bmvtype == BMV_TYPE_INTERPOLATED) { + mvbp = v->fourmvbp; + for (i = 0; i < 4; i++) { + dir = i==1 || i==3; + dmv_x = dmv_y = 0; + val = ((mvbp >> (3 - i)) & 1); + if (val) + get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0); + j = i > 1 ? 2 : 0; + vc1_pred_mv_intfr(v, j, dmv_x, dmv_y, 2, v->range_x, v->range_y, v->mb_type[0], dir); + vc1_mc_4mv_luma(v, j, dir, dir); + vc1_mc_4mv_luma(v, j+1, dir, dir); + } + + vc1_mc_4mv_chroma4(v, 0, 0, 0); + vc1_mc_4mv_chroma4(v, 1, 1, 1); + } else if (bmvtype == BMV_TYPE_INTERPOLATED) { + 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, 1, v->range_x, v->range_y, v->mb_type[0], 0); + vc1_mc_1mv(v, 0); + + dmv_x = dmv_y = 0; + if (mvbp & 1) + 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], 1); + vc1_interp_mc(v); + } else if (twomv) { + dir = bmvtype == BMV_TYPE_BACKWARD; + dir2 = dir; + if (mvsw) + dir2 = !dir; + 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], dir); + + 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], dir2); + + if (mvsw) { + for (i = 0; i < 2; i++) { + s->mv[dir][i+2][0] = s->mv[dir][i][0] = s->current_picture.motion_val[dir][s->block_index[i+2]][0] = s->current_picture.motion_val[dir][s->block_index[i]][0]; + s->mv[dir][i+2][1] = s->mv[dir][i][1] = s->current_picture.motion_val[dir][s->block_index[i+2]][1] = s->current_picture.motion_val[dir][s->block_index[i]][1]; + s->mv[dir2][i+2][0] = s->mv[dir2][i][0] = s->current_picture.motion_val[dir2][s->block_index[i]][0] = s->current_picture.motion_val[dir2][s->block_index[i+2]][0]; + s->mv[dir2][i+2][1] = s->mv[dir2][i][1] = s->current_picture.motion_val[dir2][s->block_index[i]][1] = s->current_picture.motion_val[dir2][s->block_index[i+2]][1]; + } + } else { + vc1_pred_mv_intfr(v, 0, 0, 0, 2, v->range_x, v->range_y, v->mb_type[0], !dir); + vc1_pred_mv_intfr(v, 2, 0, 0, 2, v->range_x, v->range_y, v->mb_type[0], !dir); + } + + vc1_mc_4mv_luma(v, 0, dir, 0); + vc1_mc_4mv_luma(v, 1, dir, 0); + vc1_mc_4mv_luma(v, 2, dir2, 0); + vc1_mc_4mv_luma(v, 3, dir2, 0); + vc1_mc_4mv_chroma4(v, dir, dir2, 0); + } else { + dir = bmvtype == BMV_TYPE_BACKWARD; + + mvbp = ff_vc1_mbmode_intfrp[0][idx_mbmode][2]; + dmv_x = dmv_y = 0; + 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], dir); + 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; + vc1_pred_mv_intfr(v, 0, 0, 0, 2, v->range_x, v->range_y, 0, !dir); + for (i = 0; i < 2; i++) { + s->mv[!dir][i+2][0] = s->mv[!dir][i][0] = s->current_picture.motion_val[!dir][s->block_index[i+2]][0] = s->current_picture.motion_val[!dir][s->block_index[i]][0]; + s->mv[!dir][i+2][1] = s->mv[!dir][i][1] = s->current_picture.motion_val[!dir][s->block_index[i+2]][1] = s->current_picture.motion_val[!dir][s->block_index[i]][1]; + } + vc1_mc_1mv(v, dir); + } + + if (cbp) + GET_MQUANT(); // p. 227 + s->current_picture.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 + dir = 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.mb_type[mb_pos] = MB_TYPE_SKIP; + s->current_picture.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; + + if (!direct) { + if (bmvtype == BMV_TYPE_INTERPOLATED) { + vc1_pred_mv_intfr(v, 0, 0, 0, 1, v->range_x, v->range_y, v->mb_type[0], 0); + vc1_pred_mv_intfr(v, 0, 0, 0, 1, v->range_x, v->range_y, v->mb_type[0], 1); + } else { + dir = bmvtype == BMV_TYPE_BACKWARD; + vc1_pred_mv_intfr(v, 0, 0, 0, 1, v->range_x, v->range_y, v->mb_type[0], dir); + if (mvsw) { + int dir2 = dir; + if (mvsw) + dir2 = !dir; + for (i = 0; i < 2; i++) { + s->mv[dir][i+2][0] = s->mv[dir][i][0] = s->current_picture.motion_val[dir][s->block_index[i+2]][0] = s->current_picture.motion_val[dir][s->block_index[i]][0]; + s->mv[dir][i+2][1] = s->mv[dir][i][1] = s->current_picture.motion_val[dir][s->block_index[i+2]][1] = s->current_picture.motion_val[dir][s->block_index[i]][1]; + s->mv[dir2][i+2][0] = s->mv[dir2][i][0] = s->current_picture.motion_val[dir2][s->block_index[i]][0] = s->current_picture.motion_val[dir2][s->block_index[i+2]][0]; + s->mv[dir2][i+2][1] = s->mv[dir2][i][1] = s->current_picture.motion_val[dir2][s->block_index[i]][1] = s->current_picture.motion_val[dir2][s->block_index[i+2]][1]; + } + } else { + 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; + vc1_pred_mv_intfr(v, 0, 0, 0, 2, v->range_x, v->range_y, 0, !dir); + for (i = 0; i < 2; i++) { + s->mv[!dir][i+2][0] = s->mv[!dir][i][0] = s->current_picture.motion_val[!dir][s->block_index[i+2]][0] = s->current_picture.motion_val[!dir][s->block_index[i]][0]; + s->mv[!dir][i+2][1] = s->mv[!dir][i][1] = s->current_picture.motion_val[!dir][s->block_index[i+2]][1] = s->current_picture.motion_val[!dir][s->block_index[i]][1]; + } + } + } + } + + vc1_mc_1mv(v, dir); + if (direct || bmvtype == BMV_TYPE_INTERPOLATED) { + vc1_interp_mc(v); + } + } + } + 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); + v->cbp[s->mb_x] = block_cbp; + v->ttblk[s->mb_x] = block_tt; + return 0; +} + /** Decode blocks of I-frame */ static void vc1_decode_i_blocks(VC1Context *v) @@ -4472,10 +4782,10 @@ static void vc1_decode_i_blocks(VC1Context *v) s->mb_x = s->mb_y = 0; s->mb_intra = 1; s->first_slice_line = 1; - for (s->mb_y = 0; s->mb_y < s->mb_height; s->mb_y++) { + for (s->mb_y = 0; s->mb_y < s->end_mb_y; s->mb_y++) { s->mb_x = 0; - ff_init_block_index(s); - for (; s->mb_x < s->mb_width; s->mb_x++) { + init_block_index(v); + for (; s->mb_x < v->end_mb_x; s->mb_x++) { uint8_t *dst[6]; ff_update_block_index(s); dst[0] = s->dest[0]; @@ -4486,10 +4796,10 @@ static void vc1_decode_i_blocks(VC1Context *v) dst[5] = s->dest[2]; s->dsp.clear_blocks(s->block[0]); mb_pos = s->mb_x + s->mb_y * s->mb_width; - s->current_picture.f.mb_type[mb_pos] = MB_TYPE_INTRA; - s->current_picture.f.qscale_table[mb_pos] = v->pq; - 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.mb_type[mb_pos] = MB_TYPE_INTRA; + s->current_picture.qscale_table[mb_pos] = v->pq; + s->current_picture.motion_val[1][s->block_index[0]][0] = 0; + s->current_picture.motion_val[1][s->block_index[0]][1] = 0; // do actual MB decoding and displaying cbp = get_vlc2(&v->s.gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2); @@ -4548,22 +4858,25 @@ static void vc1_decode_i_blocks(VC1Context *v) if (v->s.loop_filter) vc1_loop_filter_iblk(v, v->pq); if (get_bits_count(&s->gb) > v->bits) { - ff_er_add_slice(s, 0, 0, s->mb_x, s->mb_y, ER_MB_ERROR); + ff_er_add_slice(&s->er, 0, 0, s->mb_x, s->mb_y, ER_MB_ERROR); av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i\n", get_bits_count(&s->gb), v->bits); return; } } if (!v->s.loop_filter) - ff_draw_horiz_band(s, s->mb_y * 16, 16); + ff_mpeg_draw_horiz_band(s, s->mb_y * 16, 16); else if (s->mb_y) - ff_draw_horiz_band(s, (s->mb_y - 1) * 16, 16); + ff_mpeg_draw_horiz_band(s, (s->mb_y - 1) * 16, 16); s->first_slice_line = 0; } if (v->s.loop_filter) - ff_draw_horiz_band(s, (s->mb_height - 1) * 16, 16); - ff_er_add_slice(s, 0, 0, s->mb_width - 1, s->mb_height - 1, ER_MB_END); + ff_mpeg_draw_horiz_band(s, (s->end_mb_y - 1) * 16, 16); + + /* This is intentionally mb_height and not end_mb_y - unlike in advanced + * profile, these only differ are when decoding MSS2 rectangles. */ + ff_er_add_slice(&s->er, 0, 0, s->mb_width - 1, s->mb_height - 1, ER_MB_END); } /** Decode blocks of I-frame for advanced profile @@ -4611,21 +4924,21 @@ static void vc1_decode_i_blocks_adv(VC1Context *v) s->mb_y = s->start_mb_y; if (s->start_mb_y) { s->mb_x = 0; - ff_init_block_index(s); + init_block_index(v); memset(&s->coded_block[s->block_index[0] - s->b8_stride], 0, (1 + s->b8_stride) * sizeof(*s->coded_block)); } for (; s->mb_y < s->end_mb_y; s->mb_y++) { s->mb_x = 0; - ff_init_block_index(s); + init_block_index(v); for (;s->mb_x < s->mb_width; s->mb_x++) { - DCTELEM (*block)[64] = v->block[v->cur_blk_idx]; + int16_t (*block)[64] = v->block[v->cur_blk_idx]; 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 + 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; + s->current_picture.mb_type[mb_pos + v->mb_off] = MB_TYPE_INTRA; + s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0; + s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0; // do actual MB decoding and displaying if (v->fieldtx_is_raw) @@ -4641,7 +4954,7 @@ static void vc1_decode_i_blocks_adv(VC1Context *v) GET_MQUANT(); - s->current_picture.f.qscale_table[mb_pos] = mquant; + s->current_picture.qscale_table[mb_pos] = mquant; /* Set DC scale - y and c use the same */ s->y_dc_scale = s->y_dc_scale_table[mquant]; s->c_dc_scale = s->c_dc_scale_table[mquant]; @@ -4673,22 +4986,23 @@ static void vc1_decode_i_blocks_adv(VC1Context *v) 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, ER_MB_ERROR); + ff_er_add_slice(&s->er, 0, s->start_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR); av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i\n", get_bits_count(&s->gb), v->bits); return; } } if (!v->s.loop_filter) - ff_draw_horiz_band(s, s->mb_y * 16, 16); + ff_mpeg_draw_horiz_band(s, s->mb_y * 16, 16); else if (s->mb_y) - ff_draw_horiz_band(s, (s->mb_y-1) * 16, 16); + ff_mpeg_draw_horiz_band(s, (s->mb_y-1) * 16, 16); s->first_slice_line = 0; } /* raw bottom MB row */ s->mb_x = 0; - ff_init_block_index(s); + init_block_index(v); + for (;s->mb_x < s->mb_width; s->mb_x++) { ff_update_block_index(s); vc1_put_signed_blocks_clamped(v); @@ -4696,8 +5010,8 @@ static void vc1_decode_i_blocks_adv(VC1Context *v) vc1_loop_filter_iblk_delayed(v, v->pq); } 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 << v->field_mode, s->mb_width - 1, + ff_mpeg_draw_horiz_band(s, (s->end_mb_y-1)*16, 16); + ff_er_add_slice(&s->er, 0, s->start_mb_y << v->field_mode, s->mb_width - 1, (s->end_mb_y << v->field_mode) - 1, ER_MB_END); } @@ -4731,12 +5045,13 @@ static void vc1_decode_p_blocks(VC1Context *v) break; } - apply_loop_filter = s->loop_filter && !(s->avctx->skip_loop_filter >= AVDISCARD_NONKEY); + apply_loop_filter = s->loop_filter && !(s->avctx->skip_loop_filter >= AVDISCARD_NONKEY) && + v->fcm == PROGRESSIVE; s->first_slice_line = 1; memset(v->cbp_base, 0, sizeof(v->cbp_base[0])*2*s->mb_stride); for (s->mb_y = s->start_mb_y; s->mb_y < s->end_mb_y; s->mb_y++) { s->mb_x = 0; - ff_init_block_index(s); + init_block_index(v); for (; s->mb_x < s->mb_width; s->mb_x++) { ff_update_block_index(s); @@ -4745,11 +5060,11 @@ static void vc1_decode_p_blocks(VC1Context *v) else if (v->fcm == ILACE_FRAME) 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 == PROGRESSIVE) + if (s->mb_y != s->start_mb_y && apply_loop_filter) 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, ER_MB_ERROR); + ff_er_add_slice(&s->er, 0, s->start_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR); 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; @@ -4759,20 +5074,20 @@ static void vc1_decode_p_blocks(VC1Context *v) memmove(v->ttblk_base, v->ttblk, sizeof(v->ttblk_base[0]) * s->mb_stride); memmove(v->is_intra_base, v->is_intra, sizeof(v->is_intra_base[0]) * s->mb_stride); memmove(v->luma_mv_base, v->luma_mv, sizeof(v->luma_mv_base[0]) * s->mb_stride); - if (s->mb_y != s->start_mb_y) ff_draw_horiz_band(s, (s->mb_y - 1) * 16, 16); + if (s->mb_y != s->start_mb_y) ff_mpeg_draw_horiz_band(s, (s->mb_y - 1) * 16, 16); s->first_slice_line = 0; } if (apply_loop_filter) { s->mb_x = 0; - ff_init_block_index(s); + init_block_index(v); for (; s->mb_x < s->mb_width; s->mb_x++) { ff_update_block_index(s); vc1_apply_p_loop_filter(v); } } 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 << v->field_mode, s->mb_width - 1, + ff_mpeg_draw_horiz_band(s, (s->end_mb_y - 1) * 16, 16); + ff_er_add_slice(&s->er, 0, s->start_mb_y << v->field_mode, s->mb_width - 1, (s->end_mb_y << v->field_mode) - 1, ER_MB_END); } @@ -4808,17 +5123,19 @@ static void vc1_decode_b_blocks(VC1Context *v) s->first_slice_line = 1; for (s->mb_y = s->start_mb_y; s->mb_y < s->end_mb_y; s->mb_y++) { s->mb_x = 0; - ff_init_block_index(s); + init_block_index(v); for (; s->mb_x < s->mb_width; s->mb_x++) { ff_update_block_index(s); if (v->fcm == ILACE_FIELD) vc1_decode_b_mb_intfi(v); + else if (v->fcm == ILACE_FRAME) + vc1_decode_b_mb_intfr(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, ER_MB_ERROR); + ff_er_add_slice(&s->er, 0, s->start_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR); 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; @@ -4826,14 +5143,14 @@ static void vc1_decode_b_blocks(VC1Context *v) if (v->s.loop_filter) vc1_loop_filter_iblk(v, v->pq); } if (!v->s.loop_filter) - ff_draw_horiz_band(s, s->mb_y * 16, 16); + ff_mpeg_draw_horiz_band(s, s->mb_y * 16, 16); else if (s->mb_y) - ff_draw_horiz_band(s, (s->mb_y - 1) * 16, 16); + ff_mpeg_draw_horiz_band(s, (s->mb_y - 1) * 16, 16); s->first_slice_line = 0; } 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 << v->field_mode, s->mb_width - 1, + ff_mpeg_draw_horiz_band(s, (s->end_mb_y - 1) * 16, 16); + ff_er_add_slice(&s->er, 0, s->start_mb_y << v->field_mode, s->mb_width - 1, (s->end_mb_y << v->field_mode) - 1, ER_MB_END); } @@ -4841,22 +5158,25 @@ static void vc1_decode_skip_blocks(VC1Context *v) { MpegEncContext *s = &v->s; - ff_er_add_slice(s, 0, s->start_mb_y, s->mb_width - 1, s->end_mb_y - 1, ER_MB_END); + if (!v->s.last_picture.f.data[0]) + return; + + ff_er_add_slice(&s->er, 0, s->start_mb_y, s->mb_width - 1, s->end_mb_y - 1, ER_MB_END); s->first_slice_line = 1; for (s->mb_y = s->start_mb_y; s->mb_y < s->end_mb_y; s->mb_y++) { s->mb_x = 0; - ff_init_block_index(s); + init_block_index(v); ff_update_block_index(s); memcpy(s->dest[0], s->last_picture.f.data[0] + s->mb_y * 16 * s->linesize, s->linesize * 16); memcpy(s->dest[1], s->last_picture.f.data[1] + s->mb_y * 8 * s->uvlinesize, s->uvlinesize * 8); memcpy(s->dest[2], s->last_picture.f.data[2] + s->mb_y * 8 * s->uvlinesize, s->uvlinesize * 8); - ff_draw_horiz_band(s, s->mb_y * 16, 16); + ff_mpeg_draw_horiz_band(s, s->mb_y * 16, 16); s->first_slice_line = 0; } s->pict_type = AV_PICTURE_TYPE_P; } -static void vc1_decode_blocks(VC1Context *v) +void ff_vc1_decode_blocks(VC1Context *v) { v->s.esc3_level_length = 0; @@ -4961,7 +5281,7 @@ static void vc1_parse_sprites(VC1Context *v, GetBitContext* gb, SpriteData* sd) for (sprite = 0; sprite <= v->two_sprites; sprite++) { vc1_sprite_parse_transform(gb, sd->coefs[sprite]); if (sd->coefs[sprite][1] || sd->coefs[sprite][3]) - av_log_ask_for_sample(avctx, "Rotation coefficients are not zero"); + avpriv_request_sample(avctx, "Non-zero rotation coefficients"); av_log(avctx, AV_LOG_DEBUG, sprite ? "S2:" : "S1:"); for (i = 0; i < 7; i++) av_log(avctx, AV_LOG_DEBUG, " %d.%.3d", @@ -5014,7 +5334,7 @@ static void vc1_parse_sprites(VC1Context *v, GetBitContext* gb, SpriteData* sd) av_log(avctx, AV_LOG_DEBUG, "Effect flag set\n"); if (get_bits_count(gb) >= gb->size_in_bits + - (avctx->codec_id == CODEC_ID_WMV3IMAGE ? 64 : 0)) + (avctx->codec_id == AV_CODEC_ID_WMV3IMAGE ? 64 : 0)) av_log(avctx, AV_LOG_ERROR, "Buffer overrun\n"); if (get_bits_count(gb) < gb->size_in_bits - 8) av_log(avctx, AV_LOG_WARNING, "Buffer not fully read\n"); @@ -5044,23 +5364,25 @@ static void vc1_draw_sprites(VC1Context *v, SpriteData* sd) int width = v->output_width>>!!plane; for (row = 0; row < v->output_height>>!!plane; row++) { - uint8_t *dst = v->sprite_output_frame.data[plane] + - v->sprite_output_frame.linesize[plane] * row; + uint8_t *dst = v->sprite_output_frame->data[plane] + + v->sprite_output_frame->linesize[plane] * row; for (sprite = 0; sprite <= v->two_sprites; sprite++) { uint8_t *iplane = s->current_picture.f.data[plane]; int iline = s->current_picture.f.linesize[plane]; int ycoord = yoff[sprite] + yadv[sprite] * row; int yline = ycoord >> 16; + int next_line; ysub[sprite] = ycoord & 0xFFFF; if (sprite) { iplane = s->last_picture.f.data[plane]; iline = s->last_picture.f.linesize[plane]; } + next_line = FFMIN(yline + 1, (v->sprite_height >> !!plane) - 1) * iline; if (!(xoff[sprite] & 0xFFFF) && xadv[sprite] == 1 << 16) { src_h[sprite][0] = iplane + (xoff[sprite] >> 16) + yline * iline; if (ysub[sprite]) - src_h[sprite][1] = iplane + (xoff[sprite] >> 16) + (yline + 1) * iline; + src_h[sprite][1] = iplane + (xoff[sprite] >> 16) + next_line; } else { if (sr_cache[sprite][0] != yline) { if (sr_cache[sprite][1] == yline) { @@ -5072,7 +5394,9 @@ static void vc1_draw_sprites(VC1Context *v, SpriteData* sd) } } if (ysub[sprite] && sr_cache[sprite][1] != yline + 1) { - v->vc1dsp.sprite_h(v->sr_rows[sprite][1], iplane + (yline + 1) * iline, xoff[sprite], xadv[sprite], width); + v->vc1dsp.sprite_h(v->sr_rows[sprite][1], + iplane + next_line, xoff[sprite], + xadv[sprite], width); sr_cache[sprite][1] = yline + 1; } src_h[sprite][0] = v->sr_rows[sprite][0]; @@ -5131,12 +5455,8 @@ static int vc1_decode_sprites(VC1Context *v, GetBitContext* gb) v->two_sprites = 0; } - if (v->sprite_output_frame.data[0]) - avctx->release_buffer(avctx, &v->sprite_output_frame); - - v->sprite_output_frame.buffer_hints = FF_BUFFER_HINTS_VALID; - v->sprite_output_frame.reference = 0; - if (avctx->get_buffer(avctx, &v->sprite_output_frame) < 0) { + av_frame_unref(v->sprite_output_frame); + if (ff_get_buffer(avctx, v->sprite_output_frame, 0) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; } @@ -5166,18 +5486,19 @@ static void vc1_sprite_flush(AVCodecContext *avctx) #endif -static av_cold int vc1_decode_init_alloc_tables(VC1Context *v) +av_cold int ff_vc1_decode_init_alloc_tables(VC1Context *v) { MpegEncContext *s = &v->s; int i; + int mb_height = FFALIGN(s->mb_height, 2); /* 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); + v->mv_type_mb_plane = av_malloc (s->mb_stride * mb_height); + v->direct_mb_plane = av_malloc (s->mb_stride * mb_height); + v->forward_mb_plane = av_malloc (s->mb_stride * mb_height); + v->fieldtx_plane = av_mallocz(s->mb_stride * mb_height); + v->acpred_plane = av_malloc (s->mb_stride * mb_height); + v->over_flags_plane = av_malloc (s->mb_stride * mb_height); v->n_allocated_blks = s->mb_width + 2; v->block = av_malloc(sizeof(*v->block) * v->n_allocated_blks); @@ -5191,23 +5512,20 @@ static av_cold int vc1_decode_init_alloc_tables(VC1Context *v) v->luma_mv = v->luma_mv_base + s->mb_stride; /* allocate block type info in that way so it could be used with s->block_index[] */ - v->mb_type_base = av_malloc(s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2); + v->mb_type_base = av_malloc(s->b8_stride * (mb_height * 2 + 1) + s->mb_stride * (mb_height + 1) * 2); v->mb_type[0] = v->mb_type_base + s->b8_stride + 1; - 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); + v->mb_type[1] = v->mb_type_base + s->b8_stride * (mb_height * 2 + 1) + s->mb_stride + 1; + v->mb_type[2] = v->mb_type[1] + s->mb_stride * (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_base = av_mallocz( s->b8_stride * (mb_height * 2 + 1) + s->mb_stride * (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_base = av_mallocz(2 * (s->b8_stride * (mb_height * 2 + 1) + s->mb_stride * (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[1] = v->mv_f[0] + (s->b8_stride * (mb_height * 2 + 1) + s->mb_stride * (mb_height + 1) * 2); + v->mv_f_next_base = av_mallocz(2 * (s->b8_stride * (mb_height * 2 + 1) + s->mb_stride * (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); + v->mv_f_next[1] = v->mv_f_next[0] + (s->b8_stride * (mb_height * 2 + 1) + s->mb_stride * (mb_height + 1) * 2); /* Init coded blocks info */ if (v->profile == PROFILE_ADVANCED) { @@ -5219,19 +5537,45 @@ static av_cold int vc1_decode_init_alloc_tables(VC1Context *v) ff_intrax8_common_init(&v->x8,s); - if (s->avctx->codec_id == CODEC_ID_WMV3IMAGE || s->avctx->codec_id == CODEC_ID_VC1IMAGE) { + if (s->avctx->codec_id == AV_CODEC_ID_WMV3IMAGE || s->avctx->codec_id == AV_CODEC_ID_VC1IMAGE) { for (i = 0; i < 4; i++) if (!(v->sr_rows[i >> 1][i & 1] = av_malloc(v->output_width))) return -1; } if (!v->mv_type_mb_plane || !v->direct_mb_plane || !v->acpred_plane || !v->over_flags_plane || !v->block || !v->cbp_base || !v->ttblk_base || !v->is_intra_base || !v->luma_mv_base || - !v->mb_type_base) - return -1; + !v->mb_type_base) { + av_freep(&v->mv_type_mb_plane); + av_freep(&v->direct_mb_plane); + av_freep(&v->acpred_plane); + av_freep(&v->over_flags_plane); + av_freep(&v->block); + av_freep(&v->cbp_base); + av_freep(&v->ttblk_base); + av_freep(&v->is_intra_base); + av_freep(&v->luma_mv_base); + av_freep(&v->mb_type_base); + return AVERROR(ENOMEM); + } return 0; } +av_cold void ff_vc1_init_transposed_scantables(VC1Context *v) +{ + int i; + for (i = 0; i < 64; i++) { +#define transpose(x) ((x >> 3) | ((x & 7) << 3)) + v->zz_8x8[0][i] = transpose(ff_wmv1_scantable[0][i]); + v->zz_8x8[1][i] = transpose(ff_wmv1_scantable[1][i]); + v->zz_8x8[2][i] = transpose(ff_wmv1_scantable[2][i]); + v->zz_8x8[3][i] = transpose(ff_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; +} + /** Initialize a VC1/WMV3 decoder * @todo TODO: Handle VC-1 IDUs (Transport level?) * @todo TODO: Decypher remaining bits in extra_data @@ -5241,7 +5585,6 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx) VC1Context *v = avctx->priv_data; MpegEncContext *s = &v->s; GetBitContext gb; - int i; /* save the container output size for WMImage */ v->output_width = avctx->width; @@ -5252,21 +5595,16 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx) if (!(avctx->flags & CODEC_FLAG_GRAY)) avctx->pix_fmt = avctx->get_format(avctx, avctx->codec->pix_fmts); else - avctx->pix_fmt = PIX_FMT_GRAY8; - avctx->hwaccel = ff_find_hwaccel(avctx->codec->id, avctx->pix_fmt); + avctx->pix_fmt = AV_PIX_FMT_GRAY8; + avctx->hwaccel = ff_find_hwaccel(avctx); v->s.avctx = avctx; - avctx->flags |= CODEC_FLAG_EMU_EDGE; - v->s.flags |= CODEC_FLAG_EMU_EDGE; - - if (avctx->idct_algo == FF_IDCT_AUTO) { - avctx->idct_algo = FF_IDCT_WMV2; - } - if (vc1_init_common(v) < 0) + if (ff_vc1_init_common(v) < 0) return -1; + ff_h264chroma_init(&v->h264chroma, 8); ff_vc1dsp_init(&v->vc1dsp); - if (avctx->codec_id == CODEC_ID_WMV3 || avctx->codec_id == CODEC_ID_WMV3IMAGE) { + if (avctx->codec_id == AV_CODEC_ID_WMV3 || avctx->codec_id == AV_CODEC_ID_WMV3IMAGE) { int count = 0; // looks like WMV3 has a sequence header stored in the extradata @@ -5276,7 +5614,7 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx) init_get_bits(&gb, avctx->extradata, avctx->extradata_size*8); - if (vc1_decode_sequence_header(avctx, v, &gb) < 0) + if (ff_vc1_decode_sequence_header(avctx, v, &gb) < 0) return -1; count = avctx->extradata_size*8 - get_bits_count(&gb); @@ -5311,14 +5649,14 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx) init_get_bits(&gb, buf2, buf2_size * 8); switch (AV_RB32(start)) { case VC1_CODE_SEQHDR: - if (vc1_decode_sequence_header(avctx, v, &gb) < 0) { + if (ff_vc1_decode_sequence_header(avctx, v, &gb) < 0) { av_free(buf2); return -1; } seq_initialized = 1; break; case VC1_CODE_ENTRYPOINT: - if (vc1_decode_entry_point(avctx, v, &gb) < 0) { + if (ff_vc1_decode_entry_point(avctx, v, &gb) < 0) { av_free(buf2); return -1; } @@ -5331,36 +5669,31 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx) av_log(avctx, AV_LOG_ERROR, "Incomplete extradata\n"); return -1; } - v->res_sprite = (avctx->codec_tag == MKTAG('W','V','P','2')); + v->res_sprite = (avctx->codec_id == AV_CODEC_ID_VC1IMAGE); } + v->sprite_output_frame = av_frame_alloc(); + if (!v->sprite_output_frame) + return AVERROR(ENOMEM); + avctx->profile = v->profile; if (v->profile == PROFILE_ADVANCED) avctx->level = v->level; - avctx->has_b_frames = !!(avctx->max_b_frames); + avctx->has_b_frames = !!avctx->max_b_frames; s->mb_width = (avctx->coded_width + 15) >> 4; s->mb_height = (avctx->coded_height + 15) >> 4; if (v->profile == PROFILE_ADVANCED || v->res_fasttx) { - for (i = 0; i < 64; i++) { -#define transpose(x) ((x >> 3) | ((x & 7) << 3)) - v->zz_8x8[0][i] = transpose(wmv1_scantable[0][i]); - 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; + ff_vc1_init_transposed_scantables(v); } else { - memcpy(v->zz_8x8, wmv1_scantable, 4*64); + memcpy(v->zz_8x8, ff_wmv1_scantable, 4*64); v->left_blk_sh = 3; v->top_blk_sh = 0; } - if (avctx->codec_id == CODEC_ID_WMV3IMAGE || avctx->codec_id == CODEC_ID_VC1IMAGE) { + if (avctx->codec_id == AV_CODEC_ID_WMV3IMAGE || avctx->codec_id == AV_CODEC_ID_VC1IMAGE) { v->sprite_width = avctx->coded_width; v->sprite_height = avctx->coded_height; @@ -5379,19 +5712,18 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx) /** Close a VC1/WMV3 decoder * @warning Initial try at using MpegEncContext stuff */ -static av_cold int vc1_decode_end(AVCodecContext *avctx) +av_cold int ff_vc1_decode_end(AVCodecContext *avctx) { VC1Context *v = avctx->priv_data; int i; - if ((avctx->codec_id == CODEC_ID_WMV3IMAGE || avctx->codec_id == CODEC_ID_VC1IMAGE) - && v->sprite_output_frame.data[0]) - avctx->release_buffer(avctx, &v->sprite_output_frame); + av_frame_free(&v->sprite_output_frame); + for (i = 0; i < 4; i++) av_freep(&v->sr_rows[i >> 1][i & 1]); av_freep(&v->hrd_rate); av_freep(&v->hrd_buffer); - MPV_common_end(&v->s); + ff_MPV_common_end(&v->s); av_freep(&v->mv_type_mb_plane); av_freep(&v->direct_mb_plane); av_freep(&v->forward_mb_plane); @@ -5401,7 +5733,6 @@ static av_cold int vc1_decode_end(AVCodecContext *avctx) 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); @@ -5417,45 +5748,38 @@ static av_cold int vc1_decode_end(AVCodecContext *avctx) * @todo TODO: Handle VC-1 IDUs (Transport level?) */ static int vc1_decode_frame(AVCodecContext *avctx, void *data, - int *data_size, AVPacket *avpkt) + int *got_frame, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size, n_slices = 0, i; + int buf_size = avpkt->size, n_slices = 0, i, ret; VC1Context *v = avctx->priv_data; 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; int mby_start; - } *slices = NULL; + } *slices = NULL, *tmp; /* no supplementary picture */ if (buf_size == 0 || (buf_size == 4 && AV_RB32(buf) == VC1_CODE_ENDOFSEQ)) { /* special case for last picture */ if (s->low_delay == 0 && s->next_picture_ptr) { - *pict = *(AVFrame*)s->next_picture_ptr; + if ((ret = av_frame_ref(pict, &s->next_picture_ptr->f)) < 0) + return ret; s->next_picture_ptr = NULL; - *data_size = sizeof(AVFrame); + *got_frame = 1; } return 0; } - if (s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU) { - if (v->profile < PROFILE_ADVANCED) - avctx->pix_fmt = PIX_FMT_VDPAU_WMV3; - else - avctx->pix_fmt = PIX_FMT_VDPAU_VC1; - } - //for advanced profile we may need to parse and unescape data - if (avctx->codec_id == CODEC_ID_VC1 || avctx->codec_id == CODEC_ID_VC1IMAGE) { + if (avctx->codec_id == AV_CODEC_ID_VC1 || avctx->codec_id == AV_CODEC_ID_VC1IMAGE) { int buf_size2 = 0; buf2 = av_mallocz(buf_size + FF_INPUT_BUFFER_PADDING_SIZE); @@ -5470,16 +5794,16 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, if (size <= 0) continue; switch (AV_RB32(start)) { case VC1_CODE_FRAME: - if (avctx->hwaccel || - s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU) + if (avctx->hwaccel) 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) + tmp = av_realloc(slices, sizeof(*slices) * (n_slices+1)); + if (!tmp) goto err; + slices = tmp; slices[n_slices].buf = av_mallocz(buf_size + FF_INPUT_BUFFER_PADDING_SIZE); if (!slices[n_slices].buf) goto err; @@ -5492,21 +5816,19 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, 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); - vc1_decode_entry_point(avctx, v, &s->gb); + ff_vc1_decode_entry_point(avctx, v, &s->gb); break; case VC1_CODE_SLICE: { int buf_size3; - slices = av_realloc(slices, sizeof(*slices) * (n_slices+1)); - if (!slices) + tmp = av_realloc(slices, sizeof(*slices) * (n_slices+1)); + if (!tmp) goto err; + slices = tmp; slices[n_slices].buf = av_mallocz(buf_size + FF_INPUT_BUFFER_PADDING_SIZE); if (!slices[n_slices].buf) goto err; @@ -5522,14 +5844,26 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, } } else if (v->interlace && ((buf[0] & 0xC0) == 0xC0)) { /* WVC1 interlaced stores both fields divided by marker */ const uint8_t *divider; + int buf_size3; divider = find_next_marker(buf, buf + buf_size); 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); + tmp = av_realloc(slices, sizeof(*slices) * (n_slices+1)); + if (!tmp) + goto err; + slices = tmp; + 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(divider + 4, buf + buf_size - divider - 4, slices[n_slices].buf); + init_get_bits(&slices[n_slices].gb, slices[n_slices].buf, + buf_size3 << 3); + slices[n_slices].mby_start = s->mb_height >> 1; + n_slices1 = n_slices - 1; + n_slices++; } buf_size2 = vc1_unescape_buffer(buf, divider - buf, buf2); } else { @@ -5542,11 +5876,11 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, if (v->res_sprite) { v->new_sprite = !get_bits1(&s->gb); v->two_sprites = get_bits1(&s->gb); - /* res_sprite means a Windows Media Image stream, CODEC_ID_*IMAGE means + /* res_sprite means a Windows Media Image stream, AV_CODEC_ID_*IMAGE means we're using the sprite compositor. These are intentionally kept separate so you can get the raw sprites by using the wmv3 decoder for WMVP or the vc1 one for WVP2 */ - if (avctx->codec_id == CODEC_ID_WMV3IMAGE || avctx->codec_id == CODEC_ID_VC1IMAGE) { + if (avctx->codec_id == AV_CODEC_ID_WMV3IMAGE || avctx->codec_id == AV_CODEC_ID_VC1IMAGE) { if (v->new_sprite) { // switch AVCodecContext parameters to those of the sprites avctx->width = avctx->coded_width = v->sprite_width; @@ -5560,12 +5894,16 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, if (s->context_initialized && (s->width != avctx->coded_width || s->height != avctx->coded_height)) { - vc1_decode_end(avctx); + ff_vc1_decode_end(avctx); } if (!s->context_initialized) { - if (ff_msmpeg4_decode_init(avctx) < 0 || vc1_decode_init_alloc_tables(v) < 0) - return -1; + if (ff_msmpeg4_decode_init(avctx) < 0) + goto err; + if (ff_vc1_decode_init_alloc_tables(v) < 0) { + ff_MPV_common_end(s); + goto err; + } s->low_delay = !avctx->has_b_frames || v->res_sprite; @@ -5575,51 +5913,32 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, } } - /* We need to set current_picture_ptr before reading the header, - * otherwise we cannot store anything in there. */ - if (s->current_picture_ptr == NULL || s->current_picture_ptr->f.data[0]) { - int i = ff_find_unused_picture(s, 0); - if (i < 0) - goto err; - s->current_picture_ptr = &s->picture[i]; - } - // do parse frame header v->pic_header_flag = 0; + v->first_pic_header_flag = 1; if (v->profile < PROFILE_ADVANCED) { - if (vc1_parse_frame_header(v, &s->gb) == -1) { + if (ff_vc1_parse_frame_header(v, &s->gb) < 0) { goto err; } } else { - if (vc1_parse_frame_header_adv(v, &s->gb) == -1) { + if (ff_vc1_parse_frame_header_adv(v, &s->gb) < 0) { goto err; } } + v->first_pic_header_flag = 0; - if ((avctx->codec_id == CODEC_ID_WMV3IMAGE || avctx->codec_id == CODEC_ID_VC1IMAGE) + if ((avctx->codec_id == AV_CODEC_ID_WMV3IMAGE || avctx->codec_id == AV_CODEC_ID_VC1IMAGE) && s->pict_type != AV_PICTURE_TYPE_I) { av_log(v->s.avctx, AV_LOG_ERROR, "Sprite decoder: expected I-frame\n"); goto err; } - // process pulldown flags - s->current_picture_ptr->f.repeat_pict = 0; - // Pulldown flags are only valid when 'broadcast' has been set. - // So ticks_per_frame will be 2 - if (v->rff) { - // repeat field - s->current_picture_ptr->f.repeat_pict = 1; - } else if (v->rptfrm) { - // repeat frames - s->current_picture_ptr->f.repeat_pict = v->rptfrm * 2; - } - // for skipping the frame s->current_picture.f.pict_type = s->pict_type; s->current_picture.f.key_frame = s->pict_type == AV_PICTURE_TYPE_I; /* skip B-frames if we don't have reference frames */ - if (s->last_picture_ptr == NULL && (s->pict_type == AV_PICTURE_TYPE_B || s->dropable)) { + if (s->last_picture_ptr == NULL && (s->pict_type == AV_PICTURE_TYPE_B || s->droppable)) { goto err; } if ((avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type == AV_PICTURE_TYPE_B) || @@ -5635,17 +5954,26 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, s->next_p_frame_damaged = 0; } - if (MPV_frame_start(s, avctx) < 0) { + if (ff_MPV_frame_start(s, avctx) < 0) { goto err; } + // process pulldown flags + s->current_picture_ptr->f.repeat_pict = 0; + // Pulldown flags are only valid when 'broadcast' has been set. + // So ticks_per_frame will be 2 + if (v->rff) { + // repeat field + s->current_picture_ptr->f.repeat_pict = 1; + } else if (v->rptfrm) { + // repeat frames + s->current_picture_ptr->f.repeat_pict = v->rptfrm * 2; + } + s->me.qpel_put = s->dsp.put_qpel_pixels_tab; s->me.qpel_avg = s->dsp.avg_qpel_pixels_tab; - if ((CONFIG_VC1_VDPAU_DECODER) - &&s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU) - ff_vdpau_vc1_decode_picture(s, buf_start, (buf + buf_size) - buf_start); - else if (avctx->hwaccel) { + if (avctx->hwaccel) { if (avctx->hwaccel->start_frame(avctx, buf, buf_size) < 0) goto err; if (avctx->hwaccel->decode_slice(avctx, buf_start, (buf + buf_size) - buf_start) < 0) @@ -5653,28 +5981,34 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, if (avctx->hwaccel->end_frame(avctx) < 0) goto err; } else { - ff_er_frame_start(s); + int header_ret = 0; + + ff_mpeg_er_frame_start(s); v->bits = buf_size * 8; + v->end_mb_x = s->mb_width; 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; + + if (!mb_height) { + av_log(v->s.avctx, AV_LOG_ERROR, "Invalid mb_height.\n"); + goto err; + } + for (i = 0; i <= n_slices; i++) { if (i > 0 && slices[i - 1].mby_start >= mb_height) { + if (v->field_mode <= 0) { + av_log(v->s.avctx, AV_LOG_ERROR, "Slice %d starts beyond " + "picture boundary (%d >= %d)\n", i, + slices[i - 1].mby_start, mb_height); + continue; + } v->second_field = 1; v->blocks_off = s->mb_width * s->mb_height << 1; v->mb_off = s->mb_stride * s->mb_height >> 1; @@ -5685,46 +6019,57 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, } 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)) { + if (v->field_mode && i == n_slices1 + 2) { + if ((header_ret = ff_vc1_parse_frame_header_adv(v, &s->gb)) < 0) { + av_log(v->s.avctx, AV_LOG_ERROR, "Field header damaged\n"); + if (avctx->err_recognition & AV_EF_EXPLODE) + goto err; + continue; + } + } else if (get_bits1(&s->gb)) { v->pic_header_flag = 1; - vc1_parse_frame_header_adv(v, &s->gb); + if ((header_ret = ff_vc1_parse_frame_header_adv(v, &s->gb)) < 0) { + av_log(v->s.avctx, AV_LOG_ERROR, "Slice header damaged\n"); + if (avctx->err_recognition & AV_EF_EXPLODE) + goto err; + continue; + } } } + if (header_ret < 0) + continue; 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); + s->end_mb_y = (i <= n_slices1 + 1) ? mb_height : FFMIN(mb_height, slices[i].mby_start % mb_height); + ff_vc1_decode_blocks(v); 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; + if (v->s.pict_type != AV_PICTURE_TYPE_BI && v->s.pict_type != AV_PICTURE_TYPE_B) { + FFSWAP(uint8_t *, v->mv_f_next[0], v->mv_f[0]); + FFSWAP(uint8_t *, v->mv_f_next[1], v->mv_f[1]); + } } -//av_log(s->avctx, AV_LOG_INFO, "Consumed %i/%i bits\n", get_bits_count(&s->gb), s->gb.size_in_bits); + av_dlog(s->avctx, "Consumed %i/%i bits\n", + get_bits_count(&s->gb), s->gb.size_in_bits); // if (get_bits_count(&s->gb) > buf_size * 8) // return -1; - ff_er_frame_end(s); + if (!v->field_mode) + ff_er_frame_end(&s->er); } - MPV_frame_end(s); + ff_MPV_frame_end(s); - if (avctx->codec_id == CODEC_ID_WMV3IMAGE || avctx->codec_id == CODEC_ID_VC1IMAGE) { + if (avctx->codec_id == AV_CODEC_ID_WMV3IMAGE || avctx->codec_id == AV_CODEC_ID_VC1IMAGE) { image: avctx->width = avctx->coded_width = v->output_width; avctx->height = avctx->coded_height = v->output_height; @@ -5734,17 +6079,20 @@ image: if (vc1_decode_sprites(v, &s->gb)) goto err; #endif - *pict = v->sprite_output_frame; - *data_size = sizeof(AVFrame); + if ((ret = av_frame_ref(pict, v->sprite_output_frame)) < 0) + goto err; + *got_frame = 1; } else { if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) { - *pict = *(AVFrame*)s->current_picture_ptr; + if ((ret = av_frame_ref(pict, &s->current_picture_ptr->f)) < 0) + goto err; + ff_print_debug_info(s, s->current_picture_ptr); + *got_frame = 1; } else if (s->last_picture_ptr != NULL) { - *pict = *(AVFrame*)s->last_picture_ptr; - } - if (s->last_picture_ptr || s->low_delay) { - *data_size = sizeof(AVFrame); - ff_print_debug_info(s, pict); + if ((ret = av_frame_ref(pict, &s->last_picture_ptr->f)) < 0) + goto err; + ff_print_debug_info(s, s->last_picture_ptr); + *got_frame = 1; } } @@ -5760,7 +6108,6 @@ err: for (i = 0; i < n_slices; i++) av_free(slices[i].buf); av_free(slices); - av_free(buf_field2); return -1; } @@ -5773,64 +6120,48 @@ static const AVProfile profiles[] = { { FF_PROFILE_UNKNOWN }, }; +static const enum AVPixelFormat vc1_hwaccel_pixfmt_list_420[] = { +#if CONFIG_DXVA2 + AV_PIX_FMT_DXVA2_VLD, +#endif +#if CONFIG_VAAPI + AV_PIX_FMT_VAAPI_VLD, +#endif +#if CONFIG_VDPAU + AV_PIX_FMT_VDPAU, +#endif + AV_PIX_FMT_YUV420P, + AV_PIX_FMT_NONE +}; + AVCodec ff_vc1_decoder = { .name = "vc1", + .long_name = NULL_IF_CONFIG_SMALL("SMPTE VC-1"), .type = AVMEDIA_TYPE_VIDEO, - .id = CODEC_ID_VC1, + .id = AV_CODEC_ID_VC1, .priv_data_size = sizeof(VC1Context), .init = vc1_decode_init, - .close = vc1_decode_end, + .close = ff_vc1_decode_end, .decode = vc1_decode_frame, + .flush = ff_mpeg_flush, .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY, - .long_name = NULL_IF_CONFIG_SMALL("SMPTE VC-1"), - .pix_fmts = ff_hwaccel_pixfmt_list_420, + .pix_fmts = vc1_hwaccel_pixfmt_list_420, .profiles = NULL_IF_CONFIG_SMALL(profiles) }; #if CONFIG_WMV3_DECODER AVCodec ff_wmv3_decoder = { .name = "wmv3", - .type = AVMEDIA_TYPE_VIDEO, - .id = CODEC_ID_WMV3, - .priv_data_size = sizeof(VC1Context), - .init = vc1_decode_init, - .close = vc1_decode_end, - .decode = vc1_decode_frame, - .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY, .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9"), - .pix_fmts = ff_hwaccel_pixfmt_list_420, - .profiles = NULL_IF_CONFIG_SMALL(profiles) -}; -#endif - -#if CONFIG_WMV3_VDPAU_DECODER -AVCodec ff_wmv3_vdpau_decoder = { - .name = "wmv3_vdpau", .type = AVMEDIA_TYPE_VIDEO, - .id = CODEC_ID_WMV3, + .id = AV_CODEC_ID_WMV3, .priv_data_size = sizeof(VC1Context), .init = vc1_decode_init, - .close = vc1_decode_end, + .close = ff_vc1_decode_end, .decode = vc1_decode_frame, - .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_HWACCEL_VDPAU, - .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9 VDPAU"), - .pix_fmts = (const enum PixelFormat[]){PIX_FMT_VDPAU_WMV3, PIX_FMT_NONE}, - .profiles = NULL_IF_CONFIG_SMALL(profiles) -}; -#endif - -#if CONFIG_VC1_VDPAU_DECODER -AVCodec ff_vc1_vdpau_decoder = { - .name = "vc1_vdpau", - .type = AVMEDIA_TYPE_VIDEO, - .id = CODEC_ID_VC1, - .priv_data_size = sizeof(VC1Context), - .init = vc1_decode_init, - .close = vc1_decode_end, - .decode = vc1_decode_frame, - .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_HWACCEL_VDPAU, - .long_name = NULL_IF_CONFIG_SMALL("SMPTE VC-1 VDPAU"), - .pix_fmts = (const enum PixelFormat[]){PIX_FMT_VDPAU_VC1, PIX_FMT_NONE}, + .flush = ff_mpeg_flush, + .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY, + .pix_fmts = vc1_hwaccel_pixfmt_list_420, .profiles = NULL_IF_CONFIG_SMALL(profiles) }; #endif @@ -5838,15 +6169,15 @@ AVCodec ff_vc1_vdpau_decoder = { #if CONFIG_WMV3IMAGE_DECODER AVCodec ff_wmv3image_decoder = { .name = "wmv3image", + .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9 Image"), .type = AVMEDIA_TYPE_VIDEO, - .id = CODEC_ID_WMV3IMAGE, + .id = AV_CODEC_ID_WMV3IMAGE, .priv_data_size = sizeof(VC1Context), .init = vc1_decode_init, - .close = vc1_decode_end, + .close = ff_vc1_decode_end, .decode = vc1_decode_frame, .capabilities = CODEC_CAP_DR1, .flush = vc1_sprite_flush, - .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9 Image"), .pix_fmts = ff_pixfmt_list_420 }; #endif @@ -5854,15 +6185,15 @@ AVCodec ff_wmv3image_decoder = { #if CONFIG_VC1IMAGE_DECODER AVCodec ff_vc1image_decoder = { .name = "vc1image", + .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9 Image v2"), .type = AVMEDIA_TYPE_VIDEO, - .id = CODEC_ID_VC1IMAGE, + .id = AV_CODEC_ID_VC1IMAGE, .priv_data_size = sizeof(VC1Context), .init = vc1_decode_init, - .close = vc1_decode_end, + .close = ff_vc1_decode_end, .decode = vc1_decode_frame, .capabilities = CODEC_CAP_DR1, .flush = vc1_sprite_flush, - .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9 Image v2"), .pix_fmts = ff_pixfmt_list_420 }; #endif