📄 umc_h264_gen_enc.cpp
字号:
//// Apply the "Profile Rules" to this profile frame type////// Option Single Layer// ------------ -------------------------// Progressive// Stills// Purge frames in the// Ready and Wait queues.// Reset the profile index.//// -------------------------// Key frame// interval Wait for next 'P' in the// profile to make an I frame// Do process intervening B// frames in the profile.// No profile index reset.// The key frame interval// counter restarts after// the key frame is sent.// -------------------------// Forced Key// Frame Regardless of the profile// frame type; purge the// the Ready queue.// If destuctive key frame request// then purge the Wait queue// Reset profile index.//// -------------------------// switch B// frame to P If this profile frame type// indicates a 'B' it will be// en-queued, encoded and// emitted as a P frame. Prior// frames (P|B) in the queue// are correctly emitted using// the (new) P as a ref frame//// ------------ -------------------------EnumPicCodTypeH264VideoEncoder::DetermineFrameType( Ipp32s iProfileIndex ){ EnumPicCodType ePictureType; ePictureType = eFrameType[iProfileIndex]; // see if the layer's key frame interval has expired if ( H264_KFCM_INTERVAL == m_info.key_frame_controls.method ) { // a value of one means every frame is a key frame // The interval can be expressed as: "Every Nth frame is a key frame" m_uIntraFrameInterval--; if ( 0 == m_uIntraFrameInterval ) { m_bKeyFrameIntervalPending = true; } } // A key frame is also created if the CPU scalability parameter // indicates that all frames should be key frames. FrameType( ePictureType ); if ( INTRAPIC == ePictureType ) { // When a frame is forced INTRA, which happens internally for the // first frame, explicitly by the application, on a decode error // or for CPU scalability - the interval counter gets reset. if ( H264_KFCM_INTERVAL == m_info.key_frame_controls.method ) { m_uIntraFrameInterval = m_info.key_frame_controls.interval; } m_bMakeNextFrameKey = false; m_bKeyFrameIntervalPending = false; } return ePictureType;}voidH264VideoEncoder::FrameType( EnumPicCodType & ePictureType ){ // check if this TR's B profile frame type // is converted (suppressed) to a P profile frame type. if ( m_info.m_do_suppress_B_for_this_TR && ePictureType == BPREDPIC ) { ePictureType = PREDPIC; } // change to an I frame if ( m_bKeyFrameIntervalPending ) { ePictureType = INTRAPIC; return; } if ( m_bMakeNextFrameKey ) { ePictureType = INTRAPIC; if ( ! m_info.m_do_weak_forced_key_frames ) { //m_ReadyToEncode->Flush(); m_iProfileIndex = 0; } return; }}/************************************************************* * Name: EncodeDummyFrame * Description: Writes out a blank frame to the bitstream in case of buffer overflow. ************************************************************/StatusH264VideoEncoder::EncodeDummyFrame(H264_Image &dst){ Ipp32u uMBRow, uMB; Status status = UMC_OK; m_bs1->Reset(); encodeFrameHeader(m_bs1, dst, false); for (uMBRow=0; uMBRow < m_HeightInMBs; uMBRow++) { for (uMB=0; uMB < m_WidthInMBs; uMB++) { if (m_PicType == INTRAPIC) { m_bs1->PutBits(1,1); // MBTYPE: INTRA_16x16 m_bs1->PutBits(0,2); // AIC 16x16: DC m_bs1->PutBits(1,1); // CBP: 0 m_bs1->PutBits(1,1); // 16x16 Coef: EOB } else if (m_PicType == PREDPIC || m_PicType == BPREDPIC) { m_bs1->PutBits(1,1); // skipped MB } else { status = UMC_OPERATION_FAILED; goto done; } } }done: return status;}StatusH264VideoEncoder::InitImages(){// void *tempbuf; def_src.format.Propagate_Defaults(); def_src.format.yuv_info.y_pitch=m_info.src_width; def_src.format.yuv_info.u_pitch=m_info.src_width/2; def_src.format.yuv_info.v_pitch=m_info.src_width/2; def_src.format.dimensions.width=m_info.src_width; def_src.format.dimensions.height=m_info.src_height; def_src.size = def_src.format.yuv_info.y_pitch*def_src.format.dimensions.height*3; //tempbuf=H264_Allocate(def_src.size ,0); //def_src.Set_Buffer_Pointers(tempbuf); def_dst.format.Propagate_Defaults(); def_dst.format.yuv_info.y_pitch=m_info.src_width; def_dst.format.yuv_info.u_pitch=m_info.src_width/2; def_dst.format.yuv_info.v_pitch=m_info.src_width/2; def_dst.format.dimensions.width=m_info.src_width; def_dst.format.dimensions.height=m_info.src_height; def_dst.size = def_dst.format.yuv_info.y_pitch*def_dst.format.dimensions.height*3; //tempbuf=H264_Allocate(def_dst.size ,0); //def_dst.data = (unsigned char *)tempbuf; return UMC_OK;}StatusH264VideoEncoder::DestroyImages(){ //void *tempbuf=def_src.Get_Base_Pointer(); //H264_Free(tempbuf); //tempbuf=def_dst.Get_Base_Pointer(); //H264_Free(tempbuf); return UMC_OK;}StatusH264VideoEncoder::GetFrame(MediaData *in, MediaData *out){ if (in) { VideoData *vin = DynamicCast<VideoData ,MediaData> (in); def_src.Set_Buffer_Pointers(vin->m_lpDest[0], vin->m_lpDest[1], vin->m_lpDest[2]); def_src.format.yuv_info.y_pitch = (Ipp32u)vin->m_lPitch[0]; def_src.format.yuv_info.u_pitch = (Ipp32u)vin->m_lPitch[1]; def_src.format.yuv_info.v_pitch = (Ipp32u)vin->m_lPitch[2]; def_dst.data = (unsigned char*)out->GetDataPointer(); Encode(def_src,def_dst,cflags,cnotes); out->SetDataSize(def_dst.size); if (cnotes&H264_ECN_NO_FRAME) return UMC_OK; } else { cflags|=H264_ECF_LAST_FRAME; def_src.Set_Buffer_Pointers(NULL, NULL, NULL); def_dst.data = (unsigned char*)out->GetDataPointer(); Encode(def_src,def_dst,cflags,cnotes); out->SetDataSize(def_dst.size); if (cnotes&H264_ECN_NO_FRAME) { End_Sequence(); return UMC_END_OF_STREAM; } } return UMC_OK;} // Get codec working (initialization) parameter(s)StatusH264VideoEncoder::GetInfo(BaseCodecParams *info){ H264EncoderParams* pInfo = DynamicCast< H264EncoderParams, BaseCodecParams>(info); if(pInfo) { memcpy(pInfo, &m_info, sizeof(H264EncoderParams)); } else if(info) { VideoEncoderParams* pInfo = DynamicCast<VideoEncoderParams, BaseCodecParams>(info); if(pInfo) memcpy(info, pInfo, sizeof(VideoEncoderParams)); else return UMC_BAD_FORMAT; } else { return UMC_NULL_PTR; } return UMC_OK;}StatusH264VideoEncoder::Close(){ DestroyImages(); return UMC_OK;}#if defined(_DEBUG)void H264VideoEncoder::ZeroBits(){ m_counter_mv_bits = 0; m_counter_coeff_bits = 0; m_counter_mbhdr_bits = 0;}void H264VideoEncoder::ZeroTotalBits(){ m_counter_total_mv_bits = 0; m_counter_total_coeff_bits = 0; m_counter_total_mbhdr_bits = 0; m_counter_total_num_frames = 0;}Ipp32u H264VideoEncoder::AddBits(){ Ipp32u sum; sum = m_counter_mv_bits + m_counter_coeff_bits + m_counter_mbhdr_bits; return sum;}void H264VideoEncoder::AddBitsToTotal(){ m_counter_total_mv_bits += m_counter_mv_bits; m_counter_total_coeff_bits += m_counter_coeff_bits; m_counter_total_mbhdr_bits += m_counter_mbhdr_bits;}Ipp32u H264VideoEncoder::AddTotalBits(){ Ipp32u sum; sum = m_counter_total_mv_bits + m_counter_total_coeff_bits + m_counter_total_mbhdr_bits; return sum;}void H264VideoEncoder::PrintBits(Ipp32u ){ Ipp32u sum; sum = AddBits(); m_counter_total_num_frames++; AddBitsToTotal();}void H264VideoEncoder::PrintTotalBits(){ Ipp32u sum; sum = AddTotalBits(); if (m_counter_total_num_frames > 0) { }}void H264VideoEncoder::Write_Order_Frame(EnumPicClass ePic_Class, H264EncoderFrame * curr_frame){ static H264EncoderFrame * futr_frame = 0; if (!curr_frame) { if (futr_frame) { Write_Recon_Frame(REFERENCE_PIC, futr_frame); } return; } if (m_info.B_Frame_Rate == 0) { Write_Recon_Frame(ePic_Class, curr_frame); }else{ if (ePic_Class == DISPOSABLE_PIC) { Write_Recon_Frame(ePic_Class, curr_frame); }else{ if (futr_frame) { Write_Recon_Frame(REFERENCE_PIC, futr_frame); } futr_frame = curr_frame; } }}void H264VideoEncoder::Write_Recon_Frame(EnumPicClass ePic_Class, H264EncoderFrame * frame){ Ipp32u uDstPitch; Ipp8u *pYDst, *pUDst, *pVDst; pYDst = frame->m_pYPlane; pUDst = frame->m_pUPlane; pVDst = frame->m_pVPlane; uDstPitch = frame->m_pitch; if ((m_SliceHeader.disable_deblocking_filter_idc != 1) && (ePic_Class == DISPOSABLE_PIC)) // filter the disposable frames only for writing out reconstructed // frames. Otherwise, there is no need to filter them in the enecoder. { // set up deblock filter for Disposable frame m_deblockingFilter.Start_Frame( Get_MBInfoArray_Pointer(), Get_SliceDataBase_Pointer(), m_WidthInMBs << 4, // width, padded to MB edge m_HeightInMBs << 4, // height, padded to MB edge uDstPitch, pYDst, pVDst, pUDst ); m_deblockingFilter.DeblockSegment(0, 0, m_WidthInMBs*m_HeightInMBs); }#ifdef SAVE_RECON // write reconstructed frame to file writeimage(RAW_RECON_FILE,pYDst,pUDst,pVDst, m_info.dimensions.width, m_info.dimensions.height,uDstPitch,false,"ab");#endif}#endif // defined(_DEBUG)voidH264VideoEncoder::SetDPBSize(){ Ipp32u MaxDPBx2; Ipp32u dpbLevel; Ipp32u dpbSize; // MaxDPB, per Table A-1, Level Limits switch (m_SeqParamSet.level_idc) { case 10: MaxDPBx2 = 297; break; case 11: MaxDPBx2 = 675; break; case 12: case 13: case 20: MaxDPBx2 = 891*2; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -