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

📄 umc_h264_gen_enc.cpp

📁 这是在PCA下的基于IPP库示例代码例子,在网上下了IPP的库之后,设置相关参数就可以编译该代码.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
#ifdef _DEBUG    PrintTotalBits();#endif}// ==================================================================================voidH264VideoEncoder::Deallocate_Buffers(){    if (m_pQPMap)    {        H264_Free(m_pQPMap);        m_pQPMap = NULL;    }    m_bScratchBufferAllocated = false;    if (m_pAllocEncoderInst)    {        H264_Free(m_pAllocEncoderInst);        m_pAllocEncoderInst = NULL;    }    if (m_bs1)    {        delete m_bs1;        m_bs1 = NULL;    }    m_cpb.destroy();    m_dpb.destroy();    Free_Core_Memory();    if (m_rate_control)    {        delete m_rate_control;        m_rate_control = NULL;    }}// This function is called when the encoder's Start_Sequence function is// called.  This signals that dimension dependent variables such as frame// buffers should now be allocated.//StatusH264VideoEncoder::Allocate_Buffers(){    Ipp32s             iFrame;    Ipp32s             iBFrmsShared;    Ipp32u              uPaddedHeight, uPaddedWidth;    Ipp32u padded_width, padded_height;    Status     status = UMC_OK;    uPaddedHeight = (m_info.dimensions.height + 0xf) & ~0xf;    uPaddedWidth  = (m_info.dimensions.width + 0xf) & ~0xf;    m_HeightInMBs  = (uPaddedHeight + 15) >> 4;    m_WidthInMBs   = (uPaddedWidth  + 15) >> 4;    m_pQPMap = (Ipp8u *)H264_Allocate(m_HeightInMBs * m_WidthInMBs, true );    if (!m_pQPMap)    {        status = UMC_FAILED_TO_ALLOCATE_BUFFER;        goto done;    }    m_QPMapSize = m_HeightInMBs * m_WidthInMBs;    // not sure if this is needed... but delete the FrameList if it exists    // Allocate the Reference Frames and    //  call H264VideoEncoder::Allocate_Core_Memory    // In H.263+, we encode and decode the padded frames (padded to the right    // and bottom to multiples of 16). The Input frame dimensions are used    // for display purposes only.    padded_height = ( m_info.dimensions.height + 0xf) & ~0xf;    padded_width  = ( m_info.dimensions.width + 0xf) & ~0xf;    m_HeightInMBs   = padded_height >> 4;    m_WidthInMBs    = padded_width  >> 4;    m_NumMBs        = m_HeightInMBs * m_WidthInMBs;    // Allocate space for the bitstream and a bit stream copy (used for IPB)    if  (!m_bScratchBufferAllocated )    {        // Notice the actual non-padded frame dimensions are used.  We had this        // clarified with the ITU.        Ipp32u uSize = GetBsBufferMaxSize(                                    m_info.dimensions.width,                                    m_info.dimensions.height );        // Notice the encoder's internal bitstream buffer is 2x the standard size        m_pAllocEncoderInst = (Ipp8u *)H264_Allocate( uSize * 2, true);        if (NULL == m_pAllocEncoderInst)        {            status = UMC_FAILED_TO_ALLOCATE_BUFFER;            goto done;        }        // the bit stream buffer is 32 byte aligned.        m_pBitStream = H264_ALIGN(m_pAllocEncoderInst, 32);        m_bScratchBufferAllocated = true;    }    m_pReconstructFrame = new H264EncoderFrame(0,m_info.dimensions.width,m_info.dimensions.height,1,1,status);    if (!m_pReconstructFrame)    {        status = UMC_FAILED_TO_ALLOCATE_BUFFER;        goto done;    }    else if (status != UMC_OK)    {        delete m_pReconstructFrame;        m_pReconstructFrame = NULL;        goto done;    }    // allocate bitstream objects    m_bs1 = new CH264pBs(        //m_fid,        m_pBitStream,        GetBsBufferMaxSize(m_info.dimensions.width,                           m_info.dimensions.height),        status);    if (!m_bs1)    {        status = UMC_FAILED_TO_ALLOCATE_BUFFER;        goto done;    }    else if (status != UMC_OK)    {        delete m_bs1;        m_bs1 = NULL;        goto done;    }    Allocate_Core_Memory(m_info.Num_Slices,                         m_WidthInMBs,                         m_HeightInMBs,                         m_bs1);//CConstRateControl(Ipp32u c_width,Ipp32u c_height,Ipp32u c_pitch,Ipp32u target_bps,Ipp32u _qp_min,Ipp32u _qp_max);    m_rate_control_method = m_info.rate_controls.method;    switch(m_info.rate_controls.method) {        case H264_RCM_BITRATE:            {                m_rate_control = new CH264ConstRateControl(m_info.dst_width,m_info.dst_height,CalcPitchFromWidth(m_info.dst_width),                m_info.rate_controls.bitrate,QP_MIN,QP_MAX);                if (m_rate_control)                {                    ((CH264ConstRateControl *)m_rate_control)->SetRateControlOptions(&m_info.arco);                }            }            break;        case H264_RCM_MPEG2:            {                BitRate = m_info.rate_controls.bitrate;                FrameRate = m_info.FrameRate;                qscale[INTRASLICE] = m_info.key_frame_controls.rate_controls.quant;                qscale[PREDSLICE] = m_info.rate_controls.quant;                qscale[BPREDSLICE] = m_info.B_frame_rate_controls.quant;                M = m_info.B_Frame_Rate+1;                N = min(m_info.key_frame_controls.interval,m_info.numFramesToEncode);                m_rate_control = NULL;                InitRateControl((m_info.dimensions.width+15)>>4,                                                 (m_info.dimensions.height+15)>>4);            }        default:            m_rate_control = NULL;    }    // Allocate the input color converted frame queue for the layer    // # of frames needed by all layers using this InputFrmQ + 1 for P    for ( iFrame = iBFrmsShared = 0; iFrame < profile_frequency; iFrame++ )    {        if ( eFrameType[ iFrame ] == BPREDPIC )        {            iBFrmsShared++;        }    }    // reset the index into the Profile    m_iProfileIndex = 0;done:    // if we have an error creating or allocating above then    // cleanup any objects that were successfully created.    if ( status != UMC_OK )    {        Deallocate_Buffers();    }    return status;}// Note that if B frames are used they will be written in encode order,// not display (or original source) order.Status H264VideoEncoder::EncodePicture(H264_Image    &dst){    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 (m_PicType)    {        case INTRAPIC:            if (m_uFrames_Num == 0 && m_PicParamSet.picture_structure != BOTTOM_FIELD) {                // 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 = DISPOSABLE_PIC;            break;        default:            // Unsupport 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.            if(m_PicParamSet.picture_structure != BOTTOM_FIELD) {                //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.    if(m_PicParamSet.picture_structure != BOTTOM_FIELD) {        SetPictureQuant();    }    // Set up the values in the slice header    SetSliceHeader( m_pCurrentFrame, ePic_Class );    if(m_PicParamSet.picture_structure != BOTTOM_FIELD) {        // 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(),                                            m_PicType & ((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);    }    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;    }    status = Start_Picture(&ePic_Class, &m_SeqParamSet, &m_PicParamSet, &m_SliceHeader,                                            m_bs1, m_PicType);    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_PicParamSet.mb_width << 4,      // width, padded to MB edge            m_PicParamSet.mb_height << 4,     // height, padded to MB edge            m_pCurrentFrame->m_pitch, //???? for fields what is about future frame? was it field or frame?            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 (m_PicType == PREDPIC) {            slice_type = PREDSLICE;        } else if (m_PicType == 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_PicParamSet.mb_width*m_PicParamSet.mb_height);        if (status != UMC_OK)            goto done;    }

⌨️ 快捷键说明

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