Newer
Older
/** Decode intra block in inter frames - more generic version than vc1_decode_i_block
* @param v VC1Context
* @param block block to decode
* @param coded are AC coeffs present or not
* @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, int coded, int mquant, int codingset)
GetBitContext *gb = &v->s.gb;
MpegEncContext *s = &v->s;
int dc_pred_dir = 0; /* Direction of the DC prediction used */
int run_diff, i;
int16_t *ac_val, *ac_val2;
int dcdiff;
int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
int a_avail = v->a_avail, c_avail = v->c_avail;
int use_pred = s->ac_pred;
int scale;
int q1, q2 = 0;
/* XXX: Guard against dumb values of mquant */
mquant = (mquant < 1) ? 0 : ( (mquant>31) ? 31 : mquant );
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
/* 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];
/* Get DC differential */
if (n < 4) {
dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_luma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);
} else {
dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_chroma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);
}
if (dcdiff < 0){
av_log(s->avctx, AV_LOG_ERROR, "Illegal DC VLC\n");
return -1;
}
if (dcdiff)
{
if (dcdiff == 119 /* ESC index value */)
{
/* TODO: Optimize */
if (mquant == 1) dcdiff = get_bits(gb, 10);
else if (mquant == 2) dcdiff = get_bits(gb, 9);
else dcdiff = get_bits(gb, 8);
}
else
{
if (mquant == 1)
dcdiff = (dcdiff<<2) + get_bits(gb, 2) - 3;
else if (mquant == 2)
dcdiff = (dcdiff<<1) + get_bits(gb, 1) - 1;
}
if (get_bits(gb, 1))
dcdiff = -dcdiff;
}
/* Prediction */
dcdiff += vc1_pred_dc(&v->s, v->overlap, mquant, n, a_avail, c_avail, &dc_val, &dc_pred_dir);
*dc_val = dcdiff;
/* Store the quantized DC coeff, used for prediction */
if (n < 4) {
block[0] = dcdiff * s->y_dc_scale;
} else {
block[0] = dcdiff * s->c_dc_scale;
}
/* Skip ? */
run_diff = 0;
i = 0;
//AC Decoding
i = 1;
/* check if AC is needed at all and adjust direction if needed */
if(!a_avail) dc_pred_dir = 1;
if(!c_avail) dc_pred_dir = 0;
if(!a_avail && !c_avail) use_pred = 0;
ac_val = s->ac_val[0][0] + s->block_index[n] * 16;
ac_val2 = ac_val;
scale = mquant * 2 + v->halfpq;
if(dc_pred_dir) //left
ac_val -= 16;
else //top
ac_val -= 16 * s->block_wrap[n];
q1 = s->current_picture.qscale_table[mb_pos];
if(dc_pred_dir && c_avail && mb_pos) q2 = s->current_picture.qscale_table[mb_pos - 1];
if(!dc_pred_dir && a_avail && mb_pos >= s->mb_stride) q2 = s->current_picture.qscale_table[mb_pos - s->mb_stride];
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
if(n && n<4) q2 = q1;
if(coded) {
int last = 0, skip, value;
const int8_t *zz_table;
int k;
zz_table = vc1_simple_progressive_8x8_zz;
while (!last) {
vc1_decode_ac_coeff(v, &last, &skip, &value, codingset);
i += skip;
if(i > 63)
break;
block[zz_table[i++]] = value;
}
/* apply AC prediction if needed */
if(use_pred) {
/* scale predictors if needed*/
if(q2 && q1!=q2) {
q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1;
q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1;
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
if(dc_pred_dir) { //left
for(k = 1; k < 8; k++)
block[k << 3] += (ac_val[k] * q2 * vc1_dqscale[q1 - 1] + 0x20000) >> 18;
} else { //top
for(k = 1; k < 8; k++)
block[k] += (ac_val[k + 8] * q2 * vc1_dqscale[q1 - 1] + 0x20000) >> 18;
}
} else {
if(dc_pred_dir) { //left
for(k = 1; k < 8; k++)
block[k << 3] += ac_val[k];
} else { //top
for(k = 1; k < 8; k++)
block[k] += ac_val[k + 8];
}
}
}
/* save AC coeffs for further prediction */
for(k = 1; k < 8; k++) {
ac_val2[k] = block[k << 3];
ac_val2[k + 8] = block[k];
}
/* scale AC coeffs */
for(k = 1; k < 64; k++)
if(block[k]) {
block[k] *= scale;
if(!v->pquantizer)
block[k] += (block[k] < 0) ? -mquant : mquant;
}
if(use_pred) i = 63;
} else { // no AC coeffs
int k;
memset(ac_val2, 0, 16 * 2);
if(dc_pred_dir) {//left
if(use_pred) {
memcpy(ac_val2, ac_val, 8 * 2);
if(q2 && q1!=q2) {
q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1;
q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1;
for(k = 1; k < 8; k++)
ac_val2[k] = (ac_val2[k] * q2 * vc1_dqscale[q1 - 1] + 0x20000) >> 18;
}
}
} else {//top
if(use_pred) {
memcpy(ac_val2 + 8, ac_val + 8, 8 * 2);
if(q2 && q1!=q2) {
q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1;
q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1;
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
for(k = 1; k < 8; k++)
ac_val2[k + 8] = (ac_val2[k + 8] * q2 * vc1_dqscale[q1 - 1] + 0x20000) >> 18;
}
}
}
/* apply AC prediction if needed */
if(use_pred) {
if(dc_pred_dir) { //left
for(k = 1; k < 8; k++) {
block[k << 3] = ac_val2[k] * scale;
if(!v->pquantizer && block[k << 3])
block[k << 3] += (block[k << 3] < 0) ? -mquant : mquant;
}
} else { //top
for(k = 1; k < 8; k++) {
block[k] = ac_val2[k + 8] * scale;
if(!v->pquantizer && block[k])
block[k] += (block[k] < 0) ? -mquant : mquant;
}
}
i = 63;
}
}
s->block_last_index[n] = i;
return 0;
}
/** Decode P block
*/
static int vc1_decode_p_block(VC1Context *v, DCTELEM block[64], int n, int mquant, int ttmb, int first_block)
{
MpegEncContext *s = &v->s;
GetBitContext *gb = &s->gb;
int i, j;
int subblkpat = 0;
int scale, off, idx, last, skip, value;
int ttblk = ttmb & 7;
if(ttmb == -1) {
ttblk = ttblk_to_tt[v->tt_index][get_vlc2(gb, vc1_ttblk_vlc[v->tt_index].table, VC1_TTBLK_VLC_BITS, 1)];
}
if(ttblk == TT_4X4) {
subblkpat = ~(get_vlc2(gb, vc1_subblkpat_vlc[v->tt_index].table, VC1_SUBBLKPAT_VLC_BITS, 1) + 1);
}
if((ttblk != TT_8X8 && ttblk != TT_4X4) && (v->ttmbf || (ttmb != -1 && (ttmb & 8) && !first_block))) {
subblkpat = decode012(gb);
if(subblkpat) subblkpat ^= 3; //swap decoded pattern bits
if(ttblk == TT_8X4_TOP || ttblk == TT_8X4_BOTTOM) ttblk = TT_8X4;
if(ttblk == TT_4X8_RIGHT || ttblk == TT_4X8_LEFT) ttblk = TT_4X8;
}
scale = 2 * mquant + v->halfpq;
// convert transforms like 8X4_TOP to generic TT and SUBBLKPAT
if(ttblk == TT_8X4_TOP || ttblk == TT_8X4_BOTTOM) {
subblkpat = 2 - (ttblk == TT_8X4_TOP);
ttblk = TT_8X4;
}
if(ttblk == TT_4X8_RIGHT || ttblk == TT_4X8_LEFT) {
subblkpat = 2 - (ttblk == TT_4X8_LEFT);
ttblk = TT_4X8;
}
switch(ttblk) {
case TT_8X8:
i = 0;
last = 0;
while (!last) {
vc1_decode_ac_coeff(v, &last, &skip, &value, v->codingset2);
i += skip;
if(i > 63)
break;
idx = vc1_simple_progressive_8x8_zz[i++];
block[idx] = value * scale;
if(!v->pquantizer)
block[idx] += (block[idx] < 0) ? -mquant : mquant;
s->dsp.vc1_inv_trans_8x8(block);
break;
case TT_4X4:
for(j = 0; j < 4; j++) {
last = subblkpat & (1 << (3 - j));
i = 0;
off = (j & 1) * 4 + (j & 2) * 16;
while (!last) {
vc1_decode_ac_coeff(v, &last, &skip, &value, v->codingset2);
i += skip;
if(i > 15)
break;
idx = vc1_simple_progressive_4x4_zz[i++];
block[idx + off] = value * scale;
if(!v->pquantizer)
block[idx + off] += (block[idx + off] < 0) ? -mquant : mquant;
if(!(subblkpat & (1 << (3 - j))))
s->dsp.vc1_inv_trans_4x4(block, j);
}
break;
case TT_8X4:
for(j = 0; j < 2; j++) {
last = subblkpat & (1 << (1 - j));
i = 0;
off = j * 32;
while (!last) {
vc1_decode_ac_coeff(v, &last, &skip, &value, v->codingset2);
i += skip;
if(i > 31)
break;
if(v->profile < PROFILE_ADVANCED)
idx = vc1_simple_progressive_8x4_zz[i++];
else
idx = vc1_adv_progressive_8x4_zz[i++];
block[idx + off] = value * scale;
if(!v->pquantizer)
block[idx + off] += (block[idx + off] < 0) ? -mquant : mquant;
if(!(subblkpat & (1 << (1 - j))))
s->dsp.vc1_inv_trans_8x4(block, j);
}
break;
case TT_4X8:
for(j = 0; j < 2; j++) {
last = subblkpat & (1 << (1 - j));
i = 0;
off = j * 4;
while (!last) {
vc1_decode_ac_coeff(v, &last, &skip, &value, v->codingset2);
i += skip;
if(i > 31)
break;
if(v->profile < PROFILE_ADVANCED)
idx = vc1_simple_progressive_4x8_zz[i++];
else
idx = vc1_adv_progressive_4x8_zz[i++];
block[idx + off] = value * scale;
if(!v->pquantizer)
block[idx + off] += (block[idx + off] < 0) ? -mquant : mquant;
if(!(subblkpat & (1 << (1 - j))))
s->dsp.vc1_inv_trans_4x8(block, j);
break;
}
return 0;
}
/** Decode one P-frame MB (in Simple/Main profile)
*/
Kostya Shishkov
committed
static int vc1_decode_p_mb(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; /* cbp decoding stuff */
int mqdiff, mquant; /* MB quantization */
int ttmb = v->ttfrm; /* MB Transform type */
int status;
static const int size_table[6] = { 0, 2, 3, 4, 5, 8 },
offset_table[6] = { 0, 1, 3, 7, 15, 31 };
int mb_has_coeffs = 1; /* last_flag */
int dmv_x, dmv_y; /* Differential MV components */
int index, index1; /* LUT indices */
int val, sign; /* temp values */
int first_block = 1;
int dst_idx, off;
int skipped, fourmv;
mquant = v->pq; /* Loosy initialization */
if (v->mv_type_is_raw)
fourmv = get_bits1(gb);
else
fourmv = v->mv_type_mb_plane[mb_pos];
if (v->skip_is_raw)
skipped = get_bits1(gb);
else
skipped = v->s.mbskip_table[mb_pos];
if (!fourmv) /* 1MV mode */
if (!skipped)
{
GET_MVDATA(dmv_x, dmv_y);
if (s->mb_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] = s->mb_intra ? MB_TYPE_INTRA : MB_TYPE_16x16;
vc1_pred_mv(s, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0]);
/* FIXME Set DC val for inter block ? */
if (s->mb_intra && !mb_has_coeffs)
{
GET_MQUANT();
s->ac_pred = get_bits(gb, 1);
cbp = 0;
}
else if (mb_has_coeffs)
{
if (s->mb_intra) s->ac_pred = get_bits(gb, 1);
cbp = get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
GET_MQUANT();
}
else
{
mquant = v->pq;
cbp = 0;
s->current_picture.qscale_table[mb_pos] = mquant;
if (!v->ttmbf && !s->mb_intra && mb_has_coeffs)
ttmb = get_vlc2(gb, vc1_ttmb_vlc[v->tt_index].table,
VC1_TTMB_VLC_BITS, 2);
Kostya Shishkov
committed
if(!s->mb_intra) vc1_mc_1mv(v, 0);
dst_idx = 0;
for (i=0; i<6; i++)
{
s->dc_val[0][s->block_index[i]] = 0;
dst_idx += i >> 2;
val = ((cbp >> (5 - i)) & 1);
off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize);
v->mb_type[0][s->block_index[i]] = s->mb_intra;
if(s->mb_intra) {
Kostya Shishkov
committed
/* check if prediction blocks A and C are available */
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];
Kostya Shishkov
committed
Kostya Shishkov
committed
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;
s->dsp.vc1_inv_trans_8x8(s->block[i]);
if(v->rangeredfrm) for(j = 0; j < 64; j++) s->block[i][j] <<= 1;
Kostya Shishkov
committed
for(j = 0; j < 64; j++) s->block[i][j] += 128;
s->dsp.put_pixels_clamped(s->block[i], s->dest[dst_idx] + off, s->linesize >> ((i & 4) >> 2));
if(v->pq >= 9 && v->overlap) {
if(v->c_avail)
s->dsp.vc1_h_overlap(s->dest[dst_idx] + off, s->linesize >> ((i & 4) >> 2));
s->dsp.vc1_v_overlap(s->dest[dst_idx] + off, s->linesize >> ((i & 4) >> 2));
} else if(val) {
Kostya Shishkov
committed
vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, first_block);
if(!v->ttmbf && ttmb < 8) ttmb = -1;
first_block = 0;
if((i<4) || !(s->flags & CODEC_FLAG_GRAY))
s->dsp.add_pixels_clamped(s->block[i], s->dest[dst_idx] + off, (i&4)?s->uvlinesize:s->linesize);
}
}
}
else //Skipped
{
s->mb_intra = 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;
vc1_pred_mv(s, 0, 0, 0, 1, v->range_x, v->range_y, v->mb_type[0]);
Kostya Shishkov
committed
vc1_mc_1mv(v, 0);
return 0;
}
} //1MV mode
else //4MV mode
if (!skipped /* unskipped MB */)
int intra_count = 0, coded_inter = 0;
int is_intra[6], is_coded[6];
/* Get CBPCY */
cbp = get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
{
val = ((cbp >> (5 - i)) & 1);
s->dc_val[0][s->block_index[i]] = 0;
s->mb_intra = 0;
if(i < 4) {
dmv_x = dmv_y = 0;
s->mb_intra = 0;
mb_has_coeffs = 0;
if(val) {
GET_MVDATA(dmv_x, dmv_y);
}
vc1_pred_mv(s, i, dmv_x, dmv_y, 0, v->range_x, v->range_y, v->mb_type[0]);
if(!s->mb_intra) vc1_mc_4mv_luma(v, i);
intra_count += s->mb_intra;
is_intra[i] = s->mb_intra;
is_coded[i] = mb_has_coeffs;
}
if(i&4){
is_intra[i] = (intra_count >= 3);
is_coded[i] = val;
if(i == 4) vc1_mc_4mv_chroma(v);
v->mb_type[0][s->block_index[i]] = is_intra[i];
if(!coded_inter) coded_inter = !is_intra[i] & is_coded[i];
// if there are no coded blocks then don't do anything more
if(!intra_count && !coded_inter) return 0;
dst_idx = 0;
GET_MQUANT();
s->current_picture.qscale_table[mb_pos] = mquant;
/* test if block is intra and has pred */
{
int intrapred = 0;
for(i=0; i<6; i++)
if(is_intra[i]) {
if(((!s->first_slice_line || (i==2 || i==3)) && v->mb_type[0][s->block_index[i] - s->block_wrap[i]])
|| ((s->mb_x || (i==1 || i==3)) && v->mb_type[0][s->block_index[i] - 1])) {
intrapred = 1;
break;
}
}
if(intrapred)s->ac_pred = get_bits(gb, 1);
else s->ac_pred = 0;
}
if (!v->ttmbf && coded_inter)
ttmb = get_vlc2(gb, vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);
for (i=0; i<6; i++)
{
dst_idx += i >> 2;
off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize);
s->mb_intra = is_intra[i];
if (is_intra[i]) {
/* check if prediction blocks A and C are available */
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, is_coded[i], mquant, (i&4)?v->codingset2:v->codingset);
if((i>3) && (s->flags & CODEC_FLAG_GRAY)) continue;
s->dsp.vc1_inv_trans_8x8(s->block[i]);
if(v->rangeredfrm) for(j = 0; j < 64; j++) s->block[i][j] <<= 1;
Kostya Shishkov
committed
for(j = 0; j < 64; j++) s->block[i][j] += 128;
s->dsp.put_pixels_clamped(s->block[i], s->dest[dst_idx] + off, (i&4)?s->uvlinesize:s->linesize);
if(v->pq >= 9 && v->overlap) {
if(v->c_avail)
s->dsp.vc1_h_overlap(s->dest[dst_idx] + off, s->linesize >> ((i & 4) >> 2));
s->dsp.vc1_v_overlap(s->dest[dst_idx] + off, s->linesize >> ((i & 4) >> 2));
} else if(is_coded[i]) {
status = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, first_block);
if(!v->ttmbf && ttmb < 8) ttmb = -1;
first_block = 0;
if((i<4) || !(s->flags & CODEC_FLAG_GRAY))
s->dsp.add_pixels_clamped(s->block[i], s->dest[dst_idx] + off, (i&4)?s->uvlinesize:s->linesize);
}
return status;
}
else //Skipped MB
{
s->mb_intra = 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(s, i, 0, 0, 0, v->range_x, v->range_y, v->mb_type[0]);
vc1_mc_4mv_luma(v, i);
vc1_mc_4mv_chroma(v);
s->current_picture.qscale_table[mb_pos] = 0;
return 0;
}
}
/* Should never happen */
return -1;
}
Kostya Shishkov
committed
/** Decode one B-frame MB (in Main profile)
*/
static void vc1_decode_b_mb(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 */
Kostya Shishkov
committed
int mqdiff, mquant; /* MB quantization */
int ttmb = v->ttfrm; /* MB Transform type */
static const int size_table[6] = { 0, 2, 3, 4, 5, 8 },
offset_table[6] = { 0, 1, 3, 7, 15, 31 };
int mb_has_coeffs = 0; /* last_flag */
int index, index1; /* LUT indices */
int val, sign; /* temp values */
int first_block = 1;
int dst_idx, off;
int skipped, direct;
int dmv_x[2], dmv_y[2];
int bmvtype = BMV_TYPE_BACKWARD;
Kostya Shishkov
committed
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
mquant = v->pq; /* Loosy initialization */
s->mb_intra = 0;
if (v->dmb_is_raw)
direct = get_bits1(gb);
else
direct = v->direct_mb_plane[mb_pos];
if (v->skip_is_raw)
skipped = get_bits1(gb);
else
skipped = v->s.mbskip_table[mb_pos];
s->dsp.clear_blocks(s->block[0]);
dmv_x[0] = dmv_x[1] = dmv_y[0] = dmv_y[1] = 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.qscale_table[mb_pos] = 0;
if (!direct) {
if (!skipped) {
GET_MVDATA(dmv_x[0], dmv_y[0]);
dmv_x[1] = dmv_x[0];
dmv_y[1] = dmv_y[0];
Kostya Shishkov
committed
}
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;
dmv_x[0] = dmv_y[0] = 0;
Kostya Shishkov
committed
}
}
}
for(i = 0; i < 6; i++)
v->mb_type[0][s->block_index[i]] = s->mb_intra;
Kostya Shishkov
committed
if (skipped) {
if(direct) bmvtype = BMV_TYPE_INTERPOLATED;
vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype);
Kostya Shishkov
committed
vc1_b_mc(v, dmv_x, dmv_y, direct, bmvtype);
return;
}
if (direct) {
cbp = get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
GET_MQUANT();
s->mb_intra = 0;
mb_has_coeffs = 0;
Kostya Shishkov
committed
s->current_picture.qscale_table[mb_pos] = mquant;
if(!v->ttmbf)
Kostya Shishkov
committed
ttmb = get_vlc2(gb, 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;
vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype);
Kostya Shishkov
committed
vc1_b_mc(v, dmv_x, dmv_y, direct, bmvtype);
} else {
if(!mb_has_coeffs && !s->mb_intra) {
/* no coded blocks - effectively skipped */
vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype);
Kostya Shishkov
committed
vc1_b_mc(v, dmv_x, dmv_y, direct, bmvtype);
return;
}
if(s->mb_intra && !mb_has_coeffs) {
GET_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);
Kostya Shishkov
committed
} else {
if(bmvtype == BMV_TYPE_INTERPOLATED) {
GET_MVDATA(dmv_x[0], dmv_y[0]);
Kostya Shishkov
committed
if(!mb_has_coeffs) {
/* interpolated skipped block */
vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype);
Kostya Shishkov
committed
vc1_b_mc(v, dmv_x, dmv_y, direct, bmvtype);
return;
}
}
vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype);
if(!s->mb_intra) {
Kostya Shishkov
committed
vc1_b_mc(v, dmv_x, dmv_y, direct, bmvtype);
Kostya Shishkov
committed
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
if(s->mb_intra)
s->ac_pred = get_bits1(gb);
cbp = get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
GET_MQUANT();
s->current_picture.qscale_table[mb_pos] = mquant;
if(!v->ttmbf && !s->mb_intra && mb_has_coeffs)
ttmb = get_vlc2(gb, vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);
}
}
dst_idx = 0;
for (i=0; i<6; i++)
{
s->dc_val[0][s->block_index[i]] = 0;
dst_idx += i >> 2;
val = ((cbp >> (5 - i)) & 1);
off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize);
v->mb_type[0][s->block_index[i]] = s->mb_intra;
if(s->mb_intra) {
/* check if prediction blocks A and C are available */
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;
s->dsp.vc1_inv_trans_8x8(s->block[i]);
if(v->rangeredfrm) for(j = 0; j < 64; j++) s->block[i][j] <<= 1;
Kostya Shishkov
committed
for(j = 0; j < 64; j++) s->block[i][j] += 128;
s->dsp.put_pixels_clamped(s->block[i], s->dest[dst_idx] + off, s->linesize >> ((i & 4) >> 2));
} else if(val) {
vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, first_block);
if(!v->ttmbf && ttmb < 8) ttmb = -1;
first_block = 0;
if((i<4) || !(s->flags & CODEC_FLAG_GRAY))
s->dsp.add_pixels_clamped(s->block[i], s->dest[dst_idx] + off, (i&4)?s->uvlinesize:s->linesize);
Kostya Shishkov
committed
}
}
}
/** Decode blocks of I-frame
static void vc1_decode_i_blocks(VC1Context *v)
MpegEncContext *s = &v->s;
int cbp, val;
uint8_t *coded_val;
int mb_pos;
/* select codingmode used for VLC tables selection */
switch(v->y_ac_table_index){
case 0:
v->codingset = (v->pqindex <= 8) ? CS_HIGH_RATE_INTRA : CS_LOW_MOT_INTRA;
break;
case 1:
v->codingset = CS_HIGH_MOT_INTRA;
break;
case 2:
v->codingset = CS_MID_RATE_INTRA;
break;
}
switch(v->c_ac_table_index){
case 0:
v->codingset2 = (v->pqindex <= 8) ? CS_HIGH_RATE_INTER : CS_LOW_MOT_INTER;
break;
case 1:
v->codingset2 = CS_HIGH_MOT_INTER;
break;
case 2:
v->codingset2 = CS_MID_RATE_INTER;
break;
}
/* Set DC scale - y and c use the same */
s->y_dc_scale = s->y_dc_scale_table[v->pq];
s->c_dc_scale = s->c_dc_scale_table[v->pq];
//do frame decode
s->mb_x = s->mb_y = 0;
s->mb_intra = 1;
s->first_slice_line = 1;
ff_er_add_slice(s, 0, 0, s->mb_width - 1, s->mb_height - 1, (AC_END|DC_END|MV_END));
for(s->mb_y = 0; s->mb_y < s->mb_height; s->mb_y++) {
for(s->mb_x = 0; s->mb_x < s->mb_width; s->mb_x++) {
ff_init_block_index(s);
ff_update_block_index(s);
s->dsp.clear_blocks(s->block[0]);
mb_pos = s->mb_x + s->mb_y * s->mb_width;
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);
v->s.ac_pred = get_bits(&v->s.gb, 1);
for(k = 0; k < 6; k++) {
val = ((cbp >> (5 - k)) & 1);
Kostya Shishkov
committed
if (k < 4) {
int pred = vc1_coded_block_pred(&v->s, k, &coded_val);
val = val ^ pred;
*coded_val = val;
}
cbp |= val << (5 - k);
vc1_decode_i_block(v, s->block[k], k, val, (k<4)? v->codingset : v->codingset2);
s->dsp.vc1_inv_trans_8x8(s->block[k]);
if(v->pq >= 9 && v->overlap) {
for(j = 0; j < 64; j++) s->block[k][j] += 128;
vc1_put_block(v, s->block);
if(v->pq >= 9 && v->overlap) {
Kostya Shishkov
committed
if(s->mb_x) {
s->dsp.vc1_h_overlap(s->dest[0], s->linesize);
s->dsp.vc1_h_overlap(s->dest[0] + 8 * s->linesize, s->linesize);
s->dsp.vc1_h_overlap(s->dest[1], s->uvlinesize);
s->dsp.vc1_h_overlap(s->dest[2], s->uvlinesize);
Kostya Shishkov
committed
}
s->dsp.vc1_h_overlap(s->dest[0] + 8, s->linesize);
s->dsp.vc1_h_overlap(s->dest[0] + 8 * s->linesize + 8, s->linesize);
if(!s->first_slice_line) {
s->dsp.vc1_v_overlap(s->dest[0], s->linesize);
s->dsp.vc1_v_overlap(s->dest[0] + 8, s->linesize);
if(!(s->flags & CODEC_FLAG_GRAY)) {
s->dsp.vc1_v_overlap(s->dest[1], s->uvlinesize);
s->dsp.vc1_v_overlap(s->dest[2], s->uvlinesize);
s->dsp.vc1_v_overlap(s->dest[0] + 8 * s->linesize, s->linesize);
s->dsp.vc1_v_overlap(s->dest[0] + 8 * s->linesize + 8, s->linesize);
Kostya Shishkov
committed
}
if(get_bits_count(&s->gb) > v->bits) {
av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i\n", get_bits_count(&s->gb), v->bits);
return;
}
}
ff_draw_horiz_band(s, s->mb_y * 16, 16);
s->first_slice_line = 0;
}
}
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
/** Decode blocks of I-frame for advanced profile
*/
static void vc1_decode_i_blocks_adv(VC1Context *v)
{
int k, j;
MpegEncContext *s = &v->s;
int cbp, val;
uint8_t *coded_val;
int mb_pos;
int mquant = v->pq;
int mqdiff;
int overlap;
GetBitContext *gb = &s->gb;
/* select codingmode used for VLC tables selection */
switch(v->y_ac_table_index){
case 0:
v->codingset = (v->pqindex <= 8) ? CS_HIGH_RATE_INTRA : CS_LOW_MOT_INTRA;
break;
case 1:
v->codingset = CS_HIGH_MOT_INTRA;
break;
case 2:
v->codingset = CS_MID_RATE_INTRA;
break;
}
switch(v->c_ac_table_index){
case 0:
v->codingset2 = (v->pqindex <= 8) ? CS_HIGH_RATE_INTER : CS_LOW_MOT_INTER;
break;
case 1:
v->codingset2 = CS_HIGH_MOT_INTER;
break;
case 2:
v->codingset2 = CS_MID_RATE_INTER;
break;
}
//do frame decode
s->mb_x = s->mb_y = 0;
s->mb_intra = 1;
s->first_slice_line = 1;
ff_er_add_slice(s, 0, 0, s->mb_width - 1, s->mb_height - 1, (AC_END|DC_END|MV_END));
for(s->mb_y = 0; s->mb_y < s->mb_height; s->mb_y++) {
for(s->mb_x = 0; s->mb_x < s->mb_width; s->mb_x++) {
ff_init_block_index(s);
ff_update_block_index(s);
s->dsp.clear_blocks(s->block[0]);
mb_pos = s->mb_x + s->mb_y * s->mb_stride;
s->current_picture.mb_type[mb_pos] = 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;
// do actual MB decoding and displaying
cbp = get_vlc2(&v->s.gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2);
if(v->acpred_is_raw)
v->s.ac_pred = get_bits(&v->s.gb, 1);
else
v->s.ac_pred = v->acpred_plane[mb_pos];
if(v->condover == CONDOVER_SELECT) {
if(v->overflg_is_raw)
overlap = get_bits(&v->s.gb, 1);
else
overlap = v->over_flags_plane[mb_pos];
} else
overlap = (v->condover == CONDOVER_ALL);
GET_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];
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
for(k = 0; k < 6; k++) {
val = ((cbp >> (5 - k)) & 1);
if (k < 4) {
int pred = vc1_coded_block_pred(&v->s, k, &coded_val);
val = val ^ pred;
*coded_val = val;
}
cbp |= val << (5 - k);
v->a_avail = !s->first_slice_line || (k==2 || k==3);
v->c_avail = !!s->mb_x || (k==1 || k==3);
vc1_decode_i_block_adv(v, s->block[k], k, val, (k<4)? v->codingset : v->codingset2, mquant);
s->dsp.vc1_inv_trans_8x8(s->block[k]);
for(j = 0; j < 64; j++) s->block[k][j] += 128;
}
vc1_put_block(v, s->block);
if(overlap) {
if(s->mb_x) {
s->dsp.vc1_h_overlap(s->dest[0], s->linesize);
s->dsp.vc1_h_overlap(s->dest[0] + 8 * s->linesize, s->linesize);
if(!(s->flags & CODEC_FLAG_GRAY)) {
s->dsp.vc1_h_overlap(s->dest[1], s->uvlinesize);
s->dsp.vc1_h_overlap(s->dest[2], s->uvlinesize);
}
}
s->dsp.vc1_h_overlap(s->dest[0] + 8, s->linesize);
s->dsp.vc1_h_overlap(s->dest[0] + 8 * s->linesize + 8, s->linesize);
if(!s->first_slice_line) {
s->dsp.vc1_v_overlap(s->dest[0], s->linesize);
s->dsp.vc1_v_overlap(s->dest[0] + 8, s->linesize);
if(!(s->flags & CODEC_FLAG_GRAY)) {
s->dsp.vc1_v_overlap(s->dest[1], s->uvlinesize);
s->dsp.vc1_v_overlap(s->dest[2], s->uvlinesize);
s->dsp.vc1_v_overlap(s->dest[0] + 8 * s->linesize, s->linesize);
s->dsp.vc1_v_overlap(s->dest[0] + 8 * s->linesize + 8, s->linesize);
}
if(get_bits_count(&s->gb) > v->bits) {
av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i\n", get_bits_count(&s->gb), v->bits);
return;
}
}
ff_draw_horiz_band(s, s->mb_y * 16, 16);
s->first_slice_line = 0;
}
}
static void vc1_decode_p_blocks(VC1Context *v)
{
MpegEncContext *s = &v->s;
/* select codingmode used for VLC tables selection */
switch(v->c_ac_table_index){
case 0:
v->codingset = (v->pqindex <= 8) ? CS_HIGH_RATE_INTRA : CS_LOW_MOT_INTRA;
break;
case 1:
v->codingset = CS_HIGH_MOT_INTRA;
break;
case 2:
v->codingset = CS_MID_RATE_INTRA;
break;
switch(v->c_ac_table_index){
case 0:
v->codingset2 = (v->pqindex <= 8) ? CS_HIGH_RATE_INTER : CS_LOW_MOT_INTER;
break;
case 1:
v->codingset2 = CS_HIGH_MOT_INTER;
break;
case 2:
v->codingset2 = CS_MID_RATE_INTER;
break;
}
ff_er_add_slice(s, 0, 0, s->mb_width - 1, s->mb_height - 1, (AC_END|DC_END|MV_END));
s->first_slice_line = 1;
for(s->mb_y = 0; s->mb_y < s->mb_height; s->mb_y++) {
for(s->mb_x = 0; s->mb_x < s->mb_width; s->mb_x++) {
ff_init_block_index(s);
ff_update_block_index(s);
s->dsp.clear_blocks(s->block[0]);
Kostya Shishkov
committed
vc1_decode_p_mb(v);
if(get_bits_count(&s->gb) > v->bits || get_bits_count(&s->gb) < 0) {
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;
}
}
ff_draw_horiz_band(s, s->mb_y * 16, 16);
s->first_slice_line = 0;
}
}
Alex Beregszaszi
committed
Kostya Shishkov
committed
static void vc1_decode_b_blocks(VC1Context *v)
{
MpegEncContext *s = &v->s;