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

📄 umc_me.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    }
    return tmp;
}

bool MeBase::EstimateFrame(MeParams *par, MeFrame *res)
{
    //check and save input
    m_MePar = par;
    bool no_skip = false;

    switch(m_stream_type)
    {
    case MPEG2_VIDEO:
        GetPredictor = &UMC::MeBase::GetPredictorMPEG2;
        break;
    case VC1_VIDEO:
        if(m_MePar->SearchDirection == forward_search)
            GetPredictor = &UMC::MeBase::GetMedianHibrid;
        else
            GetPredictor = &UMC::MeBase::GetMedian;
        break;
    default:
        assert(0);
    }

    if(!CheckParams(false))
        return false;

    //estimate
    m_pRefFrameY =m_MePar->pRefFY[0] ;
    m_pRefFrameYDwn4 = m_pRefFrameFYDwn4;
    m_predictor_index = 0;

    for(Ipp32s y=0; y<m_HeightMB; y++){
        for(Ipp32s x=0; x<m_WidthMB; x++){
            m_CurMB = MeMV(x,y);
            m_adr = m_WidthMB*y + x;
            mbSkippedStatus = non_skipped;
            no_skip = !m_MePar->toProcessSkipped || ((m_stream_type == MPEG2_VIDEO) && (x == 0 || x == m_WidthMB - 1 || m_ResMB[m_adr-1].MbType == MbIntra));

            if(m_MePar->SearchDirection == forward_search)
            {
                m_CurPrediction = (this->*(GetPredictor))();
                if(!no_skip)
                {
                    if(EstimateSkipped())
                    {
                        mbSkippedStatus = skipped_forward;
                        MakeMbModeDecision();
                        continue;
                    }
                }
                EstimateMB();
            }
            else if(m_MePar->SearchDirection == bidir_search)
            {
                m_pRefFrameY =m_MePar->pRefBY[0] ;
                m_predictor_index = m_MePar->MbPart & Mb8x8 ? 4 : 1;
                m_CurPredictionB = m_CurPrediction = (this->*(GetPredictor))();

                if(!no_skip)
                {
                    if(EstimateSkipped())
                    {
                        mbSkippedStatus = skipped_backward;
                        MakeMbModeDecision();
                        continue;
                    }
                }

                m_pRefFrameY =m_MePar->pRefFY[0] ;
                m_predictor_index = 0;
                m_CurPredictionF = m_CurPrediction = (this->*(GetPredictor))();

                if(!no_skip)
                {
                    if(EstimateSkipped())
                    {
                        mbSkippedStatus = skipped_forward;
                        MakeMbModeDecision();
                        continue;
                    }
                    if(EstimateSkippedBidir())
                    {
                        mbSkippedStatus = skipped_bidir;
                        MakeMbModeDecision();
                        continue;
                    }
                }
                //direct MB:
                if(m_MePar->toProcessDirect)
                {
                    m_CurPrediction = m_MVDirectFW[m_adr];
                    m_CurPredictionB = m_MVDirectBW[m_adr];
                    if(EstimateSkippedBidir())
                    {
                        mbSkippedStatus = direct;
                        MakeMbModeDecision();
                        continue;
                    }
                }

                //non-skipped MB:
                m_pRefFrameY =m_MePar->pRefBY[0] ;
                m_pRefFrameYDwn4 = m_pRefFrameBYDwn4;
                m_CurPrediction = m_CurPredictionB;
                EstimateMB();

                memcpy(&(m_BestBCost[0][0]), &(m_BestCost[0]), 5*sizeof(m_BestCost[0]));
                memcpy(&(m_BestBMV[0][0]), &(m_BestMV[0]), 5*sizeof(m_BestMV[0]));

                m_pRefFrameY =m_MePar->pRefFY[0] ;
                m_pRefFrameYDwn4 = m_pRefFrameFYDwn4;
                m_CurPrediction = m_CurPredictionF;
                EstimateMB();
            }//if(m_MePar->SearchDirection == bidir_search)
            else assert(0);
            MakeMbModeDecision();
         }
    }

    //save results
    res->NumOfMVs = m_NumOfMVs;
    res->MBs = m_ResMB;

    return true;
}

void MeBase::Close()
{
    Ipp32s i;
    for(i = 0; i < MaxRefFrame; i++)
    {
        if(m_BestBCost[i])free(m_BestBCost[i]);
        if(m_BestBMV[i])free(m_BestBMV[i]);
    }
    if(m_BestBCost)free(m_BestBCost);
    if(m_BestBMV)free(m_BestBMV);
    if(m_BestCost)free(m_BestCost);
    if(m_BestMV)free(m_BestMV);

    if(m_16x16buf)free(m_16x16buf);
    if(m_16x16bufB)free(m_16x16bufB);
    if(m_bufAvrg)free(m_bufAvrg);
    if(m_ResMB)free(m_ResMB);
    if(m_pSrcFrameYDwn4)free(m_pSrcFrameYDwn4);
    if(m_pRefFrameFYDwn4)free(m_pRefFrameFYDwn4);
    if(m_pRefFrameBYDwn4)free(m_pRefFrameBYDwn4);
    if(m_MVDirectFW)free(m_MVDirectFW);
    if(m_MVDirectBW)free(m_MVDirectBW);

    m_16x16buf= NULL;
    m_16x16bufB = NULL;
    m_bufAvrg = NULL;
    m_ResMB= NULL;
    m_pSrcFrameYDwn4= NULL;
    m_pRefFrameFYDwn4 = NULL;
    m_pRefFrameBYDwn4 = NULL;
    m_BestCost = NULL;
    m_BestMV = NULL;
    m_BestBCost = NULL;
    m_BestBMV = NULL;
    m_MVDirectFW = NULL;
    m_MVDirectBW = NULL;
}

bool MeBase::CheckParams(bool FirsCall)
{
    if(FirsCall){
        Ipp32s NumOfMVs=0;
        if(m_MeParInit->MbPart & Mb16x16) NumOfMVs = 1;
        if(m_MeParInit->MbPart & Mb8x8) NumOfMVs = 4;
        if(m_MeParInit->SearchDirection == bidir_search) NumOfMVs *= 2;
        if(m_MeParInit->CostMetrics != SAD && m_MeParInit->CostMetrics != SADT) return false;
        m_CostMetrics = m_MeParInit->CostMetrics;

        //check capabilities
        if( (m_MeParInit->width&7) || (m_MeParInit->height&7)) return false;
      //  if( m_MeParInit->refPadding<32 ||(m_MeParInit->refPadding&15) ) return false;
      //  if( m_MeParInit->refPadding!=32) return false; // TODO:  fix this

        m_WidthMB = (m_MeParInit->width+15)/16;
        m_HeightMB = (m_MeParInit->height+15)/16;

        m_Padding = m_MeParInit->refPadding;

        m_NumOfMVs = NumOfMVs;
        return true;
    }

    Ipp32s NumOfMVs=0;
    if(m_MePar->MbPart & Mb16x16) NumOfMVs = 1;
    if(m_MePar->MbPart & Mb8x8) NumOfMVs = 4;
    if(m_MePar->SearchDirection == bidir_search) NumOfMVs *= 2;
    //temporary!!!
    //if(m_MePar->SkippedMetrics != maxad) m_MePar->SkippedMetrics = maxad;
   // if(m_MePar->SkippedMetrics != maxad && m_MePar->SkippedMetrics != sad) return false;
    if(m_MePar->SkippedMetrics == maxad) m_SkippedThreshold = 2;
    else if(m_MePar->SkippedMetrics == sad) m_SkippedThreshold = 60;
    else if(m_MePar->SkippedMetrics == sadt)m_SkippedThreshold = m_MePar->Quant;

    //check actual request
    //check if current input parameters violate Init agreement
    if(m_NumOfMVs < NumOfMVs) return false;

    if( m_MePar->SearchRange.x < 8 || m_MePar->SearchRange.x > 256 ||
        m_MePar->SearchRange.y < 8 || m_MePar->SearchRange.y > 256)return false;
    if( m_MePar->Interpolation != Vc1QpBicubic && m_MePar->Interpolation != Bilinear) return false;
    if( m_MePar->MbPart & Mb16x8 || m_MePar->MbPart & Mb8x16 ||
        m_MePar->MbPart & Mb4x4  || m_MePar->MbPart & Mb8x8) return false;
    //if( m_MePar->PixelType == HalfPixel) return false;

    m_SearchRangeX = 4*m_MePar->SearchRange.x;
    m_SearchRangeY = 4*m_MePar->SearchRange.y;

    m_PicRange.top_left.x     = m_MePar->PicRange.top_left.x;
    m_PicRange.top_left.y     = m_MePar->PicRange.top_left.y;
    m_PicRange.bottom_right.x = m_MePar->PicRange.bottom_right.x;
    m_PicRange.bottom_right.y = m_MePar->PicRange.bottom_right.y;

    m_SrcStep = m_MePar->srcStep;
    m_RefStep = m_MePar->refStep;

    if(m_MePar->SearchDirection == bidir_search && m_pRefFrameBYDwn4 == NULL) return false;

    //check input ptrs
    if( m_MePar->pSrcY == NULL) return false;
    if( (m_MePar->SearchDirection == forward_search || m_MePar->SearchDirection == bidir_search)&& (m_MePar->pRefFY==NULL || m_MePar->pRefFY[0]==NULL)) return false;
    if( m_MePar->SearchDirection == bidir_search && (m_MePar->pRefBY==NULL || m_MePar->pRefBY[0]==NULL)) return false;

    //check stupid errors
    if((m_MePar->MbPart & Mb16x16) && (m_MePar->MbPart & Mb8x8) ||
        !(m_MePar->MbPart & Mb16x16) && !(m_MePar->MbPart & Mb8x8)) return false;
    if(m_MePar->SearchDirection != forward_search && m_MePar->SearchDirection != bidir_search) return false;
    if(m_MePar->PixelType != IntegerPixel && m_MePar->PixelType != HalfPixel && m_MePar->PixelType != QuarterPixel) return false;
    if(m_MePar->PixelType == HalfPixel && m_MePar->Interpolation != Bilinear)return false;
  //  if(m_MePar->PixelType != HalfPixel && m_MePar->PixelType != IntegerPixel && m_MePar->Interpolation == MpegInterpolation)return false;

    if(!m_MePar->SetSpeedQualityParams()) return false;

    m_pSrcFrameY = m_MePar->pSrcY;
    //temporary: no process skipped macroblocks
    m_MePar->toProcessSkipped = false;
    //m_pRefFrameY =m_MePar->pRefFY[0] ;
    DownsampleReference();

    return true;
 }

template<typename T> void MeBase::DownSamplePicture4(const T* pSrc, IppiSize srcSize, Ipp32s srcStep, T* pDst)
{
    if((srcSize.height&3)!=0 && (srcSize.width&3)!=0)
        assert(0);
    for(Ipp32s y=0; y<srcSize.height/4; y++)
        for(Ipp32s x=0; x<srcSize.width/4; x++){
            Ipp32s avg = 0;
            for(Ipp32s i=0; i<4; i++)
                for(Ipp32s j=0; j<4; j++){
                    avg += *(pSrc + (4*y+i)*srcStep/sizeof(T) + 4*x+j);
                }
           *(pDst+y*srcStep/(4*sizeof(T))+x) = (T)((avg+8)/16);
        }
}

void MeBase::DownsampleReference()
{
    //Sleep(100); //to workaround bag in MS encoder about padding

    IppiSize srcSize = {16*m_WidthMB,16*m_HeightMB};
    IppiRect srcRoi = {0,0,srcSize.width,srcSize.height};
    IppiSize srcRoiDwn = {srcSize.width/4,srcSize.height/4};
    IppiSize refSize = {srcSize.width+m_Padding*2,srcSize.height+m_Padding*2};
    IppiRect refRoi = {0,0,refSize.width,refSize.height};
    IppiSize refRoiDwn = {refSize.width/4,refSize.height/4};

    ippiResize_8u_C1R(m_pSrcFrameY, srcSize, m_SrcStepDwn4, srcRoi, m_pSrcFrameYDwn4, m_SrcStepDwn4/4, srcRoiDwn, 1/4., 1/4., IPPI_INTER_SUPER);
    ippiResize_8u_C1R(m_MePar->pRefFY[0]-m_Padding-m_Padding*m_RefStepDwn4, refSize, m_RefStepDwn4, refRoi, m_pRefFrameFYDwn4, m_RefStepDwn4/4, refRoiDwn, 1/4., 1/4., IPPI_INTER_SUPER);
    if(m_MePar->SearchDirection == bidir_search)
        ippiResize_8u_C1R(m_MePar->pRefBY[0]-m_Padding-m_Padding*m_RefStepDwn4, refSize, m_RefStepDwn4, refRoi, m_pRefFrameBYDwn4, m_RefStepDwn4/4, refRoiDwn, 1/4., 1/4., IPPI_INTER_SUPER);
}



Ipp32s MeBase::GetT2()
{
    Ipp32s T2, SadA=IPP_MAX_32S, SadB=IPP_MAX_32S, SadC=IPP_MAX_32S, SadCol=IPP_MAX_32S;

    if(m_CurMB.y != 0)                                                 SadA = m_ResMB[m_adr-m_WidthMB].MbCosts[0];
    if(m_CurMB.y != 0 && m_CurMB.x < m_WidthMB-1)  SadB = m_ResMB[m_adr-m_WidthMB+1].MbCosts[0];
    if(m_CurMB.x != 0)                                                 SadC = m_ResMB[m_adr-1].MbCosts[0];

    T2 = 6*IPP_MIN(IPP_MIN(SadA,SadB), IPP_MIN(SadC,SadCol))/5 + 128;
    //T2 = IPP_MIN(IPP_MIN(SadA,SadB), IPP_MIN(SadC,SadCol));

    return T2;
}

inline void MeBase::ResetBestCost()
{
    for(int i=0; i<sizeof(m_BestCost)/sizeof(Ipp32s); i++)
        m_BestCost[i] = IPP_MAX_32S;
}

Ipp32s MeBase::WeightMV(MeMV mv)
{
    Ipp32s d = abs(mv.x-m_CurPrediction.x) + abs(mv.y-m_CurPrediction.y);
    Ipp32s cost;
    for(cost=7; cost>=0; cost--)
        if(d > (1<<cost))break;

    return 4*cost;
    //return 0;
}

template<MeMbPart mt, MeInPixType pix> inline void MeBase::CalcCost(const Ipp8u*  pSrc,Ipp32s  srcStep,const Ipp8u*  pRef,Ipp32s  refStep,MeCost * cost, Ipp32s  mc_type, MeCostEnum cst)
{
    switch(cst)
    {
    case SAD:

⌨️ 快捷键说明

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