📄 t264dec.c
字号:
//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 + -