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

📄 h263_enc_misc.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
        mBPicsearchHorBack = par->BPicsearchWidthBack;
        mBPicsearchVerBack = par->BPicsearchHeightBack;
        // calc pic_fcode_forward for BPics
        i = IPP_MAX(mBPicsearchHorForw, mBPicsearchVerForw);
        j = i << 1;
        mBPicfcodeForw = 1;
        while (j > ((16 << mBPicfcodeForw) - 1))
            mBPicfcodeForw ++;
        // calc pic_fcode_backward for BPics
        i = IPP_MAX(mBPicsearchHorBack, mBPicsearchHorBack);
        j = i << 1;
        mBPicfcodeBack = 1;
        while (j > ((16 << mBPicfcodeBack) - 1))
            mBPicfcodeBack ++;
    }
#endif
    mPlanes = (mIPicdist == 1) ? 1 : (mBPicdist == 0) ? 2 : 2 + mBPicdist + 1;
    mSourceWidth = par->Width;
    mSourceHeight = par->Height;
    mSourceFormat = YUV_CHROMA_420;
    mExpandSize = 16;
    mExpandSizeA = (mExpandSize + 15) & (~15);
    mNumMacroBlockPerRow = (mSourceWidth + 15) / 16;
    mNumMacroBlockPerCol = (mSourceHeight + 15) / 16;
    mNumMacroBlockPerPic = mNumMacroBlockPerRow * mNumMacroBlockPerCol;
    mStepLuma = mExpandSizeA * 2 + mNumMacroBlockPerRow * 16;
    mLumaPlaneSize = mStepLuma * (mExpandSizeA * 2 + mNumMacroBlockPerCol * 16);
    mStepChroma = (mExpandSizeA / 2) * 2 + mNumMacroBlockPerRow * 8;
    mChromaPlaneSize = mStepChroma * ((mExpandSizeA / 2) * 2 + mNumMacroBlockPerCol * 8);
    mSceneChangeThreshold = (mNumMacroBlockPerPic * par->SceneChangeThreshold + 50) / 100;
    mIsInit = true;
    // buffers allocation
    mFrame = new h263e_Frame[mPlanes];
    if (!mFrame)
      stsAlloc = ippStsMemAllocErr;
    mRTPdata.MBpos = ippsMalloc_32u(mNumMacroBlockPerPic);
    mRTPdata.MBquant = ippsMalloc_8u(mNumMacroBlockPerPic);
    mRTPdata.MBpredMV = (IppMotionVector*)ippsMalloc_8u(mNumMacroBlockPerPic * sizeof(IppMotionVector));
    if (mVideoPicture.advPred) {
      mRTPdata.MBpredMV1 = (IppMotionVector*)ippsMalloc_8u(mNumMacroBlockPerPic * sizeof(IppMotionVector));
      if (!mRTPdata.MBpredMV1)
        stsAlloc = ippStsMemAllocErr;
    } else
      mRTPdata.MBpredMV1 = NULL;
    mRTPdata.GOBstartPos =  ippsMalloc_32u(mVideoPicture.num_gobs_in_pic);
    if (!mRTPdata.MBpos || !mRTPdata.MBquant || !mRTPdata.MBpredMV || !mRTPdata.GOBstartPos)
      stsAlloc = ippStsMemAllocErr;
    mRTPdata.codingModes = 0; // forbidden src format 000 to be returned if plusptype is present
    // init bitstream buffer
    if (par->bsBuffer && (par->bsBuffSize > 0)) {
        cBS.mBuffer = par->bsBuffer;
        cBS.mBuffSize = par->bsBuffSize;
        mbsAlloc = false;
    } else {
        cBS.mBuffSize = mSourceWidth * mSourceHeight;
        cBS.mBuffer = ippsMalloc_8u(cBS.mBuffSize);
        if (!cBS.mBuffer)
          stsAlloc = ippStsMemAllocErr;
        mbsAlloc = true;
    }
    cBS.mPtr = cBS.mBuffer;
    if (mVideoSequence.data_partitioned) {
        mBuffer_1 = ippsMalloc_8u(mSourceWidth * mSourceHeight >> 1);
        mBuffer_2 = ippsMalloc_8u(mSourceWidth * mSourceHeight >> 1);
        if (!mBuffer_1 || !mBuffer_2)
          stsAlloc = ippStsMemAllocErr;
    } else {
        mBuffer_1 = mBuffer_2 = NULL;
    }
    mMBinfo = new h263e_MacroBlock[mNumMacroBlockPerPic];
//    mMEfastSADsize = (IPP_MAX(IPP_MAX(mPPicsearchHor, mBPicsearchHorForw), mBPicsearchHorBack) * 2 + 1) * (IPP_MAX(IPP_MAX(mPPicsearchVer, mBPicsearchVerForw), mBPicsearchVerBack) * 2 + 1);
    mMEfastSADsize = (mPPicsearchHor * 2 + 1) * (mPPicsearchVer * 2 + 1);
    mMEfastSAD = ippsMalloc_32s(mMEfastSADsize);
    if (!mMBinfo || !mMEfastSAD)
      stsAlloc = ippStsMemAllocErr;

    if (stsAlloc != ippStsNoErr) {
      Close();
      ErrorMessage(VM_STRING("Not enough memory"));
      return H263_STS_ERR_NOMEM;
    }

    {
      h263e_MacroBlock *mbCurr = mMBinfo;
      for (i = 0; i < mNumMacroBlockPerCol; i ++) {
          for (j = 0; j < mNumMacroBlockPerRow; j ++) {
            h263e_MacroBlock *mbA = mbCurr - 1;
            h263e_MacroBlock *mbC = mbCurr - mNumMacroBlockPerRow;
            mbCurr->block[0].predA = &mbA->block[1];
            mbCurr->block[0].predC = &mbC->block[2];
            mbCurr->block[1].predA = &mbCurr->block[0];
            mbCurr->block[1].predC = &mbC->block[3];
            mbCurr->block[2].predA = &mbA->block[3];
            mbCurr->block[2].predC = &mbCurr->block[0];
            mbCurr->block[3].predA = &mbCurr->block[2];
            mbCurr->block[3].predC = &mbCurr->block[1];
            mbCurr->block[4].predA = &mbA->block[4];
            mbCurr->block[4].predC = &mbC->block[4];
            mbCurr->block[5].predA = &mbA->block[5];
            mbCurr->block[5].predC = &mbC->block[5];
            mbCurr++;
          }
      }

      for (j = 0; j < mNumMacroBlockPerRow; j ++) {
        h263e_MacroBlock *mbCurr = &mMBinfo[j];
        mbCurr->block[0].predC = NULL;
        mbCurr->block[1].predC = NULL;
        mbCurr->block[4].predC = NULL;
        mbCurr->block[5].predC = NULL;
      }

      for (i = 0; i < mNumMacroBlockPerCol; i ++) {
        h263e_MacroBlock *mbCurr = &mMBinfo[i*mNumMacroBlockPerRow];
        mbCurr->block[0].predA = NULL;
        mbCurr->block[2].predA = NULL;
        mbCurr->block[4].predA = NULL;
        mbCurr->block[5].predA = NULL;
      }
    }
    // setup frames
    if (mBPicdist == 0) {
      mFrameC = &mFrame[0];
      if (mIPicdist > 1)
        mFrameF = &mFrame[1];
    } else {
      mFrameC = &mFrame[0];
      mFrameF = &mFrame[1];
      mFrameB = &mFrame[0];
      mIndxBPic = 2;
      mNumBPic = 0;
    }
    mPictime = mSyncTime = mSyncTimeB = 0;
    return H263_STS_NOERR;
}


//-----------------------------------------------------------------------------

void ippVideoEncoderH263::PostFrameRC()
{
  Ipp64f  bo, qs, dq;
  int     quant, coding_type;

  mSkipFrame = 0;
  mBitsDesiredTotal += mBitsDesiredFrame;
  coding_type = mVideoPicture.picture_coding_type;

  quant = (coding_type == H263e_PIC_TYPE_I) ? mQuantIPic : (coding_type == H263e_PIC_TYPE_B) ? mQuantBPic : mQuantPPic;

#ifdef PRINT_INFO
  printf("%d  %d %d %d %f \n", mFrameCount, coding_type, quant, mBitsEncodedFrame, mBitsEncodedTotal / (Ipp64f)mBitsDesiredTotal);
#endif

  if (!mFrameSkipped) {
    mRCqa += (1. / quant - mRCqa) / mRCqap;
    h263e_Clip(mRCqa, 1./31. , 1./1.);
    if (coding_type != H263e_PIC_TYPE_I || mIPicdist < 5) // ???
      mRCfa += (mBitsEncodedFrame - mRCfa) / mRCfap;
    if (coding_type == H263e_PIC_TYPE_B) {
      quant = (mQuantPPic * 5 >> 2) + 1;
      h263e_Clip(quant, 2, 31);
      mQuantBPic = quant;
      return;
    }
  }
  qs = pow(mBitsDesiredFrame / mRCfa, 1.5);
  dq = mRCqa * qs;
  bo = (Ipp64f)((Ipp64s)mBitsEncodedTotal - (Ipp64s)mBitsDesiredTotal) / mRCbap / mBitsDesiredFrame;

  if (mFrameSkipEnabled && bo > 1.05 && quant == 31) {
    mSkipFrame = 1;
    return;
  }

  h263e_Clip(bo, -1.0, 1.0);
  //dq = dq * (1.0 - bo);
  dq = dq + (1./31 - dq) * bo;

  h263e_ClipL(dq, 1./31.);
  if (bo > -0.05) {
    h263e_ClipR(dq, 1./2.);
  } else {
    h263e_ClipR(dq, 1./1.);
  }
  quant = (int) (1. / dq + 0.5);
  //h263e_Clip(quant, 2, 31);
  if (quant >= mRCq + 3)
    quant = mRCq + 2;
  else if (quant > mRCq + 1)
    quant = mRCq + 1;
  else if (quant <= mRCq - 3)
    quant = mRCq - 2;
  else if (quant < mRCq - 1)
    quant = mRCq - 1;
  mRCq = mQuantIPic = mQuantPPic = quant;
}

void ippVideoEncoderH263::ErrorMessage(const vm_char *msg)
{
    vm_debug_trace(VM_DEBUG_INFO, __VM_STRING("H.263 encoder error: "));
    vm_debug_trace(VM_DEBUG_INFO, msg);
    vm_debug_trace(VM_DEBUG_INFO, __VM_STRING("\n"));
}

static void h263e_ExpandFrameReplicate(Ipp8u *pSrcDstPlane, Ipp32s frameWidth, Ipp32s frameHeight, Ipp32s expandPels, Ipp32s step)
{
    Ipp8u   *pDst1, *pDst2, *pSrc1, *pSrc2;
    Ipp32s  i, j;
    Ipp32u  t1, t2;

    pDst1 = pSrcDstPlane + step * expandPels;
    pDst2 = pDst1 + frameWidth + expandPels;
    if (expandPels == 8) {
        for (i = 0; i < frameHeight; i ++) {
            t1 = pDst1[8] + (pDst1[8] << 8);
            t2 = pDst2[-1] + (pDst2[-1] << 8);
            t1 = (t1 << 16) + t1;
            t2 = (t2 << 16) + t2;
            ((Ipp32u*)pDst1)[0] = t1;
            ((Ipp32u*)pDst1)[1] = t1;
            ((Ipp32u*)pDst2)[0] = t2;
            ((Ipp32u*)pDst2)[1] = t2;
            pDst1 += step;
            pDst2 += step;
        }
    } else if (expandPels == 16) {
        for (i = 0; i < frameHeight; i ++) {
            t1 = pDst1[16] + (pDst1[16] << 8);
            t2 = pDst2[-1] + (pDst2[-1] << 8);
            t1 = (t1 << 16) + t1;
            t2 = (t2 << 16) + t2;
            ((Ipp32u*)pDst1)[0] = t1;
            ((Ipp32u*)pDst1)[1] = t1;
            ((Ipp32u*)pDst1)[2] = t1;
            ((Ipp32u*)pDst1)[3] = t1;
            ((Ipp32u*)pDst2)[0] = t2;
            ((Ipp32u*)pDst2)[1] = t2;
            ((Ipp32u*)pDst2)[2] = t2;
            ((Ipp32u*)pDst2)[3] = t2;
            pDst1 += step;
            pDst2 += step;
        }
    } else {
        for (i = 0; i < frameHeight; i ++) {
            ippsSet_8u(pDst1[expandPels], pDst1, expandPels);
            ippsSet_8u(pDst2[-1], pDst2, expandPels);
            pDst1 += step;
            pDst2 += step;
        }
    }
    pDst1 = pSrcDstPlane;
    pSrc1 = pSrcDstPlane + expandPels * step;
    pDst2 = pSrc1 + frameHeight * step;
    pSrc2 = pDst2 - step;
    j = frameWidth + 2 * expandPels;
    for (i = 0; i < expandPels; i ++) {
        ippsCopy_8u(pSrc1, pDst1, j);
        ippsCopy_8u(pSrc2, pDst2, j);
        pDst1 += step;
        pDst2 += step;
    }
}

/*
//  padding frame: replication
*/
void ippVideoEncoderH263::ExpandFrame(Ipp8u *pY, Ipp8u *pU, Ipp8u *pV)
{
  if (mExpandSize) {
    Ipp32s  wL, hL, wC, hC, es = (mExpandSize + 1) >> 1;

    wL = mNumMacroBlockPerRow * 16;
    hL = mNumMacroBlockPerCol * 16;
    wC = mSourceWidth >> 1;
    hC = mSourceHeight >> 1;

    h263e_ExpandFrameReplicate(pY-mExpandSize*mStepLuma-mExpandSize, wL, hL, mExpandSize, mStepLuma);
    h263e_ExpandFrameReplicate(pU-es*mStepChroma-es, wC, hC, es, mStepChroma);
    h263e_ExpandFrameReplicate(pV-es*mStepChroma-es, wC, hC, es, mStepChroma);
  }
}

Ipp32s ippVideoEncoderH263::GetCurrentFrameInfo(Ipp8u **pY, Ipp8u **pU, Ipp8u **pV, Ipp32s *stepLuma, Ipp32s *stepChroma)
{
  if (!mIsInit)
    return H263_STS_ERR_NOTINIT;
  *pY = mFrameC->pY;
  *pU = mFrameC->pU;
  *pV = mFrameC->pV;
  *stepLuma = mStepLuma;
  *stepChroma = mStepChroma;
  return H263_STS_NOERR;
}

void ippVideoEncoderH263::OBMC_Macroblock(h263e_MacroBlock *pMBinfo, IppMotionVector *mvCur,
                                          Ipp32s colNum, Ipp32s rowNum, IppiRect limitRectL,
                                          Ipp8u *pYr, Ipp32s stepYr, Ipp8u *pYc, Ipp32s stepYc)
{
  IppMotionVector mvOBMCL, mvOBMCU, mvOBMCR, mvOBMCB, *mvLeft, *mvUpper, *mvRight;
  Ipp32s mbPerRow = mNumMacroBlockPerRow, dx, dy, rt;

  /* get Right MV */
  if (colNum == mNumMacroBlockPerRow - 1)
    mvRight = &mvCur[1];
//  else if ((pMBinfo[1].type & 0xC0) == 0x80) /* INTRA(_Q), no vector for B-part */
  else if (pMBinfo[1].type == IPPVC_MBTYPE_INTRA || pMBinfo[1].type == IPPVC_MBTYPE_INTRA_Q)
    mvRight = &mvCur[1];
  else
    mvRight = pMBinfo[1].mv;
  /* get Left MV */
  if (colNum == 0)
    mvLeft = mvCur - 1;
//  else if ((pMBinfo[-1].type & 0xC0) == 0x80)
  else if (pMBinfo[-1].type == IPPVC_MBTYPE_INTRA || pMBinfo[1].type == IPPVC_MBTYPE_INTRA_Q)
    mvLeft = mvCur - 1;
  else
    mvLeft = pMBinfo[-1].mv;
  /* get Upper MV */
  if (rowNum == 0)
    mvUpper = mvCur - 2;
//  else if ((pMBinfo[-mNumMacroBlockPerRow].type & 0xC0) == 0x80)
  else if (pMBinfo[-mNumMacroBlockPerRow].type == IPPVC_MBTYPE_INTRA || pMBinfo[-mNumMacroBlockPerRow].type == IPPVC_MBTYPE_INTRA_Q)
    mvUpper = mvCur - 2;
  else
    mvUpper = pMBinfo[-mNumMacroBlockPerRow].mv;

  dx = colNum * 16;
  dy = rowNum * 16;
  rt = mVideoPicture.pic_rounding_type;

  h263e_LimitMV(&mvLeft[1], &mvOBMCL, &limitRectL, dx, dy, 8);
  h263e_LimitMV(&mvUpper[2], &mvOBMCU, &limitRectL, dx, dy, 8);
  h263e_LimitMV(&mvCur[1], &mvOBMCR, &limitRectL, dx, dy, 8);
  h263e_LimitMV(&mvCur[2], &mvOBMCB, &limitRectL, dx, dy, 8);
  ippiOBMC8x8HP_MPEG4_8u_C1R(pYr, stepYr, pYc, stepYc, &mvCur[0], &mvOBMCL, &mvOBMCR, &mvOBMCU, &mvOBMCB, rt);
  h263e_LimitMV(&mvCur[0], &mvOBMCL, &limitRectL, dx+8, dy, 8);
  h263e_LimitMV(&mvUpper[3], &mvOBMCU, &limitRectL, dx+8, dy, 8);
  h263e_LimitMV(&mvRight[0], &mvOBMCR, &limitRectL, dx+8, dy, 8);
  h263e_LimitMV(&mvCur[3], &mvOBMCB, &limitRectL, dx+8, dy, 8);
  ippiOBMC8x8HP_MPEG4_8u_C1R(pYr+8, stepYr, pYc+8, stepYc, &mvCur[1], &mvOBMCL, &mvOBMCR, &mvOBMCU, &mvOBMCB, rt);
  h263e_LimitMV(&mvLeft[3], &mvOBMCL, &limitRectL, dx, dy+8, 8);
  h263e_LimitMV(&mvCur[0], &mvOBMCU, &limitRectL, dx, dy+8, 8);
  h263e_LimitMV(&mvCur[3], &mvOBMCR, &limitRectL, dx, dy+8, 8);
  ippiOBMC8x8HP_MPEG4_8u_C1R(pYr+stepYr*8, stepYr, pYc+stepYc*8, stepYc, &mvCur[2], &mvOBMCL, &mvOBMCR, &mvOBMCU, &mvCur[2], rt);
  h263e_LimitMV(&mvCur[2], &mvOBMCL, &limitRectL, dx+8, dy+8, 8);
  h263e_LimitMV(&mvCur[1], &mvOBMCU, &limitRectL, dx+8, dy+8, 8);
  h263e_LimitMV(&mvRight[2], &mvOBMCR, &limitRectL, dx+8, dy+8, 8);
  ippiOBMC8x8HP_MPEG4_8u_C1R(pYr+8+stepYr*8, stepYr, pYc+8+stepYc*8, stepYc, &mvCur[3], &mvOBMCL, &mvOBMCR, &mvOBMCU, &mvCur[3], rt);
}

⌨️ 快捷键说明

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