📄 umc_h264_gen_enc.cpp
字号:
end_of_frame: // Core will set pReconstructFrame to current recon. frame if (m_rate_control) { m_rate_control->PostPictureRateControl(m_bs1->GetBitsEncoded()); } else if(m_info.rate_controls.method == H264_RCM_MPEG2) { PostPictureRateControl(m_bs1->GetBitsEncoded()); } End_Picture(); // ------------------------------------------------------------------------ // Copy the compressed image to the output area. // ------------------------------------------------------------------------ if (dst.size == 0) { m_bMakeNextFrameKey = true; status = UMC_OPERATION_FAILED; goto done; } // update TR for the "futr" reference frame // this is used/needed for temporal weighting in B frames //m_pFutrFrm->SetTR( m_pCurrentFrame->GetSequenceNumber());#if defined(SAVE_RECON) || defined(CALC_PSNR) Ipp8u *pYDst, *pUDst, *pVDst;#endif#ifdef SAVE_RECON // Nothing to do if this is the first frame of a sequence with B frames. H264EncoderFrame * curr_frame = ePic_Class == DISPOSABLE_PIC ? m_pReconstructFrame : m_pCurrentFrame; Write_Order_Frame(ePic_Class, curr_frame);#endif // SAVE_RECON#ifdef CALC_PSNR { pYDst = m_pReconstructFrame->m_pYPlane; pUDst = m_pReconstructFrame->m_pUPlane; pVDst = m_pReconstructFrame->m_pVPlane; #define LOG10(a) ( log(a)/log(double(10)) ) double PSNR; double MSE = 0.0; Ipp32u i, j, tmp, uMSE; Ipp8u *p1,*p2; p1 = m_pCurrentFrame->m_pYPlane;#ifdef USE_SMOOTHED_IMAGE_FOR_PSNR p2 = pY;#else p2 = pYDst;#endif uMSE = 0; for (i = 0; i < m_info.dimensions.height; i++) { for (j = 0; j < m_info.dimensions.width; j++) { tmp = (p1[j] - p2[j]); uMSE += (tmp*tmp); } p1 += m_pCurrentFrame->m_pitch;#ifdef USE_SMOOTHED_IMAGE_FOR_PSNR p2 += pitch;#else p2 += m_pReconstructFrame->m_pitch;#endif } if (uMSE) { MSE = double(uMSE); MSE /= m_info.dimensions.Area(); PSNR = 10*LOG10((255.0*255.0)/(MSE)); } else { PSNR = 50.00; // just need some number for the average } total_psnr += PSNR; total_bits += dst.size; num_calc_psnr++; FILE *fp = fopen(PSNR_OUTPUT_FILE_NAME, "a+"); if (fp) { if (g_first) { fprintf(fp, "=======================================================\n"); fprintf(fp, "Defines: "); fprintf(fp, "\n"); fprintf(fp, "TR\tQP\tPSNR\tBits\tAvPSNR\tAvBits\tFr.type\n"); fprintf(fp, "=======================================================\n"); g_first = false; } fprintf(fp,"%d\t%d\t%.2f\t%d\t%.2f\t%d\t%s\n", m_pCurrentFrame->m_FrameNum, m_PicParamSet.pic_init_qp, PSNR,8*dst.size, total_psnr/(double)num_calc_psnr, 8*total_bits/num_calc_psnr, m_PicType == INTRAPIC?"Key": (BPREDPIC == m_PicType)?"B":"P"); fclose(fp); } }#endif // CALC_PSNR // ------------------------------------------------------------------------ // update states for next frame, etc. // ------------------------------------------------------------------------ // Increment the Frame Number (decode order), not incremented for any frame // directly preceded (in decode order) by a disposable frame. if (ePic_Class != DISPOSABLE_PIC && m_PicParamSet.picture_structure != TOP_FIELD) { m_pCurrentFrame->m_FrameNum++; } m_uFrames_Num++;done: return status;}//// CompressFrame// This function drives the compression of one frame//StatusH264VideoEncoder::CompressFrame( EnumPicCodType & ePictureType, H264_Image & dst){#if defined SPLIT_INTO_FIELDS if(m_info.coding_type) { m_PicType = ePictureType; if(ePictureType == INTRAPIC && m_pCurrentFrame->m_FrameNum == 0) { SetSequenceParameters(); } // Set top field parameters. SetPictureParameters(TOP_FIELD); // encode top field. EncodePicture(dst); // Set bottom field parameters. SetPictureParameters(BOTTOM_FIELD); // encode bottom field. EncodePicture(dst); return(UMC_OK); }#endif // SPLIT_INTO_FIELDS Status status = UMC_OK; Ipp16u slice; EnumPicClass ePic_Class; // Determine the Pic_Class. Right now this depends on ePictureType, but that could change // to permit disposable P frames, for example. switch (ePictureType) { case INTRAPIC: if (m_uFrames_Num == 0) { // Right now, only the first INTRAPIC in a sequence is an IDR Frame ePic_Class = IDR_PIC; } else { ePic_Class = REFERENCE_PIC; } break; case PREDPIC: ePic_Class = REFERENCE_PIC; break; case BPREDPIC: ePic_Class = m_info.treat_B_as_reference?REFERENCE_PIC:DISPOSABLE_PIC; break; default: // Unsupported Picture Type VM_ASSERT(false); ePic_Class = IDR_PIC; break; } // Now set-up some things depending on Picture Class switch (ePic_Class) { case IDR_PIC: m_uPic_Count_Base = m_pCurrentFrame->GetSequenceNumber(); // Set the pic cnt base SetSequenceParameters(); // These only get (re)set on IDR pictures. SetPictureParameters(); // Toggle the idr_pic_id on and off so that adjacent IDRs will have different values // This is done here because it is done per frame and not per slice. m_SliceHeader.idr_pic_id ^= 0x1; break; case REFERENCE_PIC: // swap reference frames before encoding the new reference frame. //SwapReferencePtrs(); break; case DISPOSABLE_PIC: // Do Nothing right now? break; default: // Unsupported Picture Class break; } // reset bitstream object before begin compression m_bs1->Reset(); // Initialization before encoding all rows. m_PicType = ePictureType; SetPictureQuant(); // Set up the values in the slice header SetSliceHeader( m_pCurrentFrame, ePic_Class ); if (m_PicType == PREDPIC) { m_SliceHeader.slice_type = PREDSLICE; } else if (m_PicType == INTRAPIC) { m_SliceHeader.slice_type = INTRASLICE; } else { // BPREDPIC m_SliceHeader.slice_type = BPREDSLICE; } UpdateRefPicList(m_SliceHeader, &m_ReorderInfoL0, &m_ReorderInfoL1, 0); m_SliceHeader.num_ref_idx_l0_active = MAX(m_NumRefsInL0List, 1); m_SliceHeader.num_ref_idx_l1_active = MAX(m_NumRefsInL1List, 1); m_SliceHeader.num_ref_idx_active_override_flag = ( (m_SliceHeader.num_ref_idx_l0_active != m_PicParamSet.num_ref_idx_l0_active) || (m_SliceHeader.num_ref_idx_l1_active != m_PicParamSet.num_ref_idx_l1_active) ); // Write frame header code into bitstream buffer. status = encodeFrameHeader(m_bs1, dst, (ePic_Class == IDR_PIC)); if (status != UMC_OK) { goto done; } if (m_info.rate_controls.method==H264_RCM_BITRATE) { int slice_qp = m_rate_control->PictureRateControl( m_pCurrentFrame->m_pYPlane, m_pCurrentFrame->m_pUPlane, m_pCurrentFrame->m_pVPlane, m_pCurrentFrame->GetSequenceNumber(), ePictureType & ((m_info.current_slice_type==INTRASLICE)-1), m_bs1->GetBitsEncoded(), ExMBInfo,m_uFrames_Num/m_info.FrameRate,(m_uFrames_Num+1)/m_info.FrameRate); m_SliceHeader.slice_qp_delta = (Ipp8s)(slice_qp - m_PicParamSet.pic_init_qp); } status = Start_Picture(&ePic_Class, &m_SeqParamSet, &m_PicParamSet, &m_SliceHeader, m_bs1, ePictureType); if (status != UMC_OK) { goto done; } if ((m_SliceHeader.disable_deblocking_filter_idc != 1) && (ePic_Class != DISPOSABLE_PIC)) { // init deblock filter for this frame, must be called after encoder Start_Picture // to get correct MB info pointer 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 m_pCurrentFrame->m_pitch, m_pCurrentFrame->m_pYPlane, m_pCurrentFrame->m_pVPlane, m_pCurrentFrame->m_pUPlane ); } for (slice = 0; slice < m_info.Num_Slices; slice++) { EnumSliceType slice_type; // Fill in the slice type in the slice header. if (ePictureType == PREDPIC) { slice_type = PREDSLICE; } else if (ePictureType == INTRAPIC) { slice_type = INTRASLICE; } else { // BPREDPIC slice_type = BPREDSLICE; }re_encode_slice: m_info.current_slice_type = slice_type; // Pass to core encoder // Compress one slice status = Compress_Slice(slice); if ((slice_type == PREDSLICE) || (slice_type == BPREDSLICE)) { if (Intra_Slice_Test()) { // Force this slice to be INTRA slice_type = INTRASLICE; m_pCurrentFrame->SetPicCodType(INTRAPIC); // Reset the RBSP m_bs1->ResetRBSP(); goto re_encode_slice; } } m_bs1->WriteTrailingBits(); // Write RBSP Trailing Bits // Copy Slice RBSP to the end of the output buffer after // Adding start codes and SC emulation prevention. dst.size += m_bs1->EndOfNAL((dst.data + dst.size), (ePic_Class != DISPOSABLE_PIC), ((ePic_Class == IDR_PIC) ? NAL_UT_IDR_SLICE : NAL_UT_SLICE)); if (status != UMC_OK) { m_bMakeNextFrameKey = true; goto done; } } // check for buffer overrun if (!m_bs1->CheckBsLimit()) { status = EncodeDummyFrame(dst); m_bMakeNextFrameKey = true; if (status == UMC_OK) { goto end_of_frame; } else { goto done; } } // inloop deblocking filtering if ((m_SliceHeader.disable_deblocking_filter_idc != 1) && (ePic_Class != DISPOSABLE_PIC)) { // Currently always called here to deblock entire frame, could be // called multiple times to deblock segments of the frame. status = m_deblockingFilter.DeblockSegment(0, 0, m_WidthInMBs*m_HeightInMBs); if (status != UMC_OK) goto done; }end_of_frame: // Core will set pReconstructFrame to current recon. frame if (m_rate_control) { m_rate_control->PostPictureRateControl(m_bs1->GetBitsEncoded()); } else if(m_rate_control_method == H264_RCM_MPEG2) { PostPictureRateControl(m_bs1->GetBitsEncoded()); } switch (ePic_Class) { case IDR_PIC: case REFERENCE_PIC: UpdateRefPicMarking(); m_pCurrentFrame->ExchangePointers(m_pReconstructFrame); break; case DISPOSABLE_PIC: default: // Unsupported Picture Class break; } End_Picture(); // ------------------------------------------------------------------------ // Copy the compressed image to the output area. // ------------------------------------------------------------------------ if (dst.size == 0) { m_bMakeNextFrameKey = true; status = UMC_OPERATION_FAILED; goto done; } // update TR for the "futr" reference frame // this is used/needed for temporal weighting in B frames //m_pFutrFrm->SetTR( m_pCurrentFrame->GetSequenceNumber());#if defined(SAVE_RECON) || defined(CALC_PSNR) Ipp8u *pYDst, *pUDst, *pVDst;#endif#ifdef SAVE_RECON // This is only needed if the recon output is supposed to be used // for anything, for instance viewing or comparisons // Nothing to do if this is the first frame of a sequence with B frames. //if ((ePic_Class != IDR_PIC) || (m_info.B_Frame_Rate == 0)) H264EncoderFrame * curr_frame = (ePic_Class == DISPOSABLE_PIC) ? m_pReconstructFrame : m_pCurrentFrame; Write_Order_Frame(ePic_Class, curr_frame);#endif // SAVE_RECON
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -