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

📄 dec_cavlc.c

📁 经过开源的H.264压缩算法代码
💻 C
📖 第 1 页 / 共 4 页
字号:
            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)
{
}

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
            {
                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;
                t->mb.vec[0][luma_index[8]].refno = 0;
                t->mb.vec[0][luma_index[12]].refno = 0;
            }
            for(i = 0 ; i < 4 ; i ++)
            {
                switch(t->mb.submb_part[luma_index[4 * i]]) 
                {
                case 0: /* P_L0_8x8 */
                    t->mb.submb_part[luma_index[4 * i]] = MB_8x8;
                    vec = t->mb.vec[0][luma_index[4 * i]];
                    T264_predict_mv(t, 0, luma_index[4 * i], 2, &vec);
                    t->mb.vec[0][luma_index[4 * i]].x = eg_read_se(t->bs) + vec.x;
                    t->mb.vec[0][luma_index[4 * i]].y = eg_read_se(t->bs) + vec.y;

                    t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 1] = 
                    t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 4] = 
                    t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 5] = t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 0];
                    t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 0].vec[0] =
                    t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 1].vec[0] =
                    t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 8].vec[0] =
                    t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 9].vec[0] = t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 0];
                    break;
                case MB_8x4 - 4:    /* P_L0_8x4 */
                    t->mb.submb_part[luma_index[4 * i]] = MB_8x4;
                    vec.refno = t->mb.vec[0][luma_index[4 * i]].refno;
                    T264_predict_mv(t, 0, luma_index[4 * i], 2, &vec);
                    t->mb.vec[0][luma_index[4 * i]].x = eg_read_se(t->bs) + vec.x;
                    t->mb.vec[0][luma_index[4 * i]].y = eg_read_se(t->bs) + vec.y;
                    t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 0].vec[0] =
                    t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 1].vec[0] =
                    t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 1] = t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 0];

                    T264_predict_mv(t, 0, luma_index[4 * i + 2], 2, &vec);
                    t->mb.vec[0][luma_index[4 * i + 2]].x = eg_read_se(t->bs) + vec.x;
                    t->mb.vec[0][luma_index[4 * i + 2]].y = eg_read_se(t->bs) + vec.y;
                    t->mb.vec[0][luma_index[4 * i + 2]].refno = vec.refno;
                    t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 8].vec[0] =
                    t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 9].vec[0] = 
                    t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 5] = t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 4];
                    break;
                case MB_4x8 - 4:    /* P_L0_4x8 */
                    t->mb.submb_part[luma_index[4 * i]] = MB_4x8;
                    vec.refno = t->mb.vec[0][luma_index[4 * i]].refno;
                    T264_predict_mv(t, 0, luma_index[4 * i], 1, &vec);
                    t->mb.vec[0][luma_index[4 * i]].x = eg_read_se(t->bs) + vec.x;
                    t->mb.vec[0][luma_index[4 * i]].y = eg_read_se(t->bs) + vec.y;
                    t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 0].vec[0] =
                    t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 8].vec[0] =
                    t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 4] = t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 0];

                    T264_predict_mv(t, 0, luma_index[4 * i + 1], 1, &vec);
                    t->mb.vec[0][luma_index[4 * i + 1]].x = eg_read_se(t->bs) + vec.x;
                    t->mb.vec[0][luma_index[4 * i + 1]].y = eg_read_se(t->bs) + vec.y;
                    t->mb.vec[0][luma_index[4 * i + 1]].refno = vec.refno;
                    t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 1].vec[0] =
                    t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 9].vec[0] =
                    t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 5] = t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 1];
                    break;
                case MB_4x4 - 4:        /* P_L0_4x4 */
                    t->mb.submb_part[luma_index[4 * i]] = MB_4x4;
                    vec = t->mb.vec[0][luma_index[4 * i]];
                    T264_predict_mv(t, 0, luma_index[4 * i], 1, &vec);
                    t->mb.vec[0][luma_index[4 * i]].x = eg_read_se(t->bs) + vec.x;
                    t->mb.vec[0][luma_index[4 * i]].y = eg_read_se(t->bs) + vec.y;
                    t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 0].vec[0] = t->mb.vec[0][luma_index[4 * i]];

                    T264_predict_mv(t, 0, luma_index[4 * i + 1], 1, &vec);
                    t->mb.vec[0][luma_index[4 * i + 1]].x = eg_read_se(t->bs) + vec.x;
                    t->mb.vec[0][luma_index[4 * i + 1]].y = eg_read_se(t->bs) + vec.y;
                    t->mb.vec[0][luma_index[4 * i + 1]].refno = vec.refno;
                    t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 1].vec[0] = t->mb.vec[0][luma_index[4 * i + 1]];

                    T264_predict_mv(t, 0, luma_index[4 * i + 2], 1, &vec);
                    t->mb.vec[0][luma_index[4 * i + 2]].x = eg_read_se(t->bs) + vec.x;
                    t->mb.vec[0][luma_index[4 * i + 2]].y = eg_read_se(t->bs) + vec.y;
                    t->mb.vec[0][luma_index[4 * i + 2]].refno = vec.refno;
                    t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 8].vec[0] = t->mb.vec[0][luma_index[4 * i + 2]];

                    T264_predict_mv(t, 0, luma_index[4 * i + 3], 1, &vec);
                    t->mb.vec[0][luma_index[4 * i + 3]].x = eg_read_se(t->bs) + vec.x;
                    t->mb.vec[0][luma_index[4 * i + 3]].y = eg_read_se(t->bs) + vec.y;
                    t->mb.vec[0][luma_index[4 * i + 3]].refno = vec.refno;
                    t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 9].vec[0] = t->mb.vec[0][luma_index[4 * i + 3]];
                    break;
                }
            }
            break;
        default:
            t->mb.mb_part -= 5;
            T264dec_mb_read_intra_cavlc(t);

            /* save ref */
            memset(t->mb.submb_part, -1, sizeof(t->mb.submb_part));
            t->mb.mb_part = -1;
            for(i = 0 ; i < 2 ; i ++)
            {
                for(j = 0 ; j < 16 ; j ++)
                {
                    INITINVALIDVEC(t->mb.vec[i][j]);
                }
            }
            break;
        }
       INITINVALIDVEC(t->mb.vec[1][0]);
       copy_nvec(&t->mb.vec[1][0], &t->mb.vec[1][0], 4, 4, 4);
    }
    else 
    {
        t->mb.mb_part = mb_type;
        T264dec_mb_read_intra_cavlc(t);
    }

    if (t->mb.mb_mode != I_16x16 && t->mb.mb_mode != I_4x4)
    {
        int32_t cbp;

        cbp = inter_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);
                }
            }
        }
    }
    if (t->mb.cbp_c != 0)
    {
        T264dec_mb_read_cavlc_residual(t, BLOCK_INDEX_CHROMA_DC, t->mb.dc2x2_z[0], 4);
        T264dec_mb_read_cavlc_residual(t, BLOCK_INDEX_CHROMA_DC, t->mb.dc2x2_z[1], 4);
        if (t->mb.cbp_c & 0x2)
        {
            for(i = 0 ; i < 4 ; i ++)
            {
                T264dec_mb_read_cavlc_residual(t, 16 + i, &(t->mb.dct_uv_z[0][i % 4][1]), 15);
                t->mb.dct_uv_z[0][i][0] = t->mb.dc2x2_z[0][i];
            }
            for(i = 0 ; i < 4 ; i ++)
            {
                T264dec_mb_read_cavlc_residual(t, 20 + i, &(t->mb.dct_uv_z[1][i % 4][1]), 15);
                t->mb.dct_uv_z[1][i][0] = t->mb.dc2x2_z[1][i];
            }
        }
        else
        {
            for(i = 0 ; i < 4 ; i ++)
            {
                t->mb.dct_uv_z[0][i][0] = t->mb.dc2x2_z[0][i];
                t->mb.dct_uv_z[1][i][0] = t->mb.dc2x2_z[1][i];
            }
        }
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -