📄 dec_cavlc.c
字号:
uint8_t
T264dec_mb_read_total_zero13(T264_t* t)
{
uint8_t total_zero;
int32_t code;
code = eg_show(t->bs, 3);
total_zero = total_zero_table13_0[code].num;
eg_read_skip(t->bs, total_zero_table13_0[code].len);
return total_zero;
}
uint8_t
T264dec_mb_read_total_zero14(T264_t* t)
{
uint8_t total_zero;
int32_t code;
code = eg_show(t->bs, 2);
total_zero = total_zero_table14_0[code].num;
eg_read_skip(t->bs, total_zero_table14_0[code].len);
return total_zero;
}
uint8_t
T264dec_mb_read_total_zero15(T264_t* t)
{
return eg_read_direct1(t->bs);
}
uint8_t
T264dec_mb_read_total_zero_chroma(T264_t* t, uint8_t total_coeff)
{
uint8_t total_zero;
int32_t code;
code = eg_show(t->bs, 3);
total_zero = total_zero_table_chroma[total_coeff - 1][code].num;
eg_read_skip(t->bs, total_zero_table_chroma[total_coeff - 1][code].len);
assert(total_zero != 255);
return total_zero;
}
uint8_t
T264dec_mb_read_run_before(T264_t* t, uint8_t zero_left)
{
int32_t code;
uint8_t run_before;
assert(zero_left != 255);
code = eg_show(t->bs, 3);
if (zero_left <= 6)
{
run_before = run_before_table_0[zero_left - 1][code].num;
eg_read_skip(t->bs, run_before_table_0[zero_left - 1][code].len);
}
else
{
eg_read_skip(t->bs, 3);
if (code > 0)
{
run_before = run_before_table_0[6][code].num;
}
else
{
code = eg_show(t->bs, 4);
if (code > 0)
{
run_before = run_before_table_1[code];
eg_read_skip(t->bs, run_before - 6);
}
else
{
eg_read_skip(t->bs, 4);
code = eg_show(t->bs, 4);
run_before = run_before_table_2[code];
eg_read_skip(t->bs, run_before - 10);
}
}
}
assert(run_before >= 0 && run_before <= 14);
return run_before;
}
void
T264dec_mb_read_cavlc_residual(T264_t* t, int32_t idx, int16_t* z, int32_t count)
{
uint8_t trailing_ones, total_coeff;
int32_t i, j;
int32_t zero_left = 0;
int16_t level[16];
uint8_t run[16];
int32_t x, y;
if(idx == BLOCK_INDEX_CHROMA_DC)
{
T264dec_mb_read_coff_token_t4(t, &trailing_ones, &total_coeff);
}
else
{
/* T264_mb_predict_non_zero_code return 0 <-> (16+16+1)>>1 = 16 */
int32_t nC = 0;
typedef void (*T264dec_mb_read_coff_token_t)(T264_t* t, uint8_t* trailing_ones, uint8_t* total_coff);
static const T264dec_mb_read_coff_token_t read_coeff[17] =
{
T264dec_mb_read_coff_token_t0, T264dec_mb_read_coff_token_t0,
T264dec_mb_read_coff_token_t1, T264dec_mb_read_coff_token_t1,
T264dec_mb_read_coff_token_t2, T264dec_mb_read_coff_token_t2,
T264dec_mb_read_coff_token_t2, T264dec_mb_read_coff_token_t2,
T264dec_mb_read_coff_token_t3, T264dec_mb_read_coff_token_t3,
T264dec_mb_read_coff_token_t3, T264dec_mb_read_coff_token_t3,
T264dec_mb_read_coff_token_t3, T264dec_mb_read_coff_token_t3,
T264dec_mb_read_coff_token_t3, T264dec_mb_read_coff_token_t3,
T264dec_mb_read_coff_token_t3
};
if(idx == BLOCK_INDEX_LUMA_DC)
{
// predict nC = (nA + nB) / 2;
nC = T264_mb_predict_non_zero_code(t, 0);
read_coeff[nC](t, &trailing_ones, &total_coeff);
}
else
{
// predict nC = (nA + nB) / 2;
nC = T264_mb_predict_non_zero_code(t, idx);
read_coeff[nC](t, &trailing_ones, &total_coeff);
assert(total_coeff != 255);
assert(trailing_ones != 255);
if (idx < 16)
{
x = luma_inverse_x[idx];
y = luma_inverse_y[idx];
t->mb.nnz[luma_index[idx]] = total_coeff;
t->mb.nnz_ref[NNZ_LUMA + y * 8 + x] = total_coeff;
}
else if (idx < 20)
{
t->mb.nnz[idx] = total_coeff;
x = (idx - 16) % 2;
y = (idx - 16) / 2;
t->mb.nnz_ref[NNZ_CHROMA0 + y * 8 + x] = total_coeff;
}
else
{
t->mb.nnz[idx] = total_coeff;
x = (idx - 20) % 2;
y = (idx - 20) / 2;
t->mb.nnz_ref[NNZ_CHROMA1 + y * 8 + x] = total_coeff;
}
}
}
if (total_coeff > 0)
{
uint8_t suffix_length = 0;
int32_t level_code;
if (total_coeff > 10 && trailing_ones < 3)
suffix_length = 1;
for(i = 0 ; i < trailing_ones ; i ++)
{
level[i] = 1 - 2 * eg_read_direct1(t->bs);
}
for( ; i < total_coeff ; i ++)
{
uint32_t level_suffixsize;
uint32_t level_suffix;
uint8_t level_prefix = T264dec_mb_read_level_prefix(t);
level_suffixsize = suffix_length;
if (suffix_length == 0 && level_prefix == 14)
level_suffixsize = 4;
else if (level_prefix == 15)
level_suffixsize = 12;
if (level_suffixsize > 0)
level_suffix = eg_read_direct(t->bs, level_suffixsize);
else
level_suffix = 0;
level_code = (level_prefix << suffix_length) + level_suffix;
if (level_prefix == 15 && suffix_length == 0)
{
level_code += 15;
}
if (i == trailing_ones && trailing_ones < 3)
{
level_code += 2;
}
if (level_code % 2 == 0)
{
level[i] = (level_code + 2) >> 1;
}
else
{
level[i] = (-level_code - 1) >> 1;
}
if (suffix_length == 0)
suffix_length = 1;
if (ABS(level[i]) > (3 << (suffix_length - 1)) &&
suffix_length < 6)
{
suffix_length ++;
}
}
if (total_coeff < count)
{
typedef uint8_t (*T264dec_mb_read_total_zero_t)(T264_t* t);
static T264dec_mb_read_total_zero_t total_zero_f[] =
{
T264dec_mb_read_total_zero1, T264dec_mb_read_total_zero2, T264dec_mb_read_total_zero3, T264dec_mb_read_total_zero4,
T264dec_mb_read_total_zero5, T264dec_mb_read_total_zero6, T264dec_mb_read_total_zero7, T264dec_mb_read_total_zero8,
T264dec_mb_read_total_zero9, T264dec_mb_read_total_zero10, T264dec_mb_read_total_zero11, T264dec_mb_read_total_zero12,
T264dec_mb_read_total_zero13, T264dec_mb_read_total_zero14, T264dec_mb_read_total_zero15
};
if(idx != BLOCK_INDEX_CHROMA_DC)
zero_left = total_zero_f[total_coeff - 1](t);
else
zero_left = T264dec_mb_read_total_zero_chroma(t, total_coeff);
}
for(i = 0 ; i < total_coeff - 1 ; i ++)
{
if (zero_left > 0)
{
run[i] = T264dec_mb_read_run_before(t, zero_left);
}
else
{
run[i] = 0;
}
zero_left -= run[i];
}
run[total_coeff - 1] = zero_left;
j = -1;
for(i = total_coeff - 1 ; i >= 0 ; i --)
{
j +=run[i] + 1;
z[j] = level[i];
}
}
}
static void __inline
T264dec_mb_read_intra_cavlc(T264_t* t)
{
int32_t i;
if (t->mb.mb_part == I_4x4)
{
int32_t cbp;
T264_mb_read_cavlc_i4x4_mode(t);
t->mb.mb_mode_uv = eg_read_ue(t->bs);
assert(t->mb.mb_mode_uv <= Intra_8x8_DC128);
cbp = i4x4_eg_to_cbp[eg_read_ue(t->bs)];
t->mb.cbp_y = cbp % 16;
t->mb.cbp_c = cbp / 16;
if (cbp > 0)
{
t->mb.mb_qp_delta = eg_read_se(t->bs);
for(i = 0 ; i < 16 ; i ++)
{
if (t->mb.cbp_y & (1 << (i / 4)))
{
T264dec_mb_read_cavlc_residual(t, i, t->mb.dct_y_z[i], 16);
}
}
}
t->mb.mb_mode = I_4x4;
}
else
{
t->mb.mode_i16x16 = i16x16_eg_to_cbp[t->mb.mb_part][0];
t->mb.cbp_y = i16x16_eg_to_cbp[t->mb.mb_part][2];
t->mb.cbp_c = i16x16_eg_to_cbp[t->mb.mb_part][1];
t->mb.mb_mode_uv = eg_read_ue(t->bs);
assert(t->mb.mb_mode_uv <= Intra_8x8_DC128);
t->mb.mb_qp_delta = eg_read_se(t->bs);
// dc luma
T264dec_mb_read_cavlc_residual(t, BLOCK_INDEX_LUMA_DC, t->mb.dc4x4_z, 16);
if (t->mb.cbp_y != 0)
{
for(i = 0 ; i < 16 ; i ++)
{
if (t->mb.cbp_y & (1 << (i / 4)))
{
T264dec_mb_read_cavlc_residual(t, i, &(t->mb.dct_y_z[i][1]), 15);
}
t->mb.dct_y_z[i][0] = t->mb.dc4x4_z[i];
}
}
t->mb.mb_mode = I_16x16;
}
}
void __inline
mb_get_directMB16x16_mv(T264_t* t)
{
T264_get_direct_mv(t, t->mb.vec);
}
void
T264dec_mb_read_cavlc(T264_t* t)
{
int32_t mb_type;
int32_t i, j;
if (t->slice_type != SLICE_I)
{
if (t->skip == -1)
{
t->skip = eg_read_ue(t->bs);
}
if (t->skip -- > 0)
{
/* skip mb block, return */
if (t->slice_type == SLICE_P)
{
T264_predict_mv_skip(t, 0, &t->mb.vec[0][0]);
copy_nvec(&t->mb.vec[0][0], &t->mb.vec[0][0], 4, 4, 4);
t->mb.mb_mode = P_MODE; /* decode as MB_16x16 */
t->mb.mb_part = MB_16x16;
return;
}
else if (t->slice_type == SLICE_B)
{
T264_get_direct_mv(t,t->mb.vec);
t->mb.mb_mode = B_MODE; /* decode as MB_16x16 */
t->mb.mb_part = MB_16x16;
t->mb.is_copy = 1;
return;
}
else
{
assert(0);
}
}
}
mb_type = eg_read_ue(t->bs);
if (t->slice_type == SLICE_P)
{
T264_vector_t vec, vec1;
t->mb.mb_part = mb_type;
mb_type = -1; /* ugly way: prevent break to i slice code */
vec.refno = 0;
vec1.refno = 0;
t->mb.mb_mode = P_MODE;
switch (t->mb.mb_part)
{
case MB_16x16:
if (t->refl0_num - 1 > 0)
{
vec.refno = eg_read_te(t->bs, t->refl0_num - 1);
}
T264_predict_mv(t, 0, 0, 4, &vec);
t->mb.vec[0][0].x = eg_read_se(t->bs) + vec.x;
t->mb.vec[0][0].y = eg_read_se(t->bs) + vec.y;
t->mb.vec[0][0].refno = vec.refno;
copy_nvec(&t->mb.vec[0][0], &t->mb.vec[0][0], 4, 4, 4);
break;
case MB_16x8:
if (t->refl0_num - 1 > 0)
{
vec.refno = eg_read_te(t->bs, t->refl0_num - 1);
vec1.refno = eg_read_te(t->bs, t->refl0_num - 1);
}
T264_predict_mv(t, 0, 0, 4, &vec);
t->mb.vec[0][0].x = eg_read_se(t->bs) + vec.x;
t->mb.vec[0][0].y = eg_read_se(t->bs) + vec.y;
t->mb.vec[0][0].refno = vec.refno;
copy_nvec(&t->mb.vec[0][0], &t->mb.vec[0][0], 4, 2, 4);
t->mb.vec_ref[VEC_LUMA + 8].vec[0] = t->mb.vec[0][0];
T264_predict_mv(t, 0, 8, 4, &vec1);
t->mb.vec[0][8].x = eg_read_se(t->bs) + vec1.x;
t->mb.vec[0][8].y = eg_read_se(t->bs) + vec1.y;
t->mb.vec[0][8].refno = vec1.refno;
copy_nvec(&t->mb.vec[0][8], &t->mb.vec[0][8], 4, 2, 4);
break;
case MB_8x16:
if (t->refl0_num - 1 > 0)
{
vec.refno = eg_read_te(t->bs, t->refl0_num - 1);
vec1.refno = eg_read_te(t->bs, t->refl0_num - 1);
}
T264_predict_mv(t, 0, 0, 2, &vec);
t->mb.vec[0][0].x = eg_read_se(t->bs) + vec.x;
t->mb.vec[0][0].y = eg_read_se(t->bs) + vec.y;
t->mb.vec[0][0].refno = vec.refno;
copy_nvec(&t->mb.vec[0][0], &t->mb.vec[0][0], 2, 4, 4);
t->mb.vec_ref[VEC_LUMA + 1].vec[0] = t->mb.vec[0][0];
T264_predict_mv(t, 0, luma_index[4], 2, &vec1);
t->mb.vec[0][luma_index[4]].x = eg_read_se(t->bs) + vec1.x;
t->mb.vec[0][luma_index[4]].y = eg_read_se(t->bs) + vec1.y;
t->mb.vec[0][luma_index[4]].refno = vec1.refno;
copy_nvec(&t->mb.vec[0][2], &t->mb.vec[0][2], 2, 4, 4);
break;
case MB_8x8:
case MB_8x8ref0:
t->mb.submb_part[luma_index[4 * 0]] = eg_read_ue(t->bs);
t->mb.submb_part[luma_index[4 * 1]] = eg_read_ue(t->bs);
t->mb.submb_part[luma_index[4 * 2]] = eg_read_ue(t->bs);
t->mb.submb_part[luma_index[4 * 3]] = eg_read_ue(t->bs);
if (t->mb.mb_part != MB_8x8ref0 && t->refl0_num - 1 > 0)
{
t->mb.vec[0][0].refno = eg_read_te(t->bs, t->refl0_num - 1);
t->mb.vec[0][luma_index[4]].refno = eg_read_te(t->bs, t->refl0_num - 1);
t->mb.vec[0][luma_index[8]].refno = eg_read_te(t->bs, t->refl0_num - 1);
t->mb.vec[0][luma_index[12]].refno = eg_read_te(t->bs, t->refl0_num - 1);
}
else
{
t->mb.vec[0][0].refno = 0;
t->mb.vec[0][luma_index[4]].refno = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -