From 1160d1d47887353c5afa4f5e8a18b56bd775501e Mon Sep 17 00:00:00 2001 From: Jerome Borsboom Date: Sun, 25 Feb 2018 20:09:46 +0100 Subject: [PATCH] avcodec/vc1: add bitstream elements for VAAPI VC-1 interlaced decoding We need to pass more bitstream elements to the VAAPI VC-1 decoder in order to start doing interlaced decoding in hardware. Signed-off-by: Jerome Borsboom --- libavcodec/vc1.c | 95 +++++++++++++++++++++++++----------------------- libavcodec/vc1.h | 6 +++ 2 files changed, 55 insertions(+), 46 deletions(-) diff --git a/libavcodec/vc1.c b/libavcodec/vc1.c index 48a2cc1e48..2b9f8db3ee 100644 --- a/libavcodec/vc1.c +++ b/libavcodec/vc1.c @@ -629,7 +629,7 @@ int ff_vc1_parse_frame_header(VC1Context *v, GetBitContext* gb) int pqindex, lowquant, status; v->field_mode = 0; - v->fcm = 0; + v->fcm = PROGRESSIVE; if (v->finterpflag) v->interpfrm = get_bits1(gb); if (!v->s.avctx->codec) @@ -766,7 +766,8 @@ int ff_vc1_parse_frame_header(VC1Context *v, GetBitContext* gb) /* Hopefully this is correct for P-frames */ v->s.mv_table_index = get_bits(gb, 2); //but using ff_vc1_ tables - v->cbpcy_vlc = &ff_vc1_cbpcy_p_vlc[get_bits(gb, 2)]; + v->cbptab = get_bits(gb, 2); + v->cbpcy_vlc = &ff_vc1_cbpcy_p_vlc[v->cbptab]; if (v->dquant) { av_log(v->s.avctx, AV_LOG_DEBUG, "VOP DQuant info\n"); @@ -804,7 +805,8 @@ int ff_vc1_parse_frame_header(VC1Context *v, GetBitContext* gb) "Imode: %i, Invert: %i\n", status>>1, status&1); v->s.mv_table_index = get_bits(gb, 2); - v->cbpcy_vlc = &ff_vc1_cbpcy_p_vlc[get_bits(gb, 2)]; + v->cbptab = get_bits(gb, 2); + v->cbpcy_vlc = &ff_vc1_cbpcy_p_vlc[v->cbptab]; if (v->dquant) { av_log(v->s.avctx, AV_LOG_DEBUG, "VOP DQuant info\n"); @@ -845,7 +847,6 @@ int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) { int pqindex, lowquant; int status; - int mbmodetab, imvtab, icbptab, twomvbptab, fourmvbptab; /* useful only for debugging */ int field_mode, fcm; v->numref = 0; @@ -1056,21 +1057,21 @@ int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) status = bitplane_decoding(v->s.mbskip_table, &v->skip_is_raw, v); av_log(v->s.avctx, AV_LOG_DEBUG, "SKIPMB plane encoding: " "Imode: %i, Invert: %i\n", status>>1, status&1); - mbmodetab = get_bits(gb, 2); + v->mbmodetab = get_bits(gb, 2); if (v->fourmvswitch) - v->mbmode_vlc = &ff_vc1_intfr_4mv_mbmode_vlc[mbmodetab]; + v->mbmode_vlc = &ff_vc1_intfr_4mv_mbmode_vlc[v->mbmodetab]; else - v->mbmode_vlc = &ff_vc1_intfr_non4mv_mbmode_vlc[mbmodetab]; - imvtab = get_bits(gb, 2); - v->imv_vlc = &ff_vc1_1ref_mvdata_vlc[imvtab]; + v->mbmode_vlc = &ff_vc1_intfr_non4mv_mbmode_vlc[v->mbmodetab]; + v->imvtab = get_bits(gb, 2); + v->imv_vlc = &ff_vc1_1ref_mvdata_vlc[v->imvtab]; // interlaced p-picture cbpcy range is [1, 63] - icbptab = get_bits(gb, 3); - v->cbpcy_vlc = &ff_vc1_icbpcy_vlc[icbptab]; - twomvbptab = get_bits(gb, 2); - v->twomvbp_vlc = &ff_vc1_2mv_block_pattern_vlc[twomvbptab]; + v->icbptab = get_bits(gb, 3); + v->cbpcy_vlc = &ff_vc1_icbpcy_vlc[v->icbptab]; + v->twomvbptab = get_bits(gb, 2); + v->twomvbp_vlc = &ff_vc1_2mv_block_pattern_vlc[v->twomvbptab]; if (v->fourmvswitch) { - fourmvbptab = get_bits(gb, 2); - v->fourmvbp_vlc = &ff_vc1_4mv_block_pattern_vlc[fourmvbptab]; + v->fourmvbptab = get_bits(gb, 2); + v->fourmvbp_vlc = &ff_vc1_4mv_block_pattern_vlc[v->fourmvbptab]; } } } @@ -1154,27 +1155,28 @@ int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) /* Hopefully this is correct for P-frames */ v->s.mv_table_index = get_bits(gb, 2); //but using ff_vc1_ tables - v->cbpcy_vlc = &ff_vc1_cbpcy_p_vlc[get_bits(gb, 2)]; + v->cbptab = get_bits(gb, 2); + v->cbpcy_vlc = &ff_vc1_cbpcy_p_vlc[v->cbptab]; } else if (v->fcm == ILACE_FRAME) { // frame interlaced v->qs_last = v->s.quarter_sample; v->s.quarter_sample = 1; v->s.mspel = 1; } else { // field interlaced - mbmodetab = get_bits(gb, 3); - imvtab = get_bits(gb, 2 + v->numref); + v->mbmodetab = get_bits(gb, 3); + v->imvtab = get_bits(gb, 2 + v->numref); if (!v->numref) - v->imv_vlc = &ff_vc1_1ref_mvdata_vlc[imvtab]; + v->imv_vlc = &ff_vc1_1ref_mvdata_vlc[v->imvtab]; else - v->imv_vlc = &ff_vc1_2ref_mvdata_vlc[imvtab]; - icbptab = get_bits(gb, 3); - v->cbpcy_vlc = &ff_vc1_icbpcy_vlc[icbptab]; + v->imv_vlc = &ff_vc1_2ref_mvdata_vlc[v->imvtab]; + v->icbptab = get_bits(gb, 3); + v->cbpcy_vlc = &ff_vc1_icbpcy_vlc[v->icbptab]; if ((v->mv_mode == MV_PMODE_INTENSITY_COMP && v->mv_mode2 == MV_PMODE_MIXED_MV) || v->mv_mode == MV_PMODE_MIXED_MV) { - fourmvbptab = get_bits(gb, 2); - v->fourmvbp_vlc = &ff_vc1_4mv_block_pattern_vlc[fourmvbptab]; - v->mbmode_vlc = &ff_vc1_if_mmv_mbmode_vlc[mbmodetab]; + v->fourmvbptab = get_bits(gb, 2); + v->fourmvbp_vlc = &ff_vc1_4mv_block_pattern_vlc[v->fourmvbptab]; + v->mbmode_vlc = &ff_vc1_if_mmv_mbmode_vlc[v->mbmodetab]; } else { - v->mbmode_vlc = &ff_vc1_if_1mv_mbmode_vlc[mbmodetab]; + v->mbmode_vlc = &ff_vc1_if_1mv_mbmode_vlc[v->mbmodetab]; } } if (v->dquant) { @@ -1228,18 +1230,18 @@ int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) return -1; av_log(v->s.avctx, AV_LOG_DEBUG, "MB Forward Type plane encoding: " "Imode: %i, Invert: %i\n", status>>1, status&1); - mbmodetab = get_bits(gb, 3); + v->mbmodetab = get_bits(gb, 3); if (v->mv_mode == MV_PMODE_MIXED_MV) - v->mbmode_vlc = &ff_vc1_if_mmv_mbmode_vlc[mbmodetab]; + v->mbmode_vlc = &ff_vc1_if_mmv_mbmode_vlc[v->mbmodetab]; else - v->mbmode_vlc = &ff_vc1_if_1mv_mbmode_vlc[mbmodetab]; - imvtab = get_bits(gb, 3); - v->imv_vlc = &ff_vc1_2ref_mvdata_vlc[imvtab]; - icbptab = get_bits(gb, 3); - v->cbpcy_vlc = &ff_vc1_icbpcy_vlc[icbptab]; + v->mbmode_vlc = &ff_vc1_if_1mv_mbmode_vlc[v->mbmodetab]; + v->imvtab = get_bits(gb, 3); + v->imv_vlc = &ff_vc1_2ref_mvdata_vlc[v->imvtab]; + v->icbptab = get_bits(gb, 3); + v->cbpcy_vlc = &ff_vc1_icbpcy_vlc[v->icbptab]; if (v->mv_mode == MV_PMODE_MIXED_MV) { - fourmvbptab = get_bits(gb, 2); - v->fourmvbp_vlc = &ff_vc1_4mv_block_pattern_vlc[fourmvbptab]; + v->fourmvbptab = get_bits(gb, 2); + v->fourmvbp_vlc = &ff_vc1_4mv_block_pattern_vlc[v->fourmvbptab]; } v->numref = 1; // interlaced field B pictures are always 2-ref } else if (v->fcm == ILACE_FRAME) { @@ -1263,17 +1265,17 @@ int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) return -1; av_log(v->s.avctx, AV_LOG_DEBUG, "MB Skip plane encoding: " "Imode: %i, Invert: %i\n", status>>1, status&1); - mbmodetab = get_bits(gb, 2); - v->mbmode_vlc = &ff_vc1_intfr_non4mv_mbmode_vlc[mbmodetab]; - imvtab = get_bits(gb, 2); - v->imv_vlc = &ff_vc1_1ref_mvdata_vlc[imvtab]; + v->mbmodetab = get_bits(gb, 2); + v->mbmode_vlc = &ff_vc1_intfr_non4mv_mbmode_vlc[v->mbmodetab]; + v->imvtab = get_bits(gb, 2); + v->imv_vlc = &ff_vc1_1ref_mvdata_vlc[v->imvtab]; // interlaced p/b-picture cbpcy range is [1, 63] - icbptab = get_bits(gb, 3); - v->cbpcy_vlc = &ff_vc1_icbpcy_vlc[icbptab]; - twomvbptab = get_bits(gb, 2); - v->twomvbp_vlc = &ff_vc1_2mv_block_pattern_vlc[twomvbptab]; - fourmvbptab = get_bits(gb, 2); - v->fourmvbp_vlc = &ff_vc1_4mv_block_pattern_vlc[fourmvbptab]; + v->icbptab = get_bits(gb, 3); + v->cbpcy_vlc = &ff_vc1_icbpcy_vlc[v->icbptab]; + v->twomvbptab = get_bits(gb, 2); + v->twomvbp_vlc = &ff_vc1_2mv_block_pattern_vlc[v->twomvbptab]; + v->fourmvbptab = get_bits(gb, 2); + v->fourmvbp_vlc = &ff_vc1_4mv_block_pattern_vlc[v->fourmvbptab]; } else { v->mv_mode = get_bits1(gb) ? MV_PMODE_1MV : MV_PMODE_1MV_HPEL_BILIN; v->qs_last = v->s.quarter_sample; @@ -1290,7 +1292,8 @@ int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) av_log(v->s.avctx, AV_LOG_DEBUG, "MB Skip plane encoding: " "Imode: %i, Invert: %i\n", status>>1, status&1); v->s.mv_table_index = get_bits(gb, 2); - v->cbpcy_vlc = &ff_vc1_cbpcy_p_vlc[get_bits(gb, 2)]; + v->cbptab = get_bits(gb, 2); + v->cbpcy_vlc = &ff_vc1_cbpcy_p_vlc[v->cbptab]; } if (v->dquant) { diff --git a/libavcodec/vc1.h b/libavcodec/vc1.h index 556906d496..8fc0729cb8 100644 --- a/libavcodec/vc1.h +++ b/libavcodec/vc1.h @@ -296,6 +296,7 @@ typedef struct VC1Context{ uint8_t (*curr_luty)[256] ,(*curr_lutuv)[256]; int last_use_ic, *curr_use_ic, next_use_ic, aux_use_ic; int rnd; ///< rounding control + int cbptab; /** Frame decoding info for S/M profiles only */ //@{ @@ -367,6 +368,11 @@ typedef struct VC1Context{ int frfd, brfd; ///< reference frame distance (forward or backward) int first_pic_header_flag; int pic_header_flag; + int mbmodetab; + int icbptab; + int imvtab; + int twomvbptab; + int fourmvbptab; /** Frame decoding info for sprite modes */ //@{