⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dec_cavlc.c

📁 T264是中国的视频编码自由组织合力开发的264编解码程序
💻 C
📖 第 1 页 / 共 5 页
字号:
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 + -