📄 umc_h264_dec_bitstream.cpp
字号:
hdr->first_mb_in_slice = GetVLCElement(false);
if (0 > hdr->first_mb_in_slice)
return UMC_ERR_INVALID_STREAM;
// slice type
val = GetVLCElement(false);
if (val > S_INTRASLICE)
{
if (val > S_INTRASLICE + S_INTRASLICE + 1)
{
return UMC_ERR_INVALID_STREAM;
}
else
{
// Slice type is specifying type of not only this but all remaining
// slices in the picture. Since slice type is always present, this bit
// of info is not used in our implementation. Adjust (just shift range)
// and return type without this extra info.
val -= (S_INTRASLICE + 1);
}
}
if (val > INTRASLICE) // all other doesn't support
return UMC_ERR_INVALID_STREAM;
hdr->slice_type = (EnumSliceCodType)val;
hdr->pic_parameter_set_id = (Ipp16u)GetVLCElement(false);
if (hdr->pic_parameter_set_id > MAX_NUM_PIC_PARAM_SETS-1)
{
return UMC_ERR_INVALID_STREAM;
}
return UMC_OK;
} // Status H264Bitstream::GetSliceHeaderPart1(H264SliceHeader *pSliceHeader)
Status H264Bitstream::GetSliceHeaderPart2(
H264SliceHeader *hdr, // slice header read goes here
const H264PicParamSet *pps,
bool bIsIDRSlice,
const H264SeqParamSet *sps,
Ipp8u NALRef_idc) // from slice header NAL unit
{
hdr->frame_num = GetBits(sps->log2_max_frame_num);
hdr->idr_flag = (Ipp8u) bIsIDRSlice;
hdr->nal_ref_idc = NALRef_idc;
hdr->bottom_field_flag = 0;
if (sps->frame_mbs_only_flag == 0)
{
hdr->field_pic_flag = (Ipp8u)Get1Bit();
hdr->MbaffFrameFlag = !hdr->field_pic_flag && sps->mb_adaptive_frame_field_flag;
if (hdr->field_pic_flag != 0)
{
hdr->bottom_field_flag = (Ipp8u)Get1Bit();
}
}
// correct frst_mb_in_slice in order to handle MBAFF
if (hdr->MbaffFrameFlag && hdr->first_mb_in_slice)
hdr->first_mb_in_slice <<= 1;
if (hdr->idr_flag)
{
hdr->idr_pic_id = GetVLCElement(false);
if (hdr->idr_pic_id < 0 || hdr->idr_pic_id > 65535)
return UMC_ERR_INVALID_STREAM;
}
if (sps->pic_order_cnt_type == 0)
{
hdr->pic_order_cnt_lsb = GetBits(sps->log2_max_pic_order_cnt_lsb);
if (pps->pic_order_present_flag && (!hdr->field_pic_flag))
hdr->delta_pic_order_cnt_bottom = GetVLCElement(true);
}
if ((sps->pic_order_cnt_type == 1) && (sps->delta_pic_order_always_zero_flag == 0))
{
hdr->delta_pic_order_cnt[0] = GetVLCElement(true);
if (pps->pic_order_present_flag && (!hdr->field_pic_flag))
hdr->delta_pic_order_cnt[1] = GetVLCElement(true);
}
if (pps->redundant_pic_cnt_present_flag)
{
// redundant pic count
hdr->redundant_pic_cnt = GetVLCElement(false);
}
return UMC_OK;
}
// ---------------------------------------------------------------------------
// Read H.264 second part of slice header
//
// Do not print debug messages when IsSearch is true. In that case the function
// is being used to find the next compressed frame, errors may occur and should
// not be reported.
// ---------------------------------------------------------------------------
Status H264Bitstream::GetSliceHeaderPart3(
H264SliceHeader *hdr, // slice header read goes here
PredWeightTable *pPredWeight_L0, // L0 weight table goes here
PredWeightTable *pPredWeight_L1, // L1 weight table goes here
RefPicListReorderInfo *pReorderInfo_L0,
RefPicListReorderInfo *pReorderInfo_L1,
AdaptiveMarkingInfo *pAdaptiveMarkingInfo,
const H264PicParamSet *pps,
const H264SeqParamSet *sps,
Ipp8u NALRef_idc) // from slice header NAL unit
{
Ipp8u ref_pic_list_reordering_flag_l0 = 0;
Ipp8u ref_pic_list_reordering_flag_l1 = 0;
if (BPREDSLICE == hdr->slice_type)
{
// direct mode prediction method
hdr->direct_spatial_mv_pred_flag = (Ipp8u)Get1Bit();
}
if (PREDSLICE == hdr->slice_type ||
S_PREDSLICE == hdr->slice_type ||
BPREDSLICE == hdr->slice_type)
{
hdr->num_ref_idx_active_override_flag = (Ipp8u)Get1Bit();
if (hdr->num_ref_idx_active_override_flag != 0)
// ref idx active l0 and l1
{
hdr->num_ref_idx_l0_active = GetVLCElement(false) + 1;
if (BPREDSLICE == hdr->slice_type)
hdr->num_ref_idx_l1_active = GetVLCElement(false) + 1;
}
else
{
// no overide, use num active from pic param set
hdr->num_ref_idx_l0_active = pps->num_ref_idx_l0_active;
if (BPREDSLICE == hdr->slice_type)
hdr->num_ref_idx_l1_active = pps->num_ref_idx_l1_active;
else
hdr->num_ref_idx_l1_active = 0;
}
} // ref idx override
if (hdr->num_ref_idx_l1_active > MAX_NUM_REF_FRAMES || hdr->num_ref_idx_l0_active > MAX_NUM_REF_FRAMES)
return UMC_ERR_INVALID_STREAM;
if (hdr->slice_type != INTRASLICE && hdr->slice_type != S_INTRASLICE)
{
Ipp32u reordering_of_pic_nums_idc;
Ipp32u reorder_idx;
// Reference picture list reordering
ref_pic_list_reordering_flag_l0 = (Ipp8u)Get1Bit();
if (ref_pic_list_reordering_flag_l0)
{
bool bOk = true;
reorder_idx = 0;
reordering_of_pic_nums_idc = 0;
// Get reorder idc,pic_num pairs until idc==3
while (bOk)
{
reordering_of_pic_nums_idc = (Ipp8u)GetVLCElement(false);
if (reordering_of_pic_nums_idc == 3)
break;
if (reorder_idx >= MAX_NUM_REF_FRAMES)
{
return UMC_ERR_INVALID_STREAM;
}
pReorderInfo_L0->reordering_of_pic_nums_idc[reorder_idx] =
(Ipp8u)reordering_of_pic_nums_idc;
pReorderInfo_L0->reorder_value[reorder_idx] =
GetVLCElement(false);
if (reordering_of_pic_nums_idc < 2)
// abs_diff_pic_num is coded minus 1
pReorderInfo_L0->reorder_value[reorder_idx]++;
reorder_idx++;
} // while
pReorderInfo_L0->num_entries = reorder_idx;
} // L0 reordering info
else
pReorderInfo_L0->num_entries = 0;
if (BPREDSLICE == hdr->slice_type)
{
ref_pic_list_reordering_flag_l1 = (Ipp8u)Get1Bit();
if (ref_pic_list_reordering_flag_l1)
{
bool bOk = true;
// Get reorder idc,pic_num pairs until idc==3
reorder_idx = 0;
reordering_of_pic_nums_idc = 0;
while (bOk)
{
reordering_of_pic_nums_idc = (Ipp8u)GetVLCElement(false);
if (reordering_of_pic_nums_idc == 3)
break;
if (reorder_idx >= MAX_NUM_REF_FRAMES)
{
return UMC_ERR_INVALID_STREAM;
}
pReorderInfo_L1->reordering_of_pic_nums_idc[reorder_idx] =
(Ipp8u)reordering_of_pic_nums_idc;
pReorderInfo_L1->reorder_value[reorder_idx] =
GetVLCElement(false);
if (reordering_of_pic_nums_idc < 2)
// abs_diff_pic_num is coded minus 1
pReorderInfo_L1->reorder_value[reorder_idx]++;
reorder_idx++;
} // while
pReorderInfo_L1->num_entries = reorder_idx;
} // L1 reordering info
else
pReorderInfo_L1->num_entries = 0;
} // B slice
} // reordering info
// prediction weight table
if ( (pps->weighted_pred_flag &&
((PREDSLICE == hdr->slice_type) || (S_PREDSLICE == hdr->slice_type))) ||
((pps->weighted_bipred_idc == 1) && (BPREDSLICE == hdr->slice_type)))
{
Ipp32s refindex;
hdr->luma_log2_weight_denom = (Ipp8u)GetVLCElement(false);
hdr->chroma_log2_weight_denom = (Ipp8u)GetVLCElement(false);
for (refindex=0; refindex<hdr->num_ref_idx_l0_active; refindex++)
{
pPredWeight_L0[refindex].luma_weight_flag = (Ipp8u)Get1Bit();
if (pPredWeight_L0[refindex].luma_weight_flag)
{
pPredWeight_L0[refindex].luma_weight = (Ipp8s)GetVLCElement(true);
pPredWeight_L0[refindex].luma_offset = (Ipp8s)GetVLCElement(true);
}
else
{
pPredWeight_L0[refindex].luma_weight = (Ipp8s)(1 << hdr->luma_log2_weight_denom);
pPredWeight_L0[refindex].luma_offset = 0;
}
pPredWeight_L0[refindex].chroma_weight_flag = (Ipp8u)Get1Bit();
if (pPredWeight_L0[refindex].chroma_weight_flag)
{
pPredWeight_L0[refindex].chroma_weight[0] = (Ipp8s)GetVLCElement(true);
pPredWeight_L0[refindex].chroma_offset[0] = (Ipp8s)GetVLCElement(true);
pPredWeight_L0[refindex].chroma_weight[1] = (Ipp8s)GetVLCElement(true);
pPredWeight_L0[refindex].chroma_offset[1] = (Ipp8s)GetVLCElement(true);
}
else
{
pPredWeight_L0[refindex].chroma_weight[0] = (Ipp8s)(1 << hdr->chroma_log2_weight_denom);
pPredWeight_L0[refindex].chroma_weight[1] = (Ipp8s)(1 << hdr->chroma_log2_weight_denom);
pPredWeight_L0[refindex].chroma_offset[0] = 0;
pPredWeight_L0[refindex].chroma_offset[1] = 0;
}
}
if (BPREDSLICE == hdr->slice_type)
{
for (refindex=0; refindex<hdr->num_ref_idx_l1_active; refindex++)
{
pPredWeight_L1[refindex].luma_weight_flag = (Ipp8u)Get1Bit();
if (pPredWeight_L1[refindex].luma_weight_flag)
{
pPredWeight_L1[refindex].luma_weight = (Ipp8s)GetVLCElement(true);
pPredWeight_L1[refindex].luma_offset = (Ipp8s)GetVLCElement(true);
}
else
{
pPredWeight_L1[refindex].luma_weight = (Ipp8s)(1 << hdr->luma_log2_weight_denom);
pPredWeight_L1[refindex].luma_offset = 0;
}
pPredWeight_L1[refindex].chroma_weight_flag = (Ipp8u)Get1Bit();
if (pPredWeight_L1[refindex].chroma_weight_flag)
{
pPredWeight_L1[refindex].chroma_weight[0] = (Ipp8s)GetVLCElement(true);
pPredWeight_L1[refindex].chroma_offset[0] = (Ipp8s)GetVLCElement(true);
pPredWeight_L1[refindex].chroma_weight[1] = (Ipp8s)GetVLCElement(true);
pPredWeight_L1[refindex].chroma_offset[1] = (Ipp8s)GetVLCElement(true);
}
else
{
pPredWeight_L1[refindex].chroma_weight[0] = (Ipp8s)(1 << hdr->chroma_log2_weight_denom);
pPredWeight_L1[refindex].chroma_weight[1] = (Ipp8s)(1 << hdr->chroma_log2_weight_denom);
pPredWeight_L1[refindex].chroma_offset[0] = 0;
pPredWeight_L1[refindex].chroma_offset[1] = 0;
}
}
} // B slice
} // prediction weight table
else
{
hdr->luma_log2_weight_denom = 0;
hdr->chroma_log2_weight_denom = 0;
}
// dec_ref_pic_marking
pAdaptiveMarkingInfo->num_entries = 0;
if (NALRef_idc)
{
if (hdr->idr_flag)
{
hdr->no_output_of_prior_pics_flag = (Ipp8u)Get1Bit();
hdr->long_term_reference_flag = (Ipp8u)Get1Bit();
}
else
{
Ipp32u memory_management_control_operation;
Ipp32u num_entries = 0;
hdr->adaptive_ref_pic_marking_mode_flag = (Ipp8u)Get1Bit();
while (hdr->adaptive_ref_pic_marking_mode_flag != 0)
{
memory_management_control_operation = (Ipp8u)GetVLCElement(false);
if (memory_management_control_operation == 0)
break;
if (memory_management_control_operation > 6)
return UMC_ERR_INVALID_STREAM;
pAdaptiveMarkingInfo->mmco[num_entries] =
(Ipp8u)memory_management_control_operation;
if (memory_management_control_operation != 5)
pAdaptiveMarkingInfo->value[num_entries*2] =
GetVLCElement(false);
// Only mmco 3 requires 2 values
if (memory_management_control_operation == 3)
pAdaptiveMarkingInfo->value[num_entries*2+1] =
GetVLCElement(false);
num_entries++;
if (num_entries >= MAX_NUM_REF_FRAMES)
{
return UMC_ERR_INVALID_STREAM;
}
} // while
pAdaptiveMarkingInfo->num_entries = num_entries;
}
} // def_ref_pic_marking
if (pps->entropy_coding_mode == 1 && // CABAC
(hdr->slice_type != INTRASLICE && hdr->slice_type != S_INTRASLICE))
hdr->cabac_init_idc = (Ipp8u)GetVLCElement(false);
else
hdr->cabac_init_idc = 0;
if (hdr->cabac_init_idc > 2)
return UMC_ERR_INVALID_STREAM;
hdr->slice_qp_delta = (Ipp8s)GetVLCElement(true);
if (S_PREDSLICE == hdr->slice_type ||
S_INTRASLICE == hdr->slice_type)
{
if (S_PREDSLICE == hdr->slice_type)
hdr->sp_for_switch_flag = (Ipp8u)Get1Bit();
hdr->s
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -