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

📄 t264dec.c

📁 T264是中国的视频编码自由组织合力开发的264编解码程序
💻 C
📖 第 1 页 / 共 2 页
字号:
	//for dec CABAC
	if( t->ps.entroy_coding_mode_flag == 1 )
	{
		T264_cabac_model_update( &t->cabac, t->slice_type, t->ps.pic_init_qp_minus26+26 + t->slice.slice_qp_delta );
	}
    get_output_frame(t);

    if (t->slice_type != SLICE_B)
    {
        T264dec_save_ref(t);
    }
    else if (t->need_deblock)
    {
        T264_deblock_frame(t, t->rec);
    }
    t->emms();
}

void
T264dec_parse_pic_header(T264_t* t)
{
    t->ps.pic_id = eg_read_ue(t->bs);
    t->ps.seq_id = eg_read_ue(t->bs);
    assert(t->ps.pic_id == 0 && t->ps.seq_id == 0);
    t->ps.entroy_coding_mode_flag = eg_read_direct(t->bs, 1);
	//for dec CABAC, now support CABAC
    //assert(t->ps.entroy_coding_mode_flag == 0);
    t->ps.pic_order_present_flag = eg_read_direct(t->bs, 1);
    assert(t->ps.pic_order_present_flag == 0);
    t->ps.num_slice_groups_minus1 = eg_read_ue(t->bs);
    assert(t->ps.num_slice_groups_minus1 == 0);
    t->ps.num_ref_idx_l0_active_minus1 = eg_read_ue(t->bs);
    t->ps.num_ref_idx_l1_active_minus1 = eg_read_ue(t->bs);
    t->ps.weighted_pred_flag = eg_read_direct(t->bs, 1);
    t->ps.weighted_bipred_idc = eg_read_direct(t->bs, 2);
    t->ps.pic_init_qp_minus26 = eg_read_se(t->bs);
    t->ps.pic_init_qs_minus26 = eg_read_se(t->bs);
    t->ps.chroma_qp_index_offset = eg_read_se(t->bs);
    t->ps.deblocking_filter_control_present_flag = eg_read_direct(t->bs, 1);

    t->refl0_num = t->ps.num_ref_idx_l0_active_minus1 + 1;
    t->refl1_num = t->ps.num_ref_idx_l1_active_minus1 + 1;
    t->qp_y = t->ps.pic_init_qp_minus26 + 26;
}

void
T264dec_parse_seq_header(T264_t* t)
{
    int32_t i;
    int32_t prev_ref_num = t->ss.num_ref_frames;

    t->ss.profile_idc = eg_read_direct(t->bs, 8);
    eg_read_skip(t->bs, 8);
    t->ss.level_idc = eg_read_direct(t->bs, 8);
    t->ss.seq_id = eg_read_ue(t->bs);
    assert(t->ss.seq_id == 0);
    t->ss.log2_max_frame_num_minus4 = eg_read_ue(t->bs);
    t->ss.pic_order_cnt_type = eg_read_ue(t->bs);
    assert(t->ss.pic_order_cnt_type == 0);
    if (t->ss.pic_order_cnt_type == 0)
    {
        t->ss.max_pic_order = eg_read_ue(t->bs);
    }

    t->ss.num_ref_frames = eg_read_ue(t->bs);
    eg_read_skip(t->bs, 1);
    t->ss.pic_width_in_mbs_minus1 = eg_read_ue(t->bs);
    t->ss.pic_height_in_mbs_minus1 = eg_read_ue(t->bs);
    t->ss.frame_mbs_only_flag = eg_read_direct(t->bs, 1);
    assert(t->ss.frame_mbs_only_flag == 1);
    eg_read_skip(t->bs, 2);
    // vui_parameters_present_flag
    if (eg_read_direct(t->bs, 1))
    {
        // aspect_ratio_info_present_flag
        if (eg_read_direct(t->bs, 1) == 1)
            t->aspect_ratio = eg_read_direct(t->bs, 8);
        // overscan_info_present_flag
        eg_read_skip(t->bs, 1);
        // video_signal_type_present_flag
        if (eg_read_direct(t->bs, 1) == 1)
            t->video_format = eg_read_direct(t->bs, 3);
        // others discard
    }
    t->mb_height = t->ss.pic_height_in_mbs_minus1 + 1;
    t->mb_width = t->ss.pic_width_in_mbs_minus1 + 1;
    t->width = t->mb_width * 16;
    t->height = t->mb_height * 16;
    t->edged_width = t->width + 2 * EDGED_WIDTH;
    t->edged_height = t->height + 2 * EDGED_HEIGHT;
    t->stride    = t->width;
    t->stride_uv = t->width >> 1;
    t->edged_stride = t->edged_width;
    t->edged_stride_uv = t->edged_width >> 1;
    t->mb_stride = t->mb_width;

    /* malloc ref frame buffer */
    /* first we malloc current decode buffer */
    if (t->refn[0].Y[0] == 0)
    {
        uint8_t* p = T264_malloc(t->edged_width * t->edged_height + (t->edged_width * t->edged_height >> 1), CACHE_SIZE);
        t->refn[0].Y[0] = p + EDGED_HEIGHT * t->edged_width + EDGED_WIDTH;
        t->refn[0].U = p + t->edged_width * t->edged_height + (t->edged_width * EDGED_HEIGHT >> 2) + (EDGED_WIDTH >> 1);
        t->refn[0].V = p + t->edged_width * t->edged_height + (t->edged_width * t->edged_height >> 2) + (t->edged_width * EDGED_HEIGHT >> 2) + (EDGED_WIDTH >> 1);
        t->refn[0].mb = T264_malloc(t->mb_height * t->mb_width * sizeof(T264_mb_context_t), CACHE_SIZE);
        p = T264_malloc(t->edged_width * t->edged_height * 3, CACHE_SIZE);
        t->refn[0].Y[1] = p + EDGED_HEIGHT * t->edged_width + EDGED_WIDTH;
        t->refn[0].Y[2] = t->refn[0].Y[1] + t->edged_width * t->edged_height;
        t->refn[0].Y[3] = t->refn[0].Y[2] + t->edged_width * t->edged_height;
    }
    for (i = prev_ref_num ; i < t->ss.num_ref_frames ; i ++)
    {
        uint8_t* p = T264_malloc(t->edged_width * t->edged_height + (t->edged_width * t->edged_height >> 1), CACHE_SIZE);
        t->refn[i + 1].Y[0] = p + EDGED_HEIGHT * t->edged_width + EDGED_WIDTH;
        t->refn[i + 1].U = p + t->edged_width * t->edged_height + (t->edged_width * EDGED_HEIGHT >> 2) + (EDGED_WIDTH >> 1);
        t->refn[i + 1].V = p + t->edged_width * t->edged_height + (t->edged_width * t->edged_height >> 2) + (t->edged_width * EDGED_HEIGHT >> 2) + (EDGED_WIDTH >> 1);
        t->refn[i + 1].mb = T264_malloc(t->mb_height * t->mb_width * sizeof(T264_mb_context_t), CACHE_SIZE);
        p = T264_malloc(t->edged_width * t->edged_height * 3, CACHE_SIZE);
        t->refn[i + 1].Y[1] = p + EDGED_HEIGHT * t->edged_width + EDGED_WIDTH;
        t->refn[i + 1].Y[2] = t->refn[i + 1].Y[1] + t->edged_width * t->edged_height;
        t->refn[i + 1].Y[3] = t->refn[i + 1].Y[2] + t->edged_width * t->edged_height;
    }
    t->refl0_num = 0;
    t->refl1_num = 0;
}

void
T264dec_parse_custom_set(T264_t* t)
{
    int32_t encoder_ver = eg_read_direct(t->bs, 32);
    int32_t flag = eg_read_direct(t->bs, 32);

    if (flag & CUSTOM_FASTINTERPOLATE)
        t->flags |= USE_FASTINTERPOLATE;
}

void
T264dec_custom_buffer(T264_t* t, uint8_t* buf, int32_t stride)
{
}

decoder_state_t
T264dec_copy_nal(T264_t* t)
{
    uint8_t tmp;
    uint32_t shift;
    uint32_t shift1;

    shift = t->shift;
    shift1 = t->shift1;

    while (t->src_buf < t->src_end)
    {
        tmp = *t->src_buf ++;
        shift1 = (shift1 | tmp) << 8;

        if (shift1 == 0x00000300)
        {
            shift1 = 0xffffff00;    /* reset state */

            /* shift == x x 0 0 ==> shift == x x 0 ff
               here we need to prevent the next few words become a wrong start code */
            shift |= 0xff;

            continue;
        }

        shift = (shift << 8) | tmp;
        if (shift == 0x00000001)
        {
            t->shift1 = 0xffffff00;
            t->shift = -1;
            /* we do not copy the next start code */
            t->nal_len -= 3;
            return DEC_STATE_OK;
        }
        t->nal_buf[t->nal_len ++] = tmp;
    }

    t->shift = shift;
    t->shift1 = shift1;

    return DEC_STATE_BUFFER;
}

decoder_state_t
T264dec_find_nal(T264_t* t)
{
    int32_t find = 0;
    uint8_t tmp;
    uint32_t shift;

    shift = t->shift;	

    while (t->src_buf < t->src_end)
    {
        tmp = *t->src_buf ++;
        shift = (shift << 8) | tmp;
        
        if (shift == 0x00000001)
        {
            t->shift = -1;
            t->nal_len = 0;
            find = 1;
            break;
        }
    }

    if (find)
    {
        t->action = T264dec_copy_nal;
        return T264dec_parse(t);
    }

    t->shift = shift;	

    return DEC_STATE_BUFFER;
}

decoder_state_t
T264dec_decode_nal(T264_t* t)
{
    eg_init(t->bs, t->nal_buf, t->nal_len);

    /* ready for next nal */
    t->action = T264dec_copy_nal;
    t->nal_len = 0;

    eg_read_skip(t->bs, 1);  /* discard forbidden + nal_ref_idc */
    t->nal.nal_ref_idc = eg_read_direct(t->bs, 2);
    t->nal.nal_unit_type = eg_read_direct(t->bs, 5);

    switch (t->nal.nal_unit_type)
    {
    case NAL_SLICE_NOPART:
        T264dec_parse_slice(t);
        t->frame_num ++;
        t->frame_id ++;
        return DEC_STATE_SLICE;
    case NAL_PIC_SET:
        T264dec_parse_pic_header(t);
        return DEC_STATE_PIC;
    case NAL_SLICE_IDR:
        T264dec_parse_slice(t);
        t->frame_num ++;
        t->frame_id ++;
        return DEC_STATE_SLICE;
    case NAL_SEQ_SET:
        T264dec_parse_seq_header(t);
        t->frame_num = 0;
        return DEC_STATE_SEQ;
    case NAL_CUSTOM_SET:
        T264dec_parse_custom_set(t);
        return DEC_STATE_CUSTOM_SET;
    default:
        assert(0);
        break;
    }

    return DEC_STATE_UNKOWN;
}

T264_t*
T264dec_open()
{
    T264_t* t = T264_malloc(sizeof(T264_t), CACHE_SIZE);
	int i, j;
    memset(t, 0, sizeof(T264_t));

    t->nal_buf = T264_malloc(NAL_BUFFER_LEN, CACHE_SIZE);
    t->bs = T264_malloc(sizeof(bs_t), CACHE_SIZE);

	//for cabac
	for(j=0; j<4; j++)
	{
		for(i=5; i<8; i++)
		{
			t->mb.vec_ref[(j<<3)+i].vec[0].refno = -2;
			t->mb.vec_ref[(j<<3)+i].vec[0].x = 0;
			t->mb.vec_ref[(j<<3)+i].vec[0].y = 0;
			t->mb.vec_ref[(j<<3)+i].vec[1].refno = -2;
			t->mb.vec_ref[(j<<3)+i].vec[1].x = 0;
			t->mb.vec_ref[(j<<3)+i].vec[1].y = 0;
		}
	}
    T264_init_cpu(t);

    t->action = T264dec_find_nal;
    t->shift = -1;
    t->shift1 = 0xffffff00;

    t->need_deblock = 1;
    t->flags = USE_HALFPEL| USE_QUARTPEL;   /* interpolate func needs this flag */

    return t;
}

void
T264dec_close(T264_t* t)
{
    int32_t i;

    for(i = 0 ; i < t->ss.num_ref_frames + 1 ; i ++)
    {
        T264_free(t->refn[i].Y[0] - (EDGED_HEIGHT * t->edged_width + EDGED_WIDTH));
        T264_free(t->refn[i].mb);
        T264_free(t->refn[i].Y[1] - (EDGED_HEIGHT * t->edged_width + EDGED_WIDTH));
    }
    T264_free(t->bs);
    T264_free(t->nal_buf);
    T264_free(t);
}

void
T264dec_buffer(T264_t* t, uint8_t* buf, int32_t len)
{
    t->src_buf = buf;
    t->src_end = buf + len;
}

decoder_state_t
T264dec_parse(T264_t* t)
{
    if (t->action(t) == DEC_STATE_BUFFER)
    {
        return DEC_STATE_BUFFER;
    }

    return T264dec_decode_nal(t);
}

T264_frame_t* 
T264dec_flush_frame(T264_t* t)
{
    /* the last i/p frame */
    return &t->refn[1];
}

⌨️ 快捷键说明

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