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 <jerome.borsboom@carpalis.nl>
This commit is contained in:
Jerome Borsboom 2018-02-25 20:09:46 +01:00 committed by Mark Thompson
parent dd3f1e3a11
commit 1160d1d478
2 changed files with 55 additions and 46 deletions

View File

@ -629,7 +629,7 @@ int ff_vc1_parse_frame_header(VC1Context *v, GetBitContext* gb)
int pqindex, lowquant, status; int pqindex, lowquant, status;
v->field_mode = 0; v->field_mode = 0;
v->fcm = 0; v->fcm = PROGRESSIVE;
if (v->finterpflag) if (v->finterpflag)
v->interpfrm = get_bits1(gb); v->interpfrm = get_bits1(gb);
if (!v->s.avctx->codec) 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 */ /* Hopefully this is correct for P-frames */
v->s.mv_table_index = get_bits(gb, 2); //but using ff_vc1_ tables 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) { if (v->dquant) {
av_log(v->s.avctx, AV_LOG_DEBUG, "VOP DQuant info\n"); 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); "Imode: %i, Invert: %i\n", status>>1, status&1);
v->s.mv_table_index = get_bits(gb, 2); 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) { if (v->dquant) {
av_log(v->s.avctx, AV_LOG_DEBUG, "VOP DQuant info\n"); 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 pqindex, lowquant;
int status; int status;
int mbmodetab, imvtab, icbptab, twomvbptab, fourmvbptab; /* useful only for debugging */
int field_mode, fcm; int field_mode, fcm;
v->numref = 0; 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); status = bitplane_decoding(v->s.mbskip_table, &v->skip_is_raw, v);
av_log(v->s.avctx, AV_LOG_DEBUG, "SKIPMB plane encoding: " av_log(v->s.avctx, AV_LOG_DEBUG, "SKIPMB plane encoding: "
"Imode: %i, Invert: %i\n", status>>1, status&1); "Imode: %i, Invert: %i\n", status>>1, status&1);
mbmodetab = get_bits(gb, 2); v->mbmodetab = get_bits(gb, 2);
if (v->fourmvswitch) 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 else
v->mbmode_vlc = &ff_vc1_intfr_non4mv_mbmode_vlc[mbmodetab]; v->mbmode_vlc = &ff_vc1_intfr_non4mv_mbmode_vlc[v->mbmodetab];
imvtab = get_bits(gb, 2); v->imvtab = get_bits(gb, 2);
v->imv_vlc = &ff_vc1_1ref_mvdata_vlc[imvtab]; v->imv_vlc = &ff_vc1_1ref_mvdata_vlc[v->imvtab];
// interlaced p-picture cbpcy range is [1, 63] // interlaced p-picture cbpcy range is [1, 63]
icbptab = get_bits(gb, 3); v->icbptab = get_bits(gb, 3);
v->cbpcy_vlc = &ff_vc1_icbpcy_vlc[icbptab]; v->cbpcy_vlc = &ff_vc1_icbpcy_vlc[v->icbptab];
twomvbptab = get_bits(gb, 2); v->twomvbptab = get_bits(gb, 2);
v->twomvbp_vlc = &ff_vc1_2mv_block_pattern_vlc[twomvbptab]; v->twomvbp_vlc = &ff_vc1_2mv_block_pattern_vlc[v->twomvbptab];
if (v->fourmvswitch) { if (v->fourmvswitch) {
fourmvbptab = get_bits(gb, 2); v->fourmvbptab = get_bits(gb, 2);
v->fourmvbp_vlc = &ff_vc1_4mv_block_pattern_vlc[fourmvbptab]; 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 */ /* Hopefully this is correct for P-frames */
v->s.mv_table_index = get_bits(gb, 2); //but using ff_vc1_ tables 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 } else if (v->fcm == ILACE_FRAME) { // frame interlaced
v->qs_last = v->s.quarter_sample; v->qs_last = v->s.quarter_sample;
v->s.quarter_sample = 1; v->s.quarter_sample = 1;
v->s.mspel = 1; v->s.mspel = 1;
} else { // field interlaced } else { // field interlaced
mbmodetab = get_bits(gb, 3); v->mbmodetab = get_bits(gb, 3);
imvtab = get_bits(gb, 2 + v->numref); v->imvtab = get_bits(gb, 2 + v->numref);
if (!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 else
v->imv_vlc = &ff_vc1_2ref_mvdata_vlc[imvtab]; v->imv_vlc = &ff_vc1_2ref_mvdata_vlc[v->imvtab];
icbptab = get_bits(gb, 3); v->icbptab = get_bits(gb, 3);
v->cbpcy_vlc = &ff_vc1_icbpcy_vlc[icbptab]; v->cbpcy_vlc = &ff_vc1_icbpcy_vlc[v->icbptab];
if ((v->mv_mode == MV_PMODE_INTENSITY_COMP && if ((v->mv_mode == MV_PMODE_INTENSITY_COMP &&
v->mv_mode2 == MV_PMODE_MIXED_MV) || v->mv_mode == MV_PMODE_MIXED_MV) { v->mv_mode2 == MV_PMODE_MIXED_MV) || v->mv_mode == MV_PMODE_MIXED_MV) {
fourmvbptab = get_bits(gb, 2); v->fourmvbptab = get_bits(gb, 2);
v->fourmvbp_vlc = &ff_vc1_4mv_block_pattern_vlc[fourmvbptab]; v->fourmvbp_vlc = &ff_vc1_4mv_block_pattern_vlc[v->fourmvbptab];
v->mbmode_vlc = &ff_vc1_if_mmv_mbmode_vlc[mbmodetab]; v->mbmode_vlc = &ff_vc1_if_mmv_mbmode_vlc[v->mbmodetab];
} else { } 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) { if (v->dquant) {
@ -1228,18 +1230,18 @@ int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb)
return -1; return -1;
av_log(v->s.avctx, AV_LOG_DEBUG, "MB Forward Type plane encoding: " av_log(v->s.avctx, AV_LOG_DEBUG, "MB Forward Type plane encoding: "
"Imode: %i, Invert: %i\n", status>>1, status&1); "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) 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 else
v->mbmode_vlc = &ff_vc1_if_1mv_mbmode_vlc[mbmodetab]; v->mbmode_vlc = &ff_vc1_if_1mv_mbmode_vlc[v->mbmodetab];
imvtab = get_bits(gb, 3); v->imvtab = get_bits(gb, 3);
v->imv_vlc = &ff_vc1_2ref_mvdata_vlc[imvtab]; v->imv_vlc = &ff_vc1_2ref_mvdata_vlc[v->imvtab];
icbptab = get_bits(gb, 3); v->icbptab = get_bits(gb, 3);
v->cbpcy_vlc = &ff_vc1_icbpcy_vlc[icbptab]; v->cbpcy_vlc = &ff_vc1_icbpcy_vlc[v->icbptab];
if (v->mv_mode == MV_PMODE_MIXED_MV) { if (v->mv_mode == MV_PMODE_MIXED_MV) {
fourmvbptab = get_bits(gb, 2); v->fourmvbptab = get_bits(gb, 2);
v->fourmvbp_vlc = &ff_vc1_4mv_block_pattern_vlc[fourmvbptab]; v->fourmvbp_vlc = &ff_vc1_4mv_block_pattern_vlc[v->fourmvbptab];
} }
v->numref = 1; // interlaced field B pictures are always 2-ref v->numref = 1; // interlaced field B pictures are always 2-ref
} else if (v->fcm == ILACE_FRAME) { } else if (v->fcm == ILACE_FRAME) {
@ -1263,17 +1265,17 @@ int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb)
return -1; return -1;
av_log(v->s.avctx, AV_LOG_DEBUG, "MB Skip plane encoding: " av_log(v->s.avctx, AV_LOG_DEBUG, "MB Skip plane encoding: "
"Imode: %i, Invert: %i\n", status>>1, status&1); "Imode: %i, Invert: %i\n", status>>1, status&1);
mbmodetab = get_bits(gb, 2); v->mbmodetab = get_bits(gb, 2);
v->mbmode_vlc = &ff_vc1_intfr_non4mv_mbmode_vlc[mbmodetab]; v->mbmode_vlc = &ff_vc1_intfr_non4mv_mbmode_vlc[v->mbmodetab];
imvtab = get_bits(gb, 2); v->imvtab = get_bits(gb, 2);
v->imv_vlc = &ff_vc1_1ref_mvdata_vlc[imvtab]; v->imv_vlc = &ff_vc1_1ref_mvdata_vlc[v->imvtab];
// interlaced p/b-picture cbpcy range is [1, 63] // interlaced p/b-picture cbpcy range is [1, 63]
icbptab = get_bits(gb, 3); v->icbptab = get_bits(gb, 3);
v->cbpcy_vlc = &ff_vc1_icbpcy_vlc[icbptab]; v->cbpcy_vlc = &ff_vc1_icbpcy_vlc[v->icbptab];
twomvbptab = get_bits(gb, 2); v->twomvbptab = get_bits(gb, 2);
v->twomvbp_vlc = &ff_vc1_2mv_block_pattern_vlc[twomvbptab]; v->twomvbp_vlc = &ff_vc1_2mv_block_pattern_vlc[v->twomvbptab];
fourmvbptab = get_bits(gb, 2); v->fourmvbptab = get_bits(gb, 2);
v->fourmvbp_vlc = &ff_vc1_4mv_block_pattern_vlc[fourmvbptab]; v->fourmvbp_vlc = &ff_vc1_4mv_block_pattern_vlc[v->fourmvbptab];
} else { } else {
v->mv_mode = get_bits1(gb) ? MV_PMODE_1MV : MV_PMODE_1MV_HPEL_BILIN; v->mv_mode = get_bits1(gb) ? MV_PMODE_1MV : MV_PMODE_1MV_HPEL_BILIN;
v->qs_last = v->s.quarter_sample; 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: " av_log(v->s.avctx, AV_LOG_DEBUG, "MB Skip plane encoding: "
"Imode: %i, Invert: %i\n", status>>1, status&1); "Imode: %i, Invert: %i\n", status>>1, status&1);
v->s.mv_table_index = get_bits(gb, 2); 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) { if (v->dquant) {

View File

@ -296,6 +296,7 @@ typedef struct VC1Context{
uint8_t (*curr_luty)[256] ,(*curr_lutuv)[256]; uint8_t (*curr_luty)[256] ,(*curr_lutuv)[256];
int last_use_ic, *curr_use_ic, next_use_ic, aux_use_ic; int last_use_ic, *curr_use_ic, next_use_ic, aux_use_ic;
int rnd; ///< rounding control int rnd; ///< rounding control
int cbptab;
/** Frame decoding info for S/M profiles only */ /** 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 frfd, brfd; ///< reference frame distance (forward or backward)
int first_pic_header_flag; int first_pic_header_flag;
int pic_header_flag; int pic_header_flag;
int mbmodetab;
int icbptab;
int imvtab;
int twomvbptab;
int fourmvbptab;
/** Frame decoding info for sprite modes */ /** Frame decoding info for sprite modes */
//@{ //@{