📄 umc_h264_bs.cpp
字号:
//// INTEL CORPORATION PROPRIETARY INFORMATION// This software is supplied under the terms of a license agreement or// nondisclosure agreement with Intel Corporation and may not be copied// or disclosed except in accordance with the terms of that agreement.// Copyright (c) 2004 - 2005 Intel Corporation. All Rights Reserved.//#include <string.h>#include "umc_h264_bs.h"#include "umc_h264_video_encoder.h"// Bit stream field sizesnamespace UMC{const Ipp32u FIELDLEN_PSC = 22;const Ipp32u FIELDLEN_TR = 8; // temporal referenceconst Ipp32u FIELDLEN_TR_RV = 13;const Ipp32u FIELDLEN_PTYPE = 13; // picture typeconst Ipp32u FIELDLEN_PTYPE_CONST = 2;const Ipp32u FIELDLEN_PTYPE_SPLIT = 1;const Ipp32u FIELDLEN_PTYPE_DOC = 1;const Ipp32u FIELDLEN_PTYPE_RELEASE = 1;const Ipp32u FIELDLEN_PTYPE_SRCFORMAT = 3;const Ipp32u FIELDLEN_PTYPE_CODINGTYPE = 1;const Ipp32u FIELDLEN_PTYPE_UMV = 1;const Ipp32u FIELDLEN_PTYPE_AP = 1;const Ipp32u FIELDLEN_PTYPE_PB = 1;const Ipp32u FIELDLEN_PPTYPE_UFEP = 3;const Ipp32u FIELDLEN_OPTIONAL_EPTYPE_RESERVED = 3;const Ipp32u FIELDLEN_MANDATORY_EPTYPE_RESERVED = 2;const Ipp32u FIELDLEN_MPPTYPE_SRCFORMAT = 3;const Ipp32u FIELDLEN_MPPTYPE_RRU = 1;const Ipp32u FIELDLEN_MPPTYPE_ROUNDING = 1;const Ipp32u FIELDLEN_CSFMT_PARC = 4;const Ipp32u FIELDLEN_CSFMT_FWI = 9;const Ipp32u FIELDLEN_CSFMT_CONST = 1;const Ipp32u FIELDLEN_CSFMT_FHI = 9;const Ipp32u FIELDLEN_EPAR_WIDTH = 8;const Ipp32u FIELDLEN_EPAR_HEIGHT = 8;const Ipp32u FIELDLEN_PQUANT = 5; // picture quant valueconst Ipp32u FIELDLEN_CPM = 1; // continuous presence multipoint indicatorconst Ipp32u FIELDLEN_TRB = 3; // temporal reference for B framesconst Ipp32u FIELDLEN_DBQUANT = 2; // B frame differential quant valueconst Ipp32u FIELDLEN_PSPARE = 8; // spare informationconst Ipp32u FIELDLEN_GBSC = 17; // Group of blocks start codeconst Ipp32u FIELDLEN_GN = 5; // GOB number.const Ipp32u FIELDLEN_GLCI = 2; // GOB logical channel indicatorconst Ipp32u FIELDLEN_GFID = 2; // GOB Frame IDconst Ipp32u FIELDLEN_GQUANT = 5; // GQUANTconst Ipp32u FIELDLEN_SQUANT = 5; // SQUANTconst Ipp32u FIELDLEN_SSC = 16; // Slice start code// Bit stream field valuesconst Ipp32u FIELDVAL_PSC = (0x00008000 >> (32 - FIELDLEN_PSC));const Ipp32u FIELDVAL_SSC = 0x0001;const Ipp32u FIELDVAL_GBSC = (0x00008000 >> (32 - FIELDLEN_GBSC));const Ipp32u FIELDVAL_EPTYPE_RESERVED = 0;// Bitstream Version Information//// Starting with H264_FID_REALVIDEO30, for RealVideo formats we embed the// minor bitstream version number in the slice header.// The encoder only ever produces one bitstream format. But the decoder// must be backwards compatible, and able to decode any prior minor// bitstream version number.//// It is assumed that if the bitstream major version number changes,// then a new H264_FID is introduced. So, only the minor version number// is present in the bitstream.//// The minor version number is encoded in the bitstream using 3 bits.// Tromso's first bitstream minor version number is "2", which is encoded// as all 0's. The following table maps the bitstream value to the// actual minor version number.const Ipp32u FIELDLEN_RV_BITSTREAM_VERSION = 3;#define UNSUPPORTED_RV_BITSTREAM_VERSION 9999#define ENCODERS_CURRENT_RV_BITSTREAM_VERSION 2static const Ipp32u s_RVVersionEncodingToMinorVersion[8] = { 2, UNSUPPORTED_RV_BITSTREAM_VERSION, UNSUPPORTED_RV_BITSTREAM_VERSION, UNSUPPORTED_RV_BITSTREAM_VERSION, UNSUPPORTED_RV_BITSTREAM_VERSION, UNSUPPORTED_RV_BITSTREAM_VERSION, UNSUPPORTED_RV_BITSTREAM_VERSION, UNSUPPORTED_RV_BITSTREAM_VERSION};#define NUMBER_OF_RV_BITSTREAM_VERSIONS \ (sizeof(s_RVVersionEncodingToMinorVersion) \ / sizeof(s_RVVersionEncodingToMinorVersion[0]))// NAL unit definitions#define NAL_REF_IDC_BITS 0x60#define NAL_UNITTYPE_BITS 0x1f// ---------------------------------------------------------------------------// CH264pBs::CH264pBs()// H.263+ bitstream constructor used in the decoder// ---------------------------------------------------------------------------CH264pBs::CH264pBs( /*const H264_FID fid,*/ Ipp8u* const pb, const Ipp32u maxsize, Status &plr) : CBaseBitstream( pb, maxsize){// m_fid = fid; m_pbsRBSPBase = m_pbsBase; plr = UMC_OK;} // CH264pBs::CH264pBs()// ---------------------------------------------------------------------------// CH264pBs::CH264pBs()// default constructor used in the decoder// ---------------------------------------------------------------------------CH264pBs::CH264pBs(/* const H264_FID fid,*/ Status &plr) : CBaseBitstream(){// m_fid = fid; m_pbsRBSPBase = m_pbsBase; plr = UMC_OK;} // CH264pBs::CH264pBs()// ---------------------------------------------------------------------------// CH264pBs::~CH264pBs()// ---------------------------------------------------------------------------CH264pBs::~CH264pBs(){} // CH264pBs::~CH264pBs()// ---------------------------------------------------------------------------// CH264pBs::Reset()// reset bitstream; used in the encoder// ---------------------------------------------------------------------------void CH264pBs::Reset(){ CBaseBitstream::Reset(); m_pbsRBSPBase = m_pbsBase;} // CH264pBs::Reset()// ---------------------------------------------------------------------------// CH264pBs::ResetRBSP()// reset bitstream to beginning of current RBSP; used in the encoder// ---------------------------------------------------------------------------void CH264pBs::ResetRBSP(){ m_pbs = m_pbsRBSPBase; m_bitOffset = 0; m_pbs[0] = 0; // Zero the first byte, since subsequent bits written will be OR'd // with this byte. Subsequent bytes will be completely overwritten // or zeroed, so no need to clear them out.} // CH264pBs::Reset()// ---------------------------------------------------------------------------// CH264pBs::Reset()// reset bitstream; used in the decoder// ---------------------------------------------------------------------------void CH264pBs::Reset( Ipp8u* const pb, const Ipp32u maxsize){ CBaseBitstream::Reset(pb, maxsize); m_pbsRBSPBase = m_pbsBase;} // CH264pBs::Reset()// ---------------------------------------------------------------------------// CH264pBs::EndOfNAL()// ---------------------------------------------------------------------------Ipp32u CH264pBs::EndOfNAL(Ipp8u* const pout, Ipp8u const uIDC, NAL_Unit_Type const uUnitType){ Ipp32u size, ExtraBytes; Ipp8u* curPtr, *endPtr, *outPtr; // get current RBSP compressed size size = (Ipp32u)(m_pbs - m_pbsRBSPBase); ExtraBytes = 0; // Set Pointers endPtr = m_pbsRBSPBase + size - 1; // Point at Last byte with data in it. curPtr = m_pbsRBSPBase; outPtr = pout; // Write Start Codes, and NAL Header byte if ((uUnitType >= NAL_UT_SEI) && (uUnitType <= NAL_UT_PD)) { *outPtr++ = 0; // Write an Extra zero_byte ExtraBytes = 1; } *outPtr++ = 0; *outPtr++ = 0; *outPtr++ = 1; *outPtr++ = (Ipp8u) ((uIDC << 5) | uUnitType); ExtraBytes += 4; while (curPtr < endPtr-1) { // Copy all but the last 2 bytes *outPtr++ = *curPtr; // Check for start code emulation if ((*curPtr++ == 0) && (*curPtr == 0) && (!(*(curPtr+1) & 0xfc))) { *outPtr++ = *curPtr++; *outPtr++ = 0x03; // Emulation Prevention Byte ExtraBytes++; } } if (curPtr < endPtr) { *outPtr++ = *curPtr++; } // copy the last byte *outPtr = *curPtr; // Update RBSP Base Pointer m_pbsRBSPBase = m_pbs; // copy encoded frame to output return(size+ExtraBytes);} // CH264pBs::EndOfNAL()// ---------------------------------------------------------------------------// CH264pBs::PutSeqParms()// ---------------------------------------------------------------------------StatusCH264pBs::PutSeqParms(H264SeqParamSet const seq_parms){ Status ps = UMC_OK; // Write profile and level information PutBits(seq_parms.profile_idc, 8); PutBits(seq_parms.constraint_set0_flag, 1); PutBits(seq_parms.constraint_set1_flag, 1); PutBits(seq_parms.constraint_set2_flag, 1); PutBits(seq_parms.constraint_set3_flag, 1); // 5 reserved zero bits PutBits(0, 4); PutBits(seq_parms.level_idc, 8); // Write the sequence parameter set id PutVLCCode(seq_parms.seq_parameter_set_id); // Write log2_max_frame_num_minus4 PutVLCCode(seq_parms.log2_max_frame_num - 4); // Write pic_order_cnt_type and associated data PutVLCCode(seq_parms.pic_order_cnt_type); // Write data specific to various pic order cnt types // pic_order_cnt_type == 1 is NOT currently supported if (seq_parms.pic_order_cnt_type == 0) { PutVLCCode(seq_parms.log2_max_pic_order_cnt_lsb - 4); } // Write num_ref_frames PutVLCCode(seq_parms.num_ref_frames); // Write required_frame_num_update_behaviour_flag PutBits(seq_parms.gaps_in_frame_num_value_allowed_flag, 1); // Write picture MB dimensions PutVLCCode(seq_parms.frame_width_in_mbs - 1); if(seq_parms.frame_mbs_only_flag) { PutVLCCode(seq_parms.frame_height_in_mbs - 1); } else { // Height in MBs of a field. PutVLCCode(seq_parms.frame_height_in_mbs/2 - 1); } // Write other misc flags PutBits(seq_parms.frame_mbs_only_flag, 1); if (!seq_parms.frame_mbs_only_flag) { PutBits(seq_parms.mb_adaptive_frame_field_flag, 1); } // Right now, the decoder only supports this flag with // a value of zero. PutBits(seq_parms.direct_8x8_inference_flag, 1); PutBits(seq_parms.frame_cropping_flag, 1); if (seq_parms.frame_cropping_flag) { PutVLCCode(seq_parms.frame_crop_left_offset); PutVLCCode(seq_parms.frame_crop_right_offset); PutVLCCode(seq_parms.frame_crop_top_offset); PutVLCCode(seq_parms.frame_crop_bottom_offset); } PutBits(seq_parms.vui_parameters_present_flag, 1); if (seq_parms.vui_parameters_present_flag) { // Not currently supported. Must implement VUI Parms here... } return ps;} // CH264pBs::PutSeqParms()// ---------------------------------------------------------------------------// CH264pBs::PutPicParms()// ---------------------------------------------------------------------------StatusCH264pBs::PutPicParms(const H264PicParamSet & pic_parms, const H264SeqParamSet & ) // 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 PutBits(pic_parms.entropy_coding_mode, 1); PutBits(pic_parms.pic_order_present_flag, 1); // 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 PutBits(pic_parms.weighted_pred_flag, 1); // 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 PutBits(pic_parms.deblocking_filter_variables_present_flag, 1); PutBits(pic_parms.constrained_intra_pred_flag, 1); PutBits(pic_parms.redundant_pic_cnt_present_flag, 1); return ps;} // CH264pBs::PutPicParms()// ---------------------------------------------------------------------------// CH264pBs::PutPicDelimiter()// ---------------------------------------------------------------------------StatusCH264pBs::PutPicDelimiter(EnumPicCodType PicCodType){ Status ps = UMC_OK; // Write pic_type PutBits(PicCodType, 3); return ps;} // CH264pBs::PutPicDelimiter()// ---------------------------------------------------------------------------// CH264pBs::PutPSC()// ---------------------------------------------------------------------------void CH264pBs::PutPSC(){ PutBits(FIELDVAL_PSC, FIELDLEN_PSC);} // CH264pBs::PutPSC()// ---------------------------------------------------------------------------// CH264pBs::PutSSC()// ---------------------------------------------------------------------------void CH264pBs::PutSSC(){ PutBits(FIELDVAL_SSC, FIELDLEN_SSC);} // CH264pBs::PutSSC()// ---------------------------------------------------------------------------// CH264pBs::PutTR()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -