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

📄 h263_enc_frame.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
      mIndxBPic = 2;
    mNumBPic++;
    if (mNumBPic == mBPicdist) {
      // next frame is not B
      mNumBPic = 0;
      h263e_Swap(mFrameF, mFrameB);
      mFrameC = mFrameB;
    } else {
      // next frame is B
      mFrameC = &mFrame[mIndxBPic];
    }
  } else {
      // next frame is B
    mFrameC = &mFrame[mIndxBPic];
  }

  mPictime += mVideoSequence.fixed_pic_time_increment;
  mFrameCount ++;
  if (mFrameCount > mBPicdist + 1)
    return H263_STS_NOERR;
  else
    return isBPic ? H263_STS_BUFFERED : H263_STS_NOERR;
}

void ippVideoEncoderH263::PredictMV(h263e_MacroBlock *MBcurr, Ipp32s frGOB, Ipp32s i, Ipp32s j, Ipp32s adv, IppMotionVector *mvPred)
{
  IppMotionVector *mvLeft, *mvTop, *mvRight;
  Ipp32s i1, i2;

  if (adv) {
    i1 = 1;
    i2 = 2;
  } else {
    i1 = i2 = 0;
  }

  mvLeft  = MBcurr[-1].mv;
  mvTop   = MBcurr[-mNumMacroBlockPerRow].mv;
  mvRight = MBcurr[-mNumMacroBlockPerRow+1].mv;

  if (i == frGOB && j == 0) {
    mvPred[0].dx = mvPred[0].dy = 0;
  } else if (j == 0) {
    mvPred[0].dx = h263e_Median(0, mvTop[i2].dx, mvRight[i2].dx);
    mvPred[0].dy = h263e_Median(0, mvTop[i2].dy, mvRight[i2].dy);
  } else if (i == frGOB) {
    mvPred[0] = mvLeft[i1];
  } else if (j == mNumMacroBlockPerRow - 1) {
    mvPred[0].dx = h263e_Median(0, mvLeft[i1].dx, mvTop[i2].dx);
    mvPred[0].dy = h263e_Median(0, mvLeft[i1].dy, mvTop[i2].dy);
  } else {
    mvPred[0].dx = h263e_Median(mvLeft[i1].dx, mvTop[i2].dx, mvRight[i2].dx);
    mvPred[0].dy = h263e_Median(mvLeft[i1].dy, mvTop[i2].dy, mvRight[i2].dy);
  }
}

void ippVideoEncoderH263::me4MV_Neighbours(h263e_MacroBlock *MBcurr, Ipp32s frGOB, Ipp32s i, Ipp32s j, IppMotionVector *mvPred)
{
  IppMotionVector *mvLeft, *mvTop, *mvRight;
  mvLeft  = MBcurr[-1].mv;
  mvTop   = MBcurr[-mNumMacroBlockPerRow].mv;
  mvRight = MBcurr[-mNumMacroBlockPerRow+1].mv;

  if (i == frGOB) {
    mvPred[1].dx = mvPred[1].dy = 32767;  // top
    mvPred[2].dx = mvPred[2].dy = -32767; // top right
  } else if (j == mNumMacroBlockPerRow - 1) {
    mvPred[1] = mvTop[3];                // top
    mvPred[2].dx = mvPred[2].dy = 0;     // top right
  } else {
    mvPred[1] = mvTop[3];                // top
    mvPred[2] = mvRight[2];     // top right
  }
  if (j == 0)
    mvPred[3].dx = mvPred[3].dy = 0; // left
  else
    mvPred[3] = mvLeft[3];
}

void ippVideoEncoderH263::Predict3MV(h263e_MacroBlock *MBcurr, Ipp32s frGOB, Ipp32s i, Ipp32s j,
                                     IppMotionVector *mvPred, IppMotionVector *mvCurr)
{
  IppMotionVector *mvLeft, *mvTop, *mvRight;

  mvLeft  = MBcurr[-1].mv;
  mvTop   = MBcurr[-mNumMacroBlockPerRow].mv;
  mvRight = MBcurr[-mNumMacroBlockPerRow+1].mv;
  // block 1
  if (i == frGOB) {
    mvPred[1] = mvCurr[0];
  } else if (j == mNumMacroBlockPerRow - 1) {
    mvPred[1].dx = h263e_Median(mvCurr[0].dx, mvTop[3].dx, 0);
    mvPred[1].dy = h263e_Median(mvCurr[0].dy, mvTop[3].dy, 0);
  } else {
    mvPred[1].dx = h263e_Median(mvCurr[0].dx, mvTop[3].dx, mvRight[2].dx);
    mvPred[1].dy = h263e_Median(mvCurr[0].dy, mvTop[3].dy, mvRight[2].dy);
  }
  // block 2
  if (j == 0) {
    mvPred[2].dx = h263e_Median(0, mvCurr[0].dx, mvCurr[1].dx);
    mvPred[2].dy = h263e_Median(0, mvCurr[0].dy, mvCurr[1].dy);
  } else {
    mvPred[2].dx = h263e_Median(mvLeft[3].dx, mvCurr[0].dx, mvCurr[1].dx);
    mvPred[2].dy = h263e_Median(mvLeft[3].dy, mvCurr[0].dy, mvCurr[1].dy);
  }
  // block 3
  mvPred[3].dx = h263e_Median(mvCurr[2].dx, mvCurr[0].dx, mvCurr[1].dx);
  mvPred[3].dy = h263e_Median(mvCurr[2].dy, mvCurr[0].dy, mvCurr[1].dy);
}

void ippVideoEncoderH263::EncodeMV(IppMotionVector *mv, Ipp32s mbType)
{
  Ipp32s i, nMV = (mbType == IPPVC_MBTYPE_INTER4V) ? 4 : 1;

  for (i = 0; i < nMV; i++) {
    if (mVideoPicture.UMV <= 1) {
      cBS.PutBits(mVLC_MVD_TB12[mv[i].dx+32].code, mVLC_MVD_TB12[mv[i].dx+32].len);
      cBS.PutBits(mVLC_MVD_TB12[mv[i].dy+32].code, mVLC_MVD_TB12[mv[i].dy+32].len);
    } else {
      Ipp32s mvabs[2], sign[2], j, val, s;
      Ipp32s m, nbits;
      Ipp32u code;

      sign[0] = (mv[i].dx >= 0 ? 0 : 1);
      mvabs[0] = (mv[i].dx >= 0 ? mv[i].dx : -mv[i].dx);
      sign[1] = (mv[i].dy >= 0 ? 0 : 1);
      mvabs[1] = (mv[i].dy >= 0 ? mv[i].dy : -mv[i].dy);

      for (j = 0; j < 2; j++) {
        val = mvabs[j];
        s = sign[j];

        if (val == 0)
          cBS.PutBits(1, 1);
        else if (val == 1)
          cBS.PutBits(s << 1, 3);
        else {
          if (val < 32) {
            m = 16;
            nbits = 11;
          } else {
            m = 2048;
            nbits = 25;
          }
          while (1) {
            if (val & m)
              break;
            nbits -= 2;
            m >>= 1;
          }
          val &= m - 1;
          m >>= 1;
          code = 0;
          while (m) {
            code |= ((val & m) << 1) | m;
            code <<= 1;
            m >>= 1;
          }
          code <<= 1;
          code |= s << 1;
          cBS.PutBits(code, nbits);
        }
      }
      if (mv[i].dx == 1 && mv[i].dy == 1)
        cBS.PutBits(1, 1);
    }
  }
}

inline void ippVideoEncoderH263::EncodeMCBPC_I(Ipp32s mbtype, Ipp32s mcbpc)
{
  if (mbtype == IPPVC_MBTYPE_INTRA) {
    if (mcbpc == 0)
      cBS.PutBits(1, 1);
    else
      cBS.PutBits(mcbpc, 3);
  } else {
    if (mcbpc == 0)
      cBS.PutBits(1, 4);
    else
      cBS.PutBits(mcbpc, 7);
  }
}

inline void ippVideoEncoderH263::EncodeAdvIntraPredMode(Ipp32s scan)
{
  if (scan == IPPVC_SCAN_ZIGZAG)
    cBS.PutBits(0, 1);
  else if (scan == IPPVC_SCAN_VERTICAL)
    cBS.PutBits(3, 2);
  else
    cBS.PutBits(2, 2);
}

inline void ippVideoEncoderH263::EncodeCBPY_I(Ipp32s pat)
{
    cBS.PutBits(mVLC_CBPY_TB8[pat].code, mVLC_CBPY_TB8[pat].len);
}

inline void ippVideoEncoderH263::EncodeMCBPC_P(Ipp32s mbtype, Ipp32s pat)
{
    cBS.PutBits(mVLC_MCBPC_TB7[mbtype*4+pat].code, mVLC_MCBPC_TB7[mbtype*4+pat].len);
}

inline void ippVideoEncoderH263::EncodeCBPY_P(Ipp32s mbtype, Ipp32s pat)
{
    if (mbtype <= IPPVC_MBTYPE_INTER4V)
        pat = 15 - pat;
    cBS.PutBits(mVLC_CBPY_TB8[pat].code, mVLC_CBPY_TB8[pat].len);
}

void ippVideoEncoderH263::ChooseAdvIntraPred(h263e_MacroBlock *MBcurr, Ipp16s *coeffs, Ipp32s *predDir)
{
  h263e_Block *bCurr;
  Ipp16s      *predAcA, *predAcC;
  Ipp32s      sadDC, sadH, sadV, absCoefV, absCoefH, s, dc;
  Ipp16s      *coef;
  Ipp32s      i, v;

  sadDC = sadH = sadV = 0;

  for (i = 0; i < 4; i++) {
    bCurr = &MBcurr->block[i];
    coef = coeffs + i*64;

    absCoefH = absCoefV = 0;

    bCurr->dctOr_acA[0] = bCurr->dctOr_acC[0] = coef[0];
    for (v = 1; v < 8; v++) {
      bCurr->dctOr_acA[v] = coef[v*8];
      absCoefV += h263e_Abs(coef[v*8]);
      bCurr->dctOr_acC[v] = coef[v];
      absCoefH += h263e_Abs(coef[v]);
    }

    predAcA = bCurr->predA ? (bCurr->predA->validPredIntra ? bCurr->predA->dctOr_acA : NULL) : NULL;
    predAcC = bCurr->predC ? (bCurr->predC->validPredIntra ? bCurr->predC->dctOr_acC : NULL) : NULL;

    if (predAcA) {
      if (predAcC)
        dc = h263e_Abs(coef[0] - ((predAcA[0] + predAcC[0] + 1) >> 1));
      else
        dc = h263e_Abs(coef[0] - predAcA[0]);
    } else if (predAcC)
      dc = h263e_Abs(coef[0] - predAcC[0]);
    else
      dc = h263e_Abs(coef[0] - 1024);

    sadDC += dc + ((absCoefV + absCoefH) << 5);

    // block to the left
    s = absCoefH;
    if (predAcA) {
      dc = h263e_Abs(coef[0] - predAcA[0]);
      for (v = 1; v < 8; v++)
        s += h263e_Abs(coef[v*8] - predAcA[v]);
    } else {
      dc = h263e_Abs(coef[0] - 1024);
      s += absCoefV;
    }
    sadV += dc + (s << 5);

    // block above
    s = absCoefV;
    if (predAcC) {
      dc = h263e_Abs(coef[0] - predAcC[0]);
      for (v = 1; v < 8; v++)
        s += h263e_Abs(coef[v] - predAcC[v]);
    } else {
      dc = h263e_Abs(coef[0] - 1024);
      s += absCoefH;
    }
    sadH += dc + (s << 5);
  }

  *predDir = IPPVC_SCAN_ZIGZAG;

  if (sadV < sadDC) {
    *predDir = IPPVC_SCAN_VERTICAL;
    sadDC = sadV;
  }

  if (sadH < sadDC)
    *predDir = IPPVC_SCAN_HORIZONTAL;
}

Ipp32s ippVideoEncoderH263::PredictReconstructAdvIntra(Ipp8u *pF[6], h263e_MacroBlock *MBcurr, Ipp16s *coeffs,
                                                       Ipp32s *nzCount, Ipp32s quant, Ipp32s scan)
{
  __ALIGN16(Ipp16s, rcoef, 64);
  __ALIGN16(Ipp8u, pDec, 64*6);
  h263e_Block *bCurr;
  Ipp16s    *predAcA, *predAcC;
  Ipp16s    *coef;
  Ipp32s    i, v;
  Ipp16s    pred;
  Ipp32s    step;
  Ipp32s    pattern = 0;

  if (mCalcPSNR) {
    ippiCopy16x16_8u_C1R(pF[0], mStepLuma, pDec, 16);
    ippiCopy8x8_8u_C1R(pF[4], mStepChroma, pDec+256, 8);
    ippiCopy8x8_8u_C1R(pF[5], mStepChroma, pDec+320, 8);
  }

  for (i = 0; i < 6; i++) {
    bCurr = &MBcurr->block[i];
    coef = coeffs + i*64;
    step = (i < 4 ? mStepLuma : mStepChroma);

    predAcA = bCurr->predA ? (bCurr->predA->validPredIntra ? bCurr->predA->dct_acA : NULL) : NULL;
    predAcC = bCurr->predC ? (bCurr->predC->validPredIntra ? bCurr->predC->dct_acC : NULL) : NULL;

    if (scan == IPPVC_SCAN_ZIGZAG) {
      if (predAcA)
        if (predAcC)
          pred = (predAcA[0] + predAcC[0] + 1) >> 1;
        else
          pred = predAcA[0];
      else
        pred = predAcC ? predAcC[0] : 1024;
      coef[0] = coef[0] - pred;
    } else if (scan == IPPVC_SCAN_VERTICAL) {
      if (predAcA) {
        for (v = 0; v < 8; v++)
          coef[v*8] = coef[v*8] - predAcA[v];
      } else
        coef[0] = coef[0] - 1024;
    } else { // IPPVC_SCAN_HORIZONTAL
      if (predAcC) {
        for (v = 0; v < 8; v++)
          coef[v] = coef[v] - predAcC[v];
      } else
        coef[0] = coef[0] - 1024;
    }

    // No need to clip to [-2048,2047] as Intra AC DCT coeffs are in the range [-1020, 1020], DC -  [0, 2040]
    ippiQuantIntra_H263_16s_C1I(coef, quant, &nzCount[i], 1, mVideoPicture.modQuant);

    if (nzCount[i])
      pattern |= 32 >> i;

    ippsCopy_16s(coef, rcoef, 64); // have only inplace Quant/InvQuant

    ReconBlockIntra_AdvI_H263(pF[i], step, rcoef, bCurr, quant, nzCount[i], scan);
  }

  if (mCalcPSNR) {
    mPSNR_Y += h263e_CalcMSE_16x16(pF[0], mStepLuma, pDec, 16);
    mPSNR_U += h263e_CalcMSE_8x8(pF[4], mStepChroma, pDec+256, 8);
    mPSNR_V += h263e_CalcMSE_8x8(pF[5], mStepChroma, pDec+320, 8);
  }

  return pattern;
}

void ippVideoEncoderH263::DCT8x8MacroBlock_H263(Ipp8u *pY, Ipp8u *pU, Ipp8u *pV, Ipp16s *coeffMB)
{
  ippiDCT8x8Fwd_8u16s_C1R(pY, mStepLuma, coeffMB+0*64);
  ippiDCT8x8Fwd_8u16s_C1R(pY+8, mStepLuma, coeffMB+1*64);
  ippiDCT8x8Fwd_8u16s_C1R(pY+8*mStepLuma, mStepLuma, coeffMB+2*64);
  ippiDCT8x8Fwd_8u16s_C1R(pY+8*mStepLuma+8, mStepLuma, coeffMB+3*64);
  ippiDCT8x8Fwd_8u16s_C1R(pU, mStepChroma, coeffMB+4*64);
  ippiDCT8x8Fwd_8u16s_C1R(pV, mStepChroma, coeffMB+5*64);
}

// called only if (!mVideoPicture.advIntra)
Ipp32s ippVideoEncoderH263::QuantMacroBlockIntra_H263(Ipp16s *coeffMB, Ipp32s *nzCount, Ipp32s quant)
{
  Ipp32s pattern;
  ippiQuantIntra_H263_16s_C1I(coeffMB+0*64, quant, &nzCount[0], 0, mVideoPicture.modQuant);
  ippiQuantIntra_H263_16s_C1I(coeffMB+1*64, quant, &nzCount[1], 0, mVideoPicture.modQuant);
  ippiQuantIntra_H263_16s_C1I(coeffMB+2*64, quant, &nzCount[2], 0, mVideoPicture.modQuant);
  ippiQuantIntra_H263_16s_C1I(coeffMB+3*64, quant, &nzCount[3], 0, mVideoPicture.modQuant);
  ippiQuantIntra_H263_16s_C1I(coeffMB+4*64, quant, &nzCount[4], 0, mVideoPicture.modQuant);
  ippiQuantIntra_H263_16s_C1I(coeffMB+5*64, quant, &nzCount[5], 0, mVideoPicture.modQuant);
  h263e_SetPatternIntra(pattern, nzCount, 1);
  return pattern;
}

⌨️ 快捷键说明

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