⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 umc_h264_gen_enc.cpp

📁 这是在PCA下的基于IPP库示例代码例子,在网上下了IPP的库之后,设置相关参数就可以编译该代码.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
#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,                ePictureType == INTRAPIC?"Key":                (BPREDPIC == ePictureType)?"B":"");            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.        m_uFrames_Num++;done:    return status;}//// move all frames in WaitingForRef to ReadyToEncode//StatusH264VideoEncoder::MoveFromCPBToDPB(){ //   EnumPicCodType  ePictureType;    m_cpb.RemoveFrame(m_pCurrentFrame);    m_dpb.insertAtCurrent(m_pCurrentFrame);    return UMC_OK;}StatusH264VideoEncoder::CleanDPB(){    H264EncoderFrame *pFrm=m_dpb.findNextDisposable();    //   EnumPicCodType  ePictureType;    Status      ps = UMC_OK;    while(pFrm!=NULL) {        m_dpb.RemoveFrame(pFrm);        m_cpb.insertAtCurrent(pFrm);        pFrm=m_dpb.findNextDisposable();    } while(pFrm!=NULL);    return ps;}/************************************************************* *  Name: SetSequenceParameters *  Description:  Fill in the Sequence Parameter Set for this *  sequence.  Can only change at an IDR picture. *************************************************************/voidH264VideoEncoder::SetSequenceParameters(){    Ipp32u MB_per_frame = 0;    Ipp32u MB_per_sec = 0;    m_SeqParamSet.profile_idc = 77;    // We don't meet any of these contraints yet    m_SeqParamSet.constraint_set0_flag = 0;    m_SeqParamSet.constraint_set1_flag = 1;    m_SeqParamSet.constraint_set2_flag = 0;    m_SeqParamSet.constraint_set3_flag = 0;    m_SeqParamSet.seq_parameter_set_id = 0;    // Frame numbers are mod 256.    m_SeqParamSet.log2_max_frame_num = 8;    // Setup pic_order_cnt_type based on use of B frames.    // Note! pic_order_cnt_type == 1 is not implemented    // The following are not transmitted in either case below, and are    // just initialized here to be nice.    m_SeqParamSet.delta_pic_order_always_zero_flag = 0;    m_SeqParamSet.offset_for_non_ref_pic = 0;    m_SeqParamSet.poffset_for_ref_frame = NULL;    m_SeqParamSet.num_ref_frames_in_pic_order_cnt_cycle = 0;    if (m_info.B_Frame_Rate == 0) {        m_SeqParamSet.pic_order_cnt_type = 2;        m_SeqParamSet.log2_max_pic_order_cnt_lsb = 0;        // Right now this only supports simple P frame patterns (e.g. H264PPPP...)    } else {        m_SeqParamSet.log2_max_pic_order_cnt_lsb = 4;        m_SeqParamSet.pic_order_cnt_type = 0;        // Right now this only supports simple B frame patterns (e.g. IBBPBBP...)    }    m_SeqParamSet.num_ref_frames = m_info.num_ref_frames;    // Note!  NO code after this point supports pic_order_cnt_type == 1    // Always zero because we don't support field encoding    m_SeqParamSet.offset_for_top_to_bottom_field = 0;    m_SeqParamSet.frame_mbs_only_flag = (m_info.coding_type)? 0: 1;    m_SeqParamSet.gaps_in_frame_num_value_allowed_flag = 0;    m_SeqParamSet.mb_adaptive_frame_field_flag = 0;    // If set to 1, 8x8 blocks in Direct Mode always use 1 MV,    // obtained from the "outer corner" 4x4 block, regardless    // of how the CoLocated 8x8 is split into subblocks.  If this    // is 0, then the 8x8 in Direct Mode is subdivided exactly as    // the Colocated 8x8, with the appropriate number of derived MVs.    m_SeqParamSet.direct_8x8_inference_flag =        m_info.use_direct_inference || !m_SeqParamSet.frame_mbs_only_flag ? 1 : 0;    // Picture Dimensions in MBs    m_SeqParamSet.frame_width_in_mbs = ((m_info.dimensions.width+15)>>4);    m_SeqParamSet.frame_height_in_mbs = ((m_info.dimensions.height+15)>>4);    // If the width & height in MBs doesn't match the image dimensions then do    // some cropping in the decoder    if (((m_SeqParamSet.frame_width_in_mbs<<4) != m_info.dimensions.width) ||        ((m_SeqParamSet.frame_height_in_mbs<<4) != m_info.dimensions.height)) {        m_SeqParamSet.frame_cropping_flag = 1;        m_SeqParamSet.frame_crop_left_offset = 0;        m_SeqParamSet.frame_crop_right_offset =            ((m_SeqParamSet.frame_width_in_mbs<<4) - m_info.dimensions.width)>>1;        m_SeqParamSet.frame_crop_top_offset = 0;        m_SeqParamSet.frame_crop_bottom_offset =            ((m_SeqParamSet.frame_height_in_mbs<<4) - m_info.dimensions.height)>>1;    } else {        m_SeqParamSet.frame_cropping_flag = 0;        m_SeqParamSet.frame_crop_left_offset = 0;        m_SeqParamSet.frame_crop_right_offset = 0;        m_SeqParamSet.frame_crop_top_offset = 0;        m_SeqParamSet.frame_crop_bottom_offset = 0;    }    m_SeqParamSet.vui_parameters_present_flag = 0;    // Calculate the Level Based on encoding parameters (assume 30 fps).    MB_per_frame = m_SeqParamSet.frame_width_in_mbs * m_SeqParamSet.frame_height_in_mbs;    MB_per_sec = (Ipp32u)(MB_per_frame * m_info.FrameRate);    if (m_info.level_idc==0)    {        if ((MB_per_frame <= 99) && (MB_per_sec <= 1485)) {            m_SeqParamSet.level_idc = 10;   // Level 1        } else if ((MB_per_frame <= 396) && (MB_per_sec <= 2970)) {            m_SeqParamSet.level_idc = 11;   // Level 1.1        } else if ((MB_per_frame <= 396) && (MB_per_sec <= 5940)) {            m_SeqParamSet.level_idc = 12;   // Level 1.2        } else if ((MB_per_frame <= 396) && (MB_per_sec <= 11880)) {            m_SeqParamSet.level_idc = 20;   // Level 2        } else if ((MB_per_frame <= 792) && (MB_per_sec <= 19800)) {            m_SeqParamSet.level_idc = 21;   // Level 2.1        } else if ((MB_per_frame <= 1620) && (MB_per_sec <= 20250)) {            m_SeqParamSet.level_idc = 22;   // Level 2.2        } else if ((MB_per_frame <= 1620) && (MB_per_sec <= 40500)) {            m_SeqParamSet.level_idc = 30;   // Level 3        } else if ((MB_per_frame <= 3600) && (MB_per_sec <= 108000)) {            m_SeqParamSet.level_idc = 31;   // Level 3.1        } else if ((MB_per_frame <= 5120) && (MB_per_sec <= 216000)) {            m_SeqParamSet.level_idc = 32;   // Level 3.2        } else if ((MB_per_frame <= 8192) && (MB_per_sec <= 245760)) {            m_SeqParamSet.level_idc = 40;   // Level 4        } else if ((MB_per_frame <= 19200) && (MB_per_sec <= 491520)) {            m_SeqParamSet.level_idc= 50;    // Level 5        } else {            m_SeqParamSet.level_idc= 51;    // Level 5.1        }    }    else    {        m_SeqParamSet.level_idc = m_info.level_idc;    }    // Precalculate these values so we have them for later (repeated) use.    m_SeqParamSet.MaxMbAddress = (m_SeqParamSet.frame_width_in_mbs *                                      m_SeqParamSet.frame_height_in_mbs) - 1;    SetDPBSize();} // SetSequenceParameters/************************************************************* *  Name: SetPictureParameters *  Description:  Fill in the Picture Parameter Set for this *  sequence.  Can only change at an IDR picture. *************************************************************/voidH264VideoEncoder::SetPictureParameters(PictureStructure picture_structure){    m_PicParamSet.pic_parameter_set_id = 0;    // Assumes that there is only one sequence param set to choose from    m_PicParamSet.seq_parameter_set_id = m_SeqParamSet.seq_parameter_set_id;    m_PicParamSet.entropy_coding_mode = m_info.entropy_coding_mode;    m_PicParamSet.pic_order_present_flag = 0;    m_PicParamSet.weighted_pred_flag = 0;    // We use implicit weighted prediction (2) when B frame rate can    // benefit from it.  When B_Frame_rate == 0 or 1, it doesn't matter,    // so we do what is faster (0).    m_PicParamSet.weighted_bipred_idc = m_info.use_implicit_weighted_bipred ? 2 : 0;    // Default to P frame constant quality at time of an IDR    m_PicParamSet.pic_init_qp = m_info.rate_controls.quant;    m_PicParamSet.pic_init_qs = 26;     // Not used    m_PicParamSet.chroma_qp_index_offset = 0;    m_PicParamSet.deblocking_filter_variables_present_flag = 1;    m_PicParamSet.constrained_intra_pred_flag = 0;    // We don't do redundant slices...    m_PicParamSet.redundant_pic_cnt_present_flag = 0;    // In the future, if flexible macroblock ordering is    // desired, then a macroblock allocation map will need    // to be coded and the value below updated accordingly.    m_PicParamSet.num_slice_groups = 1;     // Hard coded for now    m_PicParamSet.SliceGroupInfo.slice_group_map_type = 0;    m_PicParamSet.SliceGroupInfo.t3.pic_size_in_map_units = 0;    m_PicParamSet.SliceGroupInfo.t3.pSliceGroupIDMap = NULL;    // I guess these ned to be 1 or greater since they are written as "minus1".    // TODO VSI, what actually goes here???    m_PicParamSet.num_ref_idx_l0_active = (picture_structure != FRAME_PICTURE)? 2 : 1;    m_PicParamSet.num_ref_idx_l1_active = 1;    m_PicParamSet.mb_width = m_SeqParamSet.frame_width_in_mbs;    m_PicParamSet.mb_height = (picture_structure != FRAME_PICTURE)? m_SeqParamSet.frame_height_in_mbs/2                                     : m_SeqParamSet.frame_height_in_mbs;    m_PicParamSet.picture_structure = picture_structure;} // SetPictureParameters/************************************************************* *  Name: SetSliceHeader *  Description:  Given the ePictureType and m_info *                fill in the slice header for this slice ************************************************************/voidH264VideoEncoder::SetSliceHeader(    H264EncoderFrame * m_pCurrentFrame,    EnumPicClass // ePictureClass){    int frame_num = m_pCurrentFrame->m_FrameNum;    // Right now, we always work with frame nums modulo 256    m_SliceHeader.frame_num = frame_num % m_uTRWrapAround;    // Assumes there is only one picture parameter set to choose from    m_SliceHeader.pic_parameter_set_id = m_PicParamSet.pic_parameter_set_id;    m_SliceHeader.field_pic_flag = (Ipp8u)(m_PicParamSet.picture_structure != 0);    m_SliceHeader.bottom_field_flag = (Ipp8u)(m_PicParamSet.picture_structure == BOTTOM_FIELD);    m_SliceHeader.direct_spatial_mv_pred_flag = m_info.use_spatial_direct_pred;    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;    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)        );    //m_TopPicOrderCnt = m_PicOrderCnt;    //m_BottomPicOrderCnt = m_TopPicOrderCnt + 1; // ????    if (m_SeqParamSet.pic_order_cnt_type == 0) {        m_SliceHeader.pic_order_cnt_lsb = m_pCurrentFrame->PicOrderCnt(m_field_index) & ~(1 << m_SeqParamSet.log2_max_pic_order_cnt_lsb);    }    m_SliceHeader.adaptive_ref_pic_marking_mode_flag=0;    // We don't do redundant slices...    // Right now we disable the block edge filter only if the global encoder option    // says so.    m_info.slice_parms.disable_deblocking_filter_idc =            m_info.Deblocking_Filter_Mode;    if (m_info.Deblocking_Filter_Mode == 1) {        m_info.slice_parms.slice_alpha_c0_offset = -51;        m_info.slice_parms.slice_beta_offset = -51;    } else {        m_info.slice_parms.slice_alpha_c0_offset =            (Ipp8s)(m_info.Deblocking_Filter_Alpha)<<1;        m_info.slice_parms.slice_beta_offset =            (Ipp8s)(m_info.Deblocking_Filter_Beta)<<1;    }    m_SliceHeader.disable_deblocking_filter_idc =        m_info.slice_parms.disable_deblocking_filter_idc;} // SetSliceHeader/************************************************************* *  Name:         encodeFrameHeader *  Description:  Write out the frame header to the bit stream. ************************************************************/StatusH264VideoEncoder::encodeFrameHeader(CH264pBs *bs,                           H264_Image &dst,                           bool bIDR_Pic){    Status ps = UMC_OK;    // First, write a picture delimiter for the frame.    ps = bs->PutPicDelimiter(m_PicType);    bs->WriteTrailingBits();    // Write RBSP Trailing Bits    // Copy PicDelimiter RBSP to the end of the output buffer after    // Adding start codes and SC emulation prevention.    dst.size += bs->EndOfNAL((dst.data + dst.size),                              0,                              NAL_UT_PD);    // If this is an IDR picture, write the seq and pic parameter sets    if (bIDR_Pic) {        // Write the seq_parameter_set_rbsp        ps = bs->PutSeqParms(m_SeqParamSet);        bs->WriteTrailingBits();    // Write RBSP Trailing Bits        // Copy Sequence Parms RBSP to the end of the output buffer after        // Adding start codes and SC emulation prevention.        dst.size += bs->EndOfNAL((dst.data + dst.size),                                  1,                                  NAL_UT_SPS);        ps = bs->PutPicParms(m_PicParamSet, m_SeqParamSet);        bs->WriteTrailingBits();    // Write RBSP Trailing Bits        // Copy Picture Parms RBSP to the end of the output buffer after        // Adding start codes and SC emulation prevention.        dst.size += bs->EndOfNAL((dst.data + dst.size),                                  1,                                  NAL_UT_PPS);    }    return ps;}// ===========================================================================

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -