📄 umc_h264_bs.cpp
字号:
VM_ASSERT(0); //Not yet supported
}
if( seq_parms.vui_parameters.nal_hrd_parameters_present_flag ||
seq_parms.vui_parameters.vcl_hrd_parameters_present_flag){
PutBit(seq_parms.vui_parameters.low_delay_hrd_flag);
}
PutBit( seq_parms.vui_parameters.pic_struct_present_flag );
PutBit( seq_parms.vui_parameters.bitstream_restriction_flag );
if(seq_parms.vui_parameters.bitstream_restriction_flag){
PutBit(seq_parms.vui_parameters.motion_vectors_over_pic_boundaries_flag);
PutVLCCode(seq_parms.vui_parameters.max_bytes_per_pic_denom);
PutVLCCode(seq_parms.vui_parameters.max_bits_per_mb_denom);
PutVLCCode(seq_parms.vui_parameters.log2_max_mv_length_horizontal);
PutVLCCode(seq_parms.vui_parameters.log2_max_mv_length_vertical);
PutVLCCode(seq_parms.vui_parameters.num_reorder_frames);
PutVLCCode(seq_parms.vui_parameters.max_dec_frame_buffering);
}
}
return ps;
} // CH264pBs::PutSeqParms()
// ---------------------------------------------------------------------------
// CH264pBs::PutPicParms()
// ---------------------------------------------------------------------------
template <class PixType, class CoeffsType>
Status CH264pBs<PixType,CoeffsType>::PutPicParms(const H264PicParamSet & pic_parms,
const H264SeqParamSet & seq_parms) // seq_parms)
{
Status ps = UMC_OK;
// Write IDs
PutVLCCode(pic_parms.pic_parameter_set_id);
PutVLCCode(pic_parms.seq_parameter_set_id);
// Write Entropy coding mode
PutBit(pic_parms.entropy_coding_mode);
PutBit(pic_parms.pic_order_present_flag);
// Only one slice group is currently supported
// Write num_slice_groups_minus1
PutVLCCode(pic_parms.num_slice_groups - 1);
// If multiple slice groups are ever supported, then add code here
// to write the slice group map information needed to allocate MBs
// to the defined slice groups.
// Write num_ref_idx_active counters
// Right now these are limited to one frame each...
PutVLCCode(pic_parms.num_ref_idx_l0_active - 1);
PutVLCCode(pic_parms.num_ref_idx_l1_active - 1);
// Write some various flags
// Weighted pred for P slices is not supported
PutBit(pic_parms.weighted_pred_flag);
// Explicit weighted BiPred not supported
// So 0 or 2 are the acceptable values
PutBits(pic_parms.weighted_bipred_idc, 2);
// Write quantization values
PutVLCCode(SIGNED_VLC_CODE(pic_parms.pic_init_qp - 26));
PutVLCCode(SIGNED_VLC_CODE(pic_parms.pic_init_qs - 26));
PutVLCCode(SIGNED_VLC_CODE(pic_parms.chroma_qp_index_offset));
// Write some more flags
PutBit(pic_parms.deblocking_filter_variables_present_flag);
PutBit(pic_parms.constrained_intra_pred_flag);
PutBit(pic_parms.redundant_pic_cnt_present_flag);
if(seq_parms.profile_idc == H264_HIGH_PROFILE ||
seq_parms.profile_idc == H264_HIGH10_PROFILE ||
seq_parms.profile_idc == H264_HIGH422_PROFILE ||
seq_parms.profile_idc == H264_HIGH444_PROFILE) {
PutBit(pic_parms.transform_8x8_mode_flag);
PutBit(pic_parms.pic_scaling_matrix_present_flag);
if(pic_parms.pic_scaling_matrix_present_flag) {
VM_ASSERT(0 /* scaling matrices coding is not supported */);
// TO DO: add scaling matrices coding.
}
PutVLCCode(SIGNED_VLC_CODE(pic_parms.second_chroma_qp_index_offset));
}
return ps;
} // CH264pBs::PutPicParms()
// ---------------------------------------------------------------------------
// CH264pBs::PutPicDelimiter()
// ---------------------------------------------------------------------------
template <class PixType, class CoeffsType>
Status CH264pBs<PixType,CoeffsType>::PutPicDelimiter(EnumPicCodType PicCodType)
{
Status ps = UMC_OK;
// Write pic_type
PutBits(PicCodType, 3);
return ps;
} // CH264pBs::PutPicDelimiter()
// ---------------------------------------------------------------------------
// CH264pBs::PutDQUANT()
// ---------------------------------------------------------------------------
template <class PixType, class CoeffsType>
void CH264pBs<PixType,CoeffsType>::PutDQUANT(const Ipp32u quant, const Ipp32u quant_prev)
{
Ipp32s dquant;
// compute dquant
dquant=quant-quant_prev;
// Get dquant between (QP_RANGE-1) to (-QP_RANGE) (25 to -26 for JVT)
if (dquant >= H264_QP_RANGE)
dquant = dquant - H264_QP_MAX;
else if (dquant < -H264_QP_RANGE)
dquant = dquant + H264_QP_MAX;
PutVLCCode(SIGNED_VLC_CODE(dquant));
} // CH264pbs::PutDQUANT()
// ---------------------------------------------------------------------------
// CH264pBs::PutSliceHeader()
// ---------------------------------------------------------------------------
template <class PixType, class CoeffsType>
Status CH264pBs<PixType,CoeffsType>::PutSliceHeader(const H264SliceHeader& slice_hdr,
const H264PicParamSet& pic_parms,
const H264SeqParamSet& seq_parms,
const EnumPicClass& ePictureClass,
const H264EncoderThreadPrivateSlice<PixType, CoeffsType> *curr_slice)
{
EnumSliceType slice_type = curr_slice->m_slice_type;
Status ps = UMC_OK;
// Write first_mb_in_slice
PutVLCCode(curr_slice->m_first_mb_in_slice);
// Write slice_type_idc
PutVLCCode(slice_type);
// Write pic_parameter_set_id
PutVLCCode(slice_hdr.pic_parameter_set_id);
// Write frame_num (modulo MAX_FN) using log2_max_frame_num bits
PutBits(slice_hdr.frame_num, seq_parms.log2_max_frame_num);
// Only write field values if not frame only...
if (!seq_parms.frame_mbs_only_flag) {
// Write field_pic_flag
PutBit(slice_hdr.field_pic_flag);
// Write bottom_field_flag
if (slice_hdr.field_pic_flag == 1) {
PutBit(slice_hdr.bottom_field_flag);
}
}
if (ePictureClass == IDR_PIC) {
PutVLCCode(slice_hdr.idr_pic_id);
}
// Write pic_order_cnt info
if (seq_parms.pic_order_cnt_type == 0) {
PutBits(slice_hdr.pic_order_cnt_lsb, seq_parms.log2_max_pic_order_cnt_lsb);
if ((pic_parms.pic_order_present_flag == 1) && (!slice_hdr.field_pic_flag)) {
PutVLCCode(SIGNED_VLC_CODE(slice_hdr.delta_pic_order_cnt_bottom));
}
}
// Handle Redundant Slice Flag
if (pic_parms.redundant_pic_cnt_present_flag) {
PutVLCCode(slice_hdr.redundant_pic_cnt);
}
// Write direct_spatial_mv_pred_flag if this is a BPREDSLICE
if (slice_type == BPREDSLICE) {
PutBit(slice_hdr.direct_spatial_mv_pred_flag);
}
if ((slice_type == BPREDSLICE) ||
(slice_type == S_PREDSLICE) ||
(slice_type == PREDSLICE)) {
// Write num_ref_idx_active_override_flag
PutBit(curr_slice->num_ref_idx_active_override_flag);
if (curr_slice->num_ref_idx_active_override_flag) {
PutVLCCode(curr_slice->num_ref_idx_l0_active - 1);
if (slice_type == BPREDSLICE) {
PutVLCCode(curr_slice->num_ref_idx_l1_active - 1);
}
}
}
// ref_pic_list_reordering() default settings
if ((slice_type != INTRASLICE) &&
(slice_type != S_INTRASLICE)) {
// ref_pic_list_reordering_flag_l0
PutBit(0);
// More data would be inserted here if the above flag is 1
if (slice_type == BPREDSLICE) {
// ref_pic_list_reordering_flag_l1
PutBit(0);
// More data would be inserted here if the above flag is 1
}
}
if ((pic_parms.weighted_pred_flag &&
(slice_type == PREDSLICE || slice_type == S_PREDSLICE)) ||
((pic_parms.weighted_bipred_idc == 1) && slice_type == BPREDSLICE)) {
// Add support for pred_weight_table() ???
}
// Write appropriate bits for dec_ref_pic_marking()
// Note! Currently there are no structure members for these syntax elements,
// so the default bits are just written directly. This need to be updated
// when appropriate structures are implemented. TODO - VSI
if (ePictureClass == IDR_PIC) {
// no_output_of_prior_pics_flag
PutBit(0);
// long_term_reference_flag
PutBit(0);
} else if (ePictureClass == REFERENCE_PIC) {
// adaptive_ref_pic_marking_mode_flag
PutBit(slice_hdr.adaptive_ref_pic_marking_mode_flag);
// Other things would be written here if memory management control
// were to be implemented, changing the value of the adaptive_ref_pic_marking_mode_flag
// written above to 1.
}
if (pic_parms.entropy_coding_mode && slice_type != INTRASLICE &&
slice_type != S_INTRASLICE) {
PutVLCCode(curr_slice->m_cabac_init_idc);
}
// Write slice_qp_delta
PutVLCCode(SIGNED_VLC_CODE(curr_slice->m_slice_qp_delta));
// No sp_for_switch_flag or slice_qp_s_delta are written because we don't
// support SI and SP slices
if ((slice_type == S_PREDSLICE) || (slice_type == S_INTRASLICE)) {
if (slice_type == S_PREDSLICE)
PutBit(slice_hdr.sp_for_switch_flag);
// Write slice_qp_s_delta
PutVLCCode(SIGNED_VLC_CODE(slice_hdr.slice_qs_delta));
}
// Write Filter Parameters
if (pic_parms.deblocking_filter_variables_present_flag) {
// Write disable_deblocking_filter_idc
PutVLCCode(curr_slice->m_disable_deblocking_filter_idc);
if (curr_slice->m_disable_deblocking_filter_idc != 1) {
// Write slice_alpha_c0_offset_div2
PutVLCCode(SIGNED_VLC_CODE(curr_slice->m_slice_alpha_c0_offset>>1));
// Write slice_beta_offset_div2
PutVLCCode(SIGNED_VLC_CODE(curr_slice->m_slice_beta_offset>>1));
} else { // If the filter is disabled, both offsets are -51
}
} else { // If no parms are written, then the filter is ON
}
if (pic_parms.num_slice_groups > 1) {
// Write slice_group_change_cycle
}
return ps;
} // CH264pBs::PutSliceHeader()
// Encoder Lookup tables for encoding coeff_token
typedef struct {
Ipp8u code;
Ipp8u len;
} struct_CodeEntry;
static const struct_CodeEntry EncTotalCoeff[5][17][4] =
{
{ // Num-VLC0
// 0 1 2 3 <-- Trailing Ones
{ { 1, 1},{ 0, 0},{ 0, 0},{ 0, 0} }, // 0 Total_Coeffs
{ { 5, 6},{ 1, 2},{ 0, 0},{ 0, 0} }, // 1 Total_Coeffs
{ { 7, 8},{ 4, 6},{ 1, 3},{ 0, 0} }, // 2 Total_Coeffs
{ { 7, 9},{ 6, 8},{ 5, 7},{ 3, 5} }, // 3 Total_Coeffs
{ { 7,10},{ 6, 9},{ 5, 8},{ 3, 6} }, // 4 Total_Coeffs
{ { 7,11},{ 6,10},{ 5, 9},{ 4, 7} }, // 5 Total_Coeffs
{ {15,13},{ 6,11},{ 5,10},{ 4, 8} }, // 6 Total_Coeffs
{ {11,13},{14,13},{ 5,11},{ 4, 9} }, // 7 Total_Coeffs
{ { 8,13},{10,13},{13,13},{ 4,10} }, // 8 Total_Coeffs
{ {15,14},{14,14},{ 9,13},{ 4,11} }, // 9 Total_Coeffs
{ {11,14},{10,14},{13,14},{12,13} }, // 10 Total_Coeffs
{ {15,15},{14,15},{ 9,14},{12,14} }, // 11 Total_Coeffs
{ {11,15},{10,15},{13,15},{ 8,14} }, // 12 Total_Coeffs
{ {15,16},{ 1,15},{ 9,15},{12,15} }, // 13 Total_Coeffs
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -