vc1dec: interlaced stream decoding support 3/3

Cosmetics: break some lines and reformat TODOs

Signed-off-by: Anton Khirnov <anton@khirnov.net>
This commit is contained in:
Mashiat Sarker Shakkhar 2011-10-07 00:00:26 +05:00 committed by Anton Khirnov
parent f0c02e1cbc
commit cad16562c8
3 changed files with 2236 additions and 419 deletions

View File

@ -1,5 +1,6 @@
/*
* VC-1 and WMV3 decoder common code
* Copyright (c) 2011 Mashiat Sarker Shakkhar
* Copyright (c) 2006-2007 Konstantin Shishkov
* Partly based on vc9.c (c) 2005 Anonymous, Alex Beregszaszi, Michael Niedermayer
*
@ -116,7 +117,7 @@ static int bitplane_decoding(uint8_t* data, int *raw_flag, VC1Context *v)
int width, height, stride;
width = v->s.mb_width;
height = v->s.mb_height;
height = v->s.mb_height >> v->field_mode;
stride = v->s.mb_stride;
invert = get_bits1(gb);
imode = get_vlc2(gb, ff_vc1_imode_vlc.table, VC1_IMODE_VLC_BITS, 1);
@ -682,6 +683,7 @@ int vc1_parse_frame_header(VC1Context *v, GetBitContext* gb)
v->lutuv[i] = av_clip_uint8((scale * (i - 128) + 128*64 + 32) >> 6);
}
}
v->qs_last = v->s.quarter_sample;
if(v->mv_mode == MV_PMODE_1MV_HPEL || v->mv_mode == MV_PMODE_1MV_HPEL_BILIN)
v->s.quarter_sample = 0;
else if(v->mv_mode == MV_PMODE_INTENSITY_COMP) {
@ -739,6 +741,7 @@ int vc1_parse_frame_header(VC1Context *v, GetBitContext* gb)
else v->tt_index = 2;
v->mv_mode = get_bits1(gb) ? MV_PMODE_1MV : MV_PMODE_1MV_HPEL_BILIN;
v->qs_last = v->s.quarter_sample;
v->s.quarter_sample = (v->mv_mode == MV_PMODE_1MV);
v->s.mspel = v->s.quarter_sample;
@ -794,21 +797,60 @@ int vc1_parse_frame_header(VC1Context *v, GetBitContext* gb)
return 0;
}
/* fill lookup tables for intensity compensation */
#define INIT_LUT(lumscale, lumshift, luty, lutuv) \
if (!lumscale) { \
scale = -64; \
shift = (255 - lumshift * 2) << 6; \
if (lumshift > 31) \
shift += 128 << 6; \
} else { \
scale = lumscale + 32; \
if (lumshift > 31) \
shift = (lumshift - 64) << 6; \
else \
shift = lumshift << 6; \
} \
for (i = 0; i < 256; i++) { \
luty[i] = av_clip_uint8((scale * i + shift + 32) >> 6); \
lutuv[i] = av_clip_uint8((scale * (i - 128) + 128*64 + 32) >> 6); \
}
int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb)
{
int pqindex, lowquant;
int status;
int mbmodetab, imvtab, icbptab, twomvbptab, fourmvbptab; /* useful only for debugging */
int scale, shift, i; /* for initializing LUT for intensity compensation */
v->p_frame_skipped = 0;
if (v->second_field) {
v->s.pict_type = (v->fptype & 1) ? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I;
if (v->fptype & 4)
v->s.pict_type = (v->fptype & 1) ? AV_PICTURE_TYPE_BI : AV_PICTURE_TYPE_B;
v->s.current_picture_ptr->f.pict_type = v->s.pict_type;
if (!v->pic_header_flag)
goto parse_common_info;
}
if(v->interlace){
v->fcm = decode012(gb);
if(v->fcm){
if(!v->warn_interlaced++)
av_log(v->s.avctx, AV_LOG_ERROR, "Interlaced frames/fields support is not implemented\n");
return -1;
if (v->fcm == 2)
v->field_mode = 1;
else
v->field_mode = 0;
if (!v->warn_interlaced++)
av_log(v->s.avctx, AV_LOG_ERROR, "Interlaced frames/fields support is incomplete\n");
}
}
if (v->field_mode) {
v->fptype = get_bits(gb, 3);
v->s.pict_type = (v->fptype & 2) ? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I;
if (v->fptype & 4) // B-picture
v->s.pict_type = (v->fptype & 2) ? AV_PICTURE_TYPE_BI : AV_PICTURE_TYPE_B;
} else {
switch(get_unary(gb, 0, 4)) {
case 0:
v->s.pict_type = AV_PICTURE_TYPE_P;
@ -827,6 +869,7 @@ int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb)
v->p_frame_skipped = 1;
break;
}
}
if(v->tfcntrflag)
skip_bits(gb, 8);
if(v->broadcast) {
@ -847,6 +890,26 @@ int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb)
v->rnd = get_bits1(gb);
if(v->interlace)
v->uvsamp = get_bits1(gb);
if (v->field_mode) {
if (!v->refdist_flag)
v->refdist = 0;
else {
if ((v->s.pict_type != AV_PICTURE_TYPE_B)
&& (v->s.pict_type != AV_PICTURE_TYPE_BI)) {
v->refdist = get_bits(gb, 2);
if (v->refdist == 3)
v->refdist += get_unary(gb, 0, 16);
} else {
v->bfraction_lut_index = get_vlc2(gb, ff_vc1_bfraction_vlc.table, VC1_BFRACTION_VLC_BITS, 1);
v->bfraction = ff_vc1_bfraction_lut[v->bfraction_lut_index];
v->frfd = (v->bfraction * v->refdist) >> 8;
v->brfd = v->refdist - v->frfd - 1;
if (v->brfd < 0)
v->brfd = 0;
}
}
goto parse_common_info;
}
if(v->finterpflag) v->interpfrm = get_bits1(gb);
if(v->s.pict_type == AV_PICTURE_TYPE_B) {
v->bfraction_lut_index = get_vlc2(gb, ff_vc1_bfraction_vlc.table, VC1_BFRACTION_VLC_BITS, 1);
@ -855,6 +918,10 @@ int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb)
v->s.pict_type = AV_PICTURE_TYPE_BI; /* XXX: should not happen here */
}
}
parse_common_info:
if (v->field_mode)
v->cur_field_type = !(v->tff ^ v->second_field);
pqindex = get_bits(gb, 5);
if(!pqindex) return -1;
v->pqindex = pqindex;
@ -869,23 +936,34 @@ int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb)
if (v->quantizer_mode == QUANT_NON_UNIFORM)
v->pquantizer = 0;
v->pqindex = pqindex;
if (pqindex < 9) v->halfpq = get_bits1(gb);
else v->halfpq = 0;
if (pqindex < 9)
v->halfpq = get_bits1(gb);
else
v->halfpq = 0;
if (v->quantizer_mode == QUANT_FRAME_EXPLICIT)
v->pquantizer = get_bits1(gb);
if(v->postprocflag)
v->postproc = get_bits(gb, 2);
if(v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_P) v->use_ic = 0;
if(v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_P)
v->use_ic = 0;
if(v->parse_only)
if (v->parse_only)
return 0;
switch(v->s.pict_type) {
case AV_PICTURE_TYPE_I:
case AV_PICTURE_TYPE_BI:
if (v->fcm == 1) { //interlace frame picture
status = bitplane_decoding(v->fieldtx_plane, &v->fieldtx_is_raw, v);
if (status < 0)
return -1;
av_log(v->s.avctx, AV_LOG_DEBUG, "FIELDTX plane encoding: "
"Imode: %i, Invert: %i\n", status>>1, status&1);
}
status = bitplane_decoding(v->acpred_plane, &v->acpred_is_raw, v);
if (status < 0) return -1;
if (status < 0)
return -1;
av_log(v->s.avctx, AV_LOG_DEBUG, "ACPRED plane encoding: "
"Imode: %i, Invert: %i\n", status>>1, status&1);
v->condover = CONDOVER_NONE;
@ -893,51 +971,92 @@ int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb)
v->condover = decode012(gb);
if(v->condover == CONDOVER_SELECT) {
status = bitplane_decoding(v->over_flags_plane, &v->overflg_is_raw, v);
if (status < 0) return -1;
if (status < 0)
return -1;
av_log(v->s.avctx, AV_LOG_DEBUG, "CONDOVER plane encoding: "
"Imode: %i, Invert: %i\n", status>>1, status&1);
}
}
break;
case AV_PICTURE_TYPE_P:
if (v->extended_mv) v->mvrange = get_unary(gb, 0, 3);
else v->mvrange = 0;
if (v->field_mode) {
v->numref = get_bits1(gb);
if (!v->numref) {
v->reffield = get_bits1(gb);
v->ref_field_type[0] = v->reffield ^ !v->cur_field_type;
}
}
if (v->extended_mv)
v->mvrange = get_unary(gb, 0, 3);
else
v->mvrange = 0;
if (v->interlace) {
if (v->extended_dmv)
v->dmvrange = get_unary(gb, 0, 3);
else
v->dmvrange = 0;
if (v->fcm == 1) { // interlaced frame picture
v->fourmvswitch = get_bits1(gb);
v->intcomp = get_bits1(gb);
if (v->intcomp) {
v->lumscale = get_bits(gb, 6);
v->lumshift = get_bits(gb, 6);
INIT_LUT(v->lumscale, v->lumshift, v->luty, v->lutuv);
}
status = bitplane_decoding(v->s.mbskip_table, &v->skip_is_raw, v);
av_log(v->s.avctx, AV_LOG_DEBUG, "SKIPMB plane encoding: "
"Imode: %i, Invert: %i\n", status>>1, status&1);
mbmodetab = get_bits(gb, 2);
if (v->fourmvswitch)
v->mbmode_vlc = &ff_vc1_intfr_4mv_mbmode_vlc[mbmodetab];
else
v->mbmode_vlc = &ff_vc1_intfr_non4mv_mbmode_vlc[mbmodetab];
imvtab = get_bits(gb, 2);
v->imv_vlc = &ff_vc1_1ref_mvdata_vlc[imvtab];
// interlaced p-picture cbpcy range is [1, 63]
icbptab = get_bits(gb, 3);
v->cbpcy_vlc = &ff_vc1_icbpcy_vlc[icbptab];
twomvbptab = get_bits(gb, 2);
v->twomvbp_vlc = &ff_vc1_2mv_block_pattern_vlc[twomvbptab];
if (v->fourmvswitch) {
fourmvbptab = get_bits(gb, 2);
v->fourmvbp_vlc = &ff_vc1_4mv_block_pattern_vlc[fourmvbptab];
}
}
}
v->k_x = v->mvrange + 9 + (v->mvrange >> 1); //k_x can be 9 10 12 13
v->k_y = v->mvrange + 8; //k_y can be 8 9 10 11
v->range_x = 1 << (v->k_x - 1);
v->range_y = 1 << (v->k_y - 1);
if (v->pq < 5) v->tt_index = 0;
else if(v->pq < 13) v->tt_index = 1;
else v->tt_index = 2;
if (v->pq < 5)
v->tt_index = 0;
else if(v->pq < 13)
v->tt_index = 1;
else
v->tt_index = 2;
if (v->fcm != 1) {
int mvmode;
mvmode = get_unary(gb, 1, 4);
lowquant = (v->pq > 12) ? 0 : 1;
v->mv_mode = ff_vc1_mv_pmode_table[lowquant][get_unary(gb, 1, 4)];
if (v->mv_mode == MV_PMODE_INTENSITY_COMP)
{
int scale, shift, i;
v->mv_mode2 = ff_vc1_mv_pmode_table2[lowquant][get_unary(gb, 1, 3)];
v->mv_mode = ff_vc1_mv_pmode_table[lowquant][mvmode];
if (v->mv_mode == MV_PMODE_INTENSITY_COMP) {
int mvmode2;
mvmode2 = get_unary(gb, 1, 3);
v->mv_mode2 = ff_vc1_mv_pmode_table2[lowquant][mvmode2];
if (v->field_mode)
v->intcompfield = decode210(gb);
v->lumscale = get_bits(gb, 6);
v->lumshift = get_bits(gb, 6);
/* fill lookup tables for intensity compensation */
if(!v->lumscale) {
scale = -64;
shift = (255 - v->lumshift * 2) << 6;
if(v->lumshift > 31)
shift += 128 << 6;
} else {
scale = v->lumscale + 32;
if(v->lumshift > 31)
shift = (v->lumshift - 64) << 6;
else
shift = v->lumshift << 6;
}
for(i = 0; i < 256; i++) {
v->luty[i] = av_clip_uint8((scale * i + shift + 32) >> 6);
v->lutuv[i] = av_clip_uint8((scale * (i - 128) + 128*64 + 32) >> 6);
INIT_LUT(v->lumscale, v->lumshift, v->luty, v->lutuv);
if ((v->field_mode) && !v->intcompfield) {
v->lumscale2 = get_bits(gb, 6);
v->lumshift2 = get_bits(gb, 6);
INIT_LUT(v->lumscale2, v->lumshift2, v->luty2, v->lutuv2);
}
v->use_ic = 1;
}
v->qs_last = v->s.quarter_sample;
if(v->mv_mode == MV_PMODE_1MV_HPEL || v->mv_mode == MV_PMODE_1MV_HPEL_BILIN)
v->s.quarter_sample = 0;
else if(v->mv_mode == MV_PMODE_INTENSITY_COMP) {
@ -948,13 +1067,15 @@ int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb)
} else
v->s.quarter_sample = 1;
v->s.mspel = !(v->mv_mode == MV_PMODE_1MV_HPEL_BILIN || (v->mv_mode == MV_PMODE_INTENSITY_COMP && v->mv_mode2 == MV_PMODE_1MV_HPEL_BILIN));
}
if (v->fcm == 0) { // progressive
if ((v->mv_mode == MV_PMODE_INTENSITY_COMP &&
v->mv_mode2 == MV_PMODE_MIXED_MV)
|| v->mv_mode == MV_PMODE_MIXED_MV)
{
status = bitplane_decoding(v->mv_type_mb_plane, &v->mv_type_is_raw, v);
if (status < 0) return -1;
if (status < 0)
return -1;
av_log(v->s.avctx, AV_LOG_DEBUG, "MB MV Type plane encoding: "
"Imode: %i, Invert: %i\n", status>>1, status&1);
} else {
@ -962,13 +1083,36 @@ int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb)
memset(v->mv_type_mb_plane, 0, v->s.mb_stride * v->s.mb_height);
}
status = bitplane_decoding(v->s.mbskip_table, &v->skip_is_raw, v);
if (status < 0) return -1;
if (status < 0)
return -1;
av_log(v->s.avctx, AV_LOG_DEBUG, "MB Skip plane encoding: "
"Imode: %i, Invert: %i\n", status>>1, status&1);
/* Hopefully this is correct for P frames */
v->s.mv_table_index = get_bits(gb, 2); //but using ff_vc1_ tables
v->cbpcy_vlc = &ff_vc1_cbpcy_p_vlc[get_bits(gb, 2)];
} else if (v->fcm == 1) { // frame interlaced
v->qs_last = v->s.quarter_sample;
v->s.quarter_sample = 1;
v->s.mspel = 1;
} else { // field interlaced
mbmodetab = get_bits(gb, 3);
imvtab = get_bits(gb, 2 + v->numref);
if (!v->numref)
v->imv_vlc = &ff_vc1_1ref_mvdata_vlc[imvtab];
else
v->imv_vlc = &ff_vc1_2ref_mvdata_vlc[imvtab];
icbptab = get_bits(gb, 3);
v->cbpcy_vlc = &ff_vc1_icbpcy_vlc[icbptab];
if ((v->mv_mode == MV_PMODE_INTENSITY_COMP &&
v->mv_mode2 == MV_PMODE_MIXED_MV) || v->mv_mode == MV_PMODE_MIXED_MV) {
fourmvbptab = get_bits(gb, 2);
v->fourmvbp_vlc = &ff_vc1_4mv_block_pattern_vlc[fourmvbptab];
v->mbmode_vlc = &ff_vc1_if_mmv_mbmode_vlc[mbmodetab];
} else {
v->mbmode_vlc = &ff_vc1_if_1mv_mbmode_vlc[mbmodetab];
}
}
if (v->dquant)
{
av_log(v->s.avctx, AV_LOG_DEBUG, "VOP DQuant info\n");
@ -989,32 +1133,72 @@ int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb)
}
break;
case AV_PICTURE_TYPE_B:
if (v->extended_mv) v->mvrange = get_unary(gb, 0, 3);
else v->mvrange = 0;
// TODO: implement interlaced frame B picture decoding
if (v->fcm == 1)
return -1;
if (v->extended_mv)
v->mvrange = get_unary(gb, 0, 3);
else
v->mvrange = 0;
v->k_x = v->mvrange + 9 + (v->mvrange >> 1); //k_x can be 9 10 12 13
v->k_y = v->mvrange + 8; //k_y can be 8 9 10 11
v->range_x = 1 << (v->k_x - 1);
v->range_y = 1 << (v->k_y - 1);
if (v->pq < 5) v->tt_index = 0;
else if(v->pq < 13) v->tt_index = 1;
else v->tt_index = 2;
if (v->pq < 5)
v->tt_index = 0;
else if(v->pq < 13)
v->tt_index = 1;
else
v->tt_index = 2;
if (v->field_mode) {
int mvmode;
if (v->extended_dmv)
v->dmvrange = get_unary(gb, 0, 3);
mvmode = get_unary(gb, 1, 3);
lowquant = (v->pq > 12) ? 0 : 1;
v->mv_mode = ff_vc1_mv_pmode_table2[lowquant][mvmode];
v->qs_last = v->s.quarter_sample;
v->s.quarter_sample = (v->mv_mode == MV_PMODE_1MV || v->mv_mode == MV_PMODE_MIXED_MV);
v->s.mspel = !(v->mv_mode == MV_PMODE_1MV_HPEL_BILIN || v->mv_mode == MV_PMODE_1MV_HPEL);
status = bitplane_decoding(v->forward_mb_plane, &v->fmb_is_raw, v);
if (status < 0)
return -1;
av_log(v->s.avctx, AV_LOG_DEBUG, "MB Forward Type plane encoding: "
"Imode: %i, Invert: %i\n", status>>1, status&1);
mbmodetab = get_bits(gb, 3);
if (v->mv_mode == MV_PMODE_MIXED_MV)
v->mbmode_vlc = &ff_vc1_if_mmv_mbmode_vlc[mbmodetab];
else
v->mbmode_vlc = &ff_vc1_if_1mv_mbmode_vlc[mbmodetab];
imvtab = get_bits(gb, 3);
v->imv_vlc = &ff_vc1_2ref_mvdata_vlc[imvtab];
icbptab = get_bits(gb, 3);
v->cbpcy_vlc = &ff_vc1_icbpcy_vlc[icbptab];
if (v->mv_mode == MV_PMODE_MIXED_MV) {
fourmvbptab = get_bits(gb, 2);
v->fourmvbp_vlc = &ff_vc1_4mv_block_pattern_vlc[fourmvbptab];
}
v->numref = 1; // interlaced field B pictures are always 2-ref
} else {
v->mv_mode = get_bits1(gb) ? MV_PMODE_1MV : MV_PMODE_1MV_HPEL_BILIN;
v->qs_last = v->s.quarter_sample;
v->s.quarter_sample = (v->mv_mode == MV_PMODE_1MV);
v->s.mspel = v->s.quarter_sample;
status = bitplane_decoding(v->direct_mb_plane, &v->dmb_is_raw, v);
if (status < 0) return -1;
if (status < 0)
return -1;
av_log(v->s.avctx, AV_LOG_DEBUG, "MB Direct Type plane encoding: "
"Imode: %i, Invert: %i\n", status>>1, status&1);
status = bitplane_decoding(v->s.mbskip_table, &v->skip_is_raw, v);
if (status < 0) return -1;
if (status < 0)
return -1;
av_log(v->s.avctx, AV_LOG_DEBUG, "MB Skip plane encoding: "
"Imode: %i, Invert: %i\n", status>>1, status&1);
v->s.mv_table_index = get_bits(gb, 2);
v->cbpcy_vlc = &ff_vc1_cbpcy_p_vlc[get_bits(gb, 2)];
}
if (v->dquant)
{

File diff suppressed because it is too large Load Diff

View File

@ -688,6 +688,26 @@ static void put_no_rnd_vc1_chroma_mc8_c(uint8_t *dst/*align 8*/, uint8_t *src/*a
}
}
static void put_no_rnd_vc1_chroma_mc4_c(uint8_t *dst, uint8_t *src, int stride, int h, int x, int y){
const int A=(8-x)*(8-y);
const int B=( x)*(8-y);
const int C=(8-x)*( y);
const int D=( x)*( y);
int i;
assert(x<8 && y<8 && x>=0 && y>=0);
for(i=0; i<h; i++)
{
dst[0] = (A*src[0] + B*src[1] + C*src[stride+0] + D*src[stride+1] + 32 - 4) >> 6;
dst[1] = (A*src[1] + B*src[2] + C*src[stride+1] + D*src[stride+2] + 32 - 4) >> 6;
dst[2] = (A*src[2] + B*src[3] + C*src[stride+2] + D*src[stride+3] + 32 - 4) >> 6;
dst[3] = (A*src[3] + B*src[4] + C*src[stride+3] + D*src[stride+4] + 32 - 4) >> 6;
dst+= stride;
src+= stride;
}
}
#define avg2(a,b) ((a+b+1)>>1)
static void avg_no_rnd_vc1_chroma_mc8_c(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y){
const int A=(8-x)*(8-y);
@ -829,6 +849,7 @@ av_cold void ff_vc1dsp_init(VC1DSPContext* dsp) {
dsp->put_no_rnd_vc1_chroma_pixels_tab[0]= put_no_rnd_vc1_chroma_mc8_c;
dsp->avg_no_rnd_vc1_chroma_pixels_tab[0]= avg_no_rnd_vc1_chroma_mc8_c;
dsp->put_no_rnd_vc1_chroma_pixels_tab[1] = put_no_rnd_vc1_chroma_mc4_c;
#if CONFIG_WMV3IMAGE_DECODER || CONFIG_VC1IMAGE_DECODER
dsp->sprite_h = sprite_h_c;