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

📄 h263_enc_frame.cpp

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

Ipp32s ippVideoEncoderH263::TransMacroBlockInter_H263(Ipp8u *pYc, Ipp8u *pUc, Ipp8u *pVc, Ipp16s *coeffMB,
                                                      Ipp32s *nzCount, Ipp32s quant, Ipp8u *mcPred, Ipp32s lumaErr)
{
    Ipp32s pattern, sU, sV, sL0, sL1, sL2, sL3, lim;

    lim = quant * 16;
    if (lumaErr < quant * 20) {
        nzCount[0] = nzCount[1] = nzCount[2] = nzCount[3] = 0;
        coeffMB[0*64] = coeffMB[1*64] = coeffMB[2*64] = coeffMB[3*64] = 0;
    } else {
        ippiSubSAD8x8_8u16s_C1R(pYc, mStepLuma, mcPred, 16, coeffMB+0*64, 16, &sL0);
        ippiSubSAD8x8_8u16s_C1R(pYc+8, mStepLuma, mcPred+8, 16, coeffMB+1*64, 16, &sL1);
        ippiSubSAD8x8_8u16s_C1R(pYc+8*mStepLuma, mStepLuma, mcPred+128, 16, coeffMB+2*64, 16, &sL2);
        ippiSubSAD8x8_8u16s_C1R(pYc+8*mStepLuma+8, mStepLuma, mcPred+136, 16, coeffMB+3*64, 16, &sL3);
        if (sL0 < lim) {
            nzCount[0] = 0;
            coeffMB[0*64] = 0;
        } else {
            ippiDCT8x8Fwd_16s_C1I(coeffMB+0*64);
            ippiQuantInter_H263_16s_C1I(coeffMB+0*64, quant, &nzCount[0], mVideoPicture.modQuant);
        }
        if (sL1 < lim) {
            nzCount[1] = 0;
            coeffMB[1*64] = 0;
        } else {
            ippiDCT8x8Fwd_16s_C1I(coeffMB+1*64);
            ippiQuantInter_H263_16s_C1I(coeffMB+1*64, quant, &nzCount[1], mVideoPicture.modQuant);
        }
        if (sL2 < lim) {
            nzCount[2] = 0;
            coeffMB[2*64] = 0;
        } else {
            ippiDCT8x8Fwd_16s_C1I(coeffMB+2*64);
            ippiQuantInter_H263_16s_C1I(coeffMB+2*64, quant, &nzCount[2], mVideoPicture.modQuant);
        }
        if (sL3 < lim) {
            nzCount[3] = 0;
            coeffMB[3*64] = 0;
        } else {
            ippiDCT8x8Fwd_16s_C1I(coeffMB+3*64);
            ippiQuantInter_H263_16s_C1I(coeffMB+3*64, quant, &nzCount[3], mVideoPicture.modQuant);
        }
    }
    ippiSubSAD8x8_8u16s_C1R(pUc, mStepChroma, mcPred+64*4, 8, coeffMB+4*64, 16, &sU);
    ippiSubSAD8x8_8u16s_C1R(pVc, mStepChroma, mcPred+64*5, 8, coeffMB+5*64, 16, &sV);
    if (sU < lim) {
        nzCount[4] = 0;
        coeffMB[4*64] = 0;
    } else {
        ippiDCT8x8Fwd_16s_C1I(coeffMB+4*64);
        ippiQuantInter_H263_16s_C1I(coeffMB+4*64, quant, &nzCount[4], mVideoPicture.modQuant);
    }
    if (sV < lim) {
        nzCount[5] = 0;
        coeffMB[5*64] = 0;
    } else {
        ippiDCT8x8Fwd_16s_C1I(coeffMB+5*64);
        ippiQuantInter_H263_16s_C1I(coeffMB+5*64, quant, &nzCount[5], mVideoPicture.modQuant);
    }
    h263e_SetPatternInter(pattern, nzCount);
    return pattern;
}

inline void ippVideoEncoderH263::EncodeMacroBlockIntra_H263(Ipp16s *coeffMB, Ipp32s pattern, Ipp32s *nzCount, Ipp32s scan)
{
  Ipp32s i, pm = 32;

  if (mVideoPicture.advIntra) {
    for (i = 0; i < 6; i ++) {
      if (pattern & pm)
        ippiEncodeCoeffsIntra_H263_16s1u(coeffMB+i*64, &cBS.mPtr, &cBS.mBitOff, nzCount[i], 1, mVideoPicture.modQuant, scan);
      pm >>= 1;
    }
  } else {
    for (i = 0; i < 6; i ++) {
      ippiEncodeDCIntra_H263_16s1u(coeffMB[i*64], &cBS.mPtr, &cBS.mBitOff);
      if (pattern & pm)
        ippiEncodeCoeffsIntra_H263_16s1u(coeffMB+i*64, &cBS.mPtr, &cBS.mBitOff, nzCount[i] - 1, 0, mVideoPicture.modQuant, IPPVC_SCAN_ZIGZAG);
      pm >>= 1;
    }
  }
}

inline void ippVideoEncoderH263::EncodeMacroBlockInter_H263(Ipp16s *coeffMB, Ipp32s pattern, Ipp32s *nzCount)
{
  Ipp32s  i, pm = 32;

  for (i = 0; i < 6; i ++) {
    if (pattern & pm)
      ippiEncodeCoeffsInter_H263_16s1u(coeffMB+i*64, &cBS.mPtr, &cBS.mBitOff, nzCount[i], mVideoPicture.modQuant, IPPVC_SCAN_ZIGZAG);
    pm >>= 1;
  }
}

inline void ippVideoEncoderH263::ReconMacroBlockNotCoded(Ipp8u *pYc, Ipp8u *pUc, Ipp8u *pVc, Ipp8u *mcPred)
{
  if (mCalcPSNR) {
    mPSNR_Y += h263e_CalcMSE_16x16(mcPred, 16, pYc, mStepLuma);
    mPSNR_U += h263e_CalcMSE_8x8(mcPred+64*4, 8, pUc, mStepChroma);
    mPSNR_V += h263e_CalcMSE_8x8(mcPred+64*5, 8, pVc, mStepChroma);
  }
  ippiCopy16x16_8u_C1R(mcPred, 16, pYc, mStepLuma);
  ippiCopy8x8_8u_C1R(mcPred+64*4, 8, pUc, mStepChroma);
  ippiCopy8x8_8u_C1R(mcPred+64*5, 8, pVc, mStepChroma);
}

// called only if (!mVideoPicture.advIntra)
void ippVideoEncoderH263::ReconMacroBlockIntra_H263(Ipp8u *pY, Ipp8u *pU, Ipp8u *pV, Ipp16s *coeffMB, Ipp32s quant, Ipp32s pattern)
{
  __ALIGN16(Ipp8u, pDec, 64*6);

  if (mCalcPSNR) {
    ippiCopy16x16_8u_C1R(pY, mStepLuma, pDec, 16);
    ippiCopy8x8_8u_C1R(pU, mStepChroma, pDec+256, 8);
    ippiCopy8x8_8u_C1R(pV, mStepChroma, pDec+320, 8);
  }
  if (pattern & 32) {
    ippiQuantInvIntra_H263_16s_C1I(coeffMB+0*64, 63, quant, 0, mVideoPicture.modQuant);
    ippiDCT8x8Inv_16s8u_C1R(coeffMB+0*64, pY, mStepLuma);
  } else {
    h263e_Set8x8_8u(pY, mStepLuma, (Ipp8u)coeffMB[0*64]);
  }
  if (pattern & 16) {
    ippiQuantInvIntra_H263_16s_C1I(coeffMB+1*64, 63, quant, 0, mVideoPicture.modQuant);
    ippiDCT8x8Inv_16s8u_C1R(coeffMB+1*64, pY+8, mStepLuma);
  } else {
    h263e_Set8x8_8u(pY+8, mStepLuma, (Ipp8u)coeffMB[1*64]);
  }
  if (pattern & 8) {
    ippiQuantInvIntra_H263_16s_C1I(coeffMB+2*64, 63, quant, 0, mVideoPicture.modQuant);
    ippiDCT8x8Inv_16s8u_C1R(coeffMB+2*64, pY+8*mStepLuma, mStepLuma);
  } else {
    h263e_Set8x8_8u(pY+8*mStepLuma, mStepLuma, (Ipp8u)coeffMB[2*64]);
  }
  if (pattern & 4) {
    ippiQuantInvIntra_H263_16s_C1I(coeffMB+3*64, 63, quant, 0, mVideoPicture.modQuant);
    ippiDCT8x8Inv_16s8u_C1R(coeffMB+3*64, pY+8*mStepLuma+8, mStepLuma);
  } else {
    h263e_Set8x8_8u(pY+8*mStepLuma+8, mStepLuma, (Ipp8u)coeffMB[3*64]);
  }
  if (pattern & 2) {
    ippiQuantInvIntra_H263_16s_C1I(coeffMB+4*64, 63, quant, 0, mVideoPicture.modQuant);
    ippiDCT8x8Inv_16s8u_C1R(coeffMB+4*64, pU, mStepChroma);
  } else {
    h263e_Set8x8_8u(pU, mStepChroma, (Ipp8u)coeffMB[4*64]);
  }
  if (pattern & 1) {
    ippiQuantInvIntra_H263_16s_C1I(coeffMB+5*64, 63, quant, 0, mVideoPicture.modQuant);
    ippiDCT8x8Inv_16s8u_C1R(coeffMB+5*64, pV, mStepChroma);
  } else {
    h263e_Set8x8_8u(pV, mStepChroma, (Ipp8u)coeffMB[5*64]);
  }
  if (mCalcPSNR) {
      mPSNR_Y += h263e_CalcMSE_16x16(pY, mStepLuma, pDec, 16);
      mPSNR_U += h263e_CalcMSE_8x8(pU, mStepChroma, pDec+256, 8);
      mPSNR_V += h263e_CalcMSE_8x8(pV, mStepChroma, pDec+320, 8);
  }
}

void ippVideoEncoderH263::ReconBlockIntra_AdvI_H263(Ipp8u *p, Ipp32s step, Ipp16s *coef, h263e_Block *bCurr,
                                                    Ipp32s quant, Ipp32s pattern, Ipp32s scan)
{
  Ipp32s v;
  Ipp16s *predAcA, *predAcC, pred;
  Ipp32s lnz;

  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 (pattern) {
    ippiQuantInvIntra_H263_16s_C1I(coef, 63, quant, 1, mVideoPicture.modQuant);
    lnz = 63;
  } else {
    if (scan != IPPVC_SCAN_ZIGZAG) {
      h263e_Zero64_16s(coef);
    } else
      coef[0] = 0;
    lnz = 0;
  }

  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;
    pred += coef[0];
    pred |= 1;
    h263e_Clip(pred, 0, 2047);
    coef[0] = pred;
  } else if (scan == IPPVC_SCAN_VERTICAL) {
    if (predAcA) {
      pred = coef[0] + predAcA[0];
      pred |= 1;
      h263e_Clip(pred, 0, 2047);
      coef[0] = pred;
      for (v = 1; v < 8; v++) {
        pred = coef[v*8] + predAcA[v];
        h263e_Clip(pred, -2048, 2047);
        coef[v*8] = pred;
        lnz |= pred;
      }
    } else {
      pred = coef[0] + 1024;
      pred |= 1;
      h263e_Clip(pred, 0, 2047);
      coef[0] = pred;
    }
  } else {
    if (predAcC) {
      pred = coef[0] + predAcC[0];
      pred |= 1;
      h263e_Clip(pred, 0, 2047);
      coef[0] = pred;
      for (v = 1; v < 8; v++) {
        pred = coef[v] + predAcC[v];
        h263e_Clip(pred, -2048, 2047);
        coef[v] = pred;
        lnz |= pred;
      }
    } else {
      pred = coef[0] + 1024;
      pred |= 1;
      h263e_Clip(pred, 0, 2047);
      coef[0] = pred;
    }
  }

  if (lnz) {
    ippiDCT8x8Inv_16s8u_C1R(coef, p, step);
    /* copy predicted coeffs for future Prediction */
    for (v = 0; v < 8; v ++) {
      bCurr->dct_acC[v] = coef[v];
      bCurr->dct_acA[v] = coef[v*8];
    }
  } else {
    h263e_Zero8_16s(bCurr->dct_acA);
    h263e_Zero8_16s(bCurr->dct_acC);
    bCurr->dct_acA[0] = bCurr->dct_acC[0] = coef[0];
    pred = (coef[0] + 4) >> 3;
    h263e_ClipR(pred, 255);
    h263e_Set8x8_8u(p, step, (Ipp8u)pred);
  }
}

void ippVideoEncoderH263::ReconMacroBlockInter_H263(Ipp8u *pYc, Ipp8u *pUc, Ipp8u *pVc, Ipp8u *mcPred,
                                                    Ipp16s *coeffMB, Ipp32s quant, Ipp32s pattern)
{
    if (pattern & 32) {
        ippiQuantInvInter_H263_16s_C1I(coeffMB+0*64, 63, quant, mVideoPicture.modQuant);
        ippiDCT8x8Inv_16s_C1I(coeffMB+0*64);
        h263e_Add8x8_16s8u(mcPred, coeffMB+0*64, 16);
    }
    if (pattern & 16) {
        ippiQuantInvInter_H263_16s_C1I(coeffMB+1*64, 63, quant, mVideoPicture.modQuant);
        ippiDCT8x8Inv_16s_C1I(coeffMB+1*64);
        h263e_Add8x8_16s8u(mcPred+8, coeffMB+1*64, 16);
    }
    if (pattern & 8) {
        ippiQuantInvInter_H263_16s_C1I(coeffMB+2*64, 63, quant, mVideoPicture.modQuant);
        ippiDCT8x8Inv_16s_C1I(coeffMB+2*64);
        h263e_Add8x8_16s8u(mcPred+16*8, coeffMB+2*64, 16);
    }
    if (pattern & 4) {
        ippiQuantInvInter_H263_16s_C1I(coeffMB+3*64, 63, quant, mVideoPicture.modQuant);
        ippiDCT8x8Inv_16s_C1I(coeffMB+3*64);
        h263e_Add8x8_16s8u(mcPred+16*8+8, coeffMB+3*64, 16);
    }
    if (pattern & 2) {
        ippiQuantInvInter_H263_16s_C1I(coeffMB+4*64, 63, quant, mVideoPicture.modQuant);
        ippiDCT8x8Inv_16s_C1I(coeffMB+4*64);
        h263e_Add8x8_16s8u(mcPred+64*4, coeffMB+4*64, 8);
    }
    if (pattern & 1) {
        ippiQuantInvInter_H263_16s_C1I(coeffMB+5*64, 63, quant, mVideoPicture.modQuant);
        ippiDCT8x8Inv_16s_C1I(coeffMB+5*64);
        h263e_Add8x8_16s8u(mcPred+64*5, coeffMB+5*64, 8);
    }
    if (mCalcPSNR) {
        mPSNR_Y += h263e_CalcMSE_16x16(pYc, mStepLuma, mcPred, 16);
        mPSNR_U += h263e_CalcMSE_8x8(pUc, mStepChroma, mcPred+64*4, 8);
        mPSNR_V += h263e_CalcMSE_8x8(pVc, mStepChroma, mcPred+64*5, 8);
    }
    ippiCopy16x16_8u_C1R(mcPred, 16, pYc, mStepLuma);
    ippiCopy8x8_8u_C1R(mcPred+64*4, 8, pUc, mStepChroma);
    ippiCopy8x8_8u_C1R(mcPred+64*5, 8, pVc, mStepChroma);
}

void ippVideoEncoderH263::EncodeIPic()
{
  __ALIGN16(Ipp16s, coeffMB, 64*6);
  Ipp8u  *pY, *pU, *pV, *pF[6];
  Ipp32s i, j, quant, pattern;
  Ipp32s nzCount[6];
  h263e_MacroBlock *MBcurr = mMBinfo;
  Ipp32s scan;
  Ipp32s nmbf = 0;
  Ipp32s gn, gRow, frGOB = 0;

  mVideoPicture.gob_number = 1;
  quant = mVideoPicture.pic_quant;

  for (gn = 0; gn < mVideoPicture.num_gobs_in_pic; gn++) {
    mRTPdata.GOBstartPos[gn] = 8 * (cBS.mPtr - cBS.mBuffer) + cBS.mBitOff;

    if (mGOBheaders && gn) {
      EncodeGOB_Header(gn);
      frGOB = gn*mVideoPicture.num_MBrows_in_gob;
    }

    for (gRow = 0; gRow < mVideoPicture.num_MBrows_in_gob; gRow++) {
      Ipp32s boundOnTop;
      i = gn*mVideoPicture.num_MBrows_in_gob + gRow;

      boundOnTop = (i == frGOB && i);

      pY = mFrameC->pY + i * 16 * mStepLuma;
      pU = mFrameC->pU + i * 8 * mStepChroma;
      pV = mFrameC->pV + i * 8 * mStepChroma;
      for (j = 0; j < mNumMacroBlockPerRow; j++) {
        MBcurr->mv[0].dx = MBcurr->mv[0].dy = 0;
        MBcurr->block[0].validPredIntra = MBcurr->block[1].validPredIntra = MBcurr->block[2].validPredIntra = MBcurr->block[3].validPredIntra = MBcurr->block[4].validPredIntra = MBcurr->block[5].validPredIntra = 1;

        // for RTP support
        mRTPdata.MBpos[nmbf] = 8 * (cBS.mPtr - cBS.mBuffer) + cBS.mBitOff;
        mRTPdata.MBquant[nmbf] = (Ipp8u)quant;

        DCT8x8MacroBlock_H263(pY, pU, pV, coeffMB);

        if (mVideoPicture.advIntra) {
          pF[0] = pY; pF[1] = pY + 8; pF[2] = pY + 8*mStepLuma; pF[3] = pY + 8*mStepLuma + 8;
          pF[4] = pU; pF[5] = pV;

          if (boundOnTop) { // mark top row blocks as invalid
            MBcurr->block[0].predC->validPredIntra = 0;
            MBcurr->block[1].predC->validPredIntra = 0;
            MBcurr->block[4].predC->validPredIntra = 0;
            MBcurr->block[5].predC->validPredIntra = 0;
          }

          ChooseAdvIntraPred(MBcurr, coeffMB, &scan);
          pattern = PredictReconstructAdvIntra(pF, MBcurr, coeffMB, nzCount, quant, scan);
        } else {
          scan = IPPVC_SCAN_ZIGZAG;
          pattern = QuantMacroBlockIntra_H263(coeffMB, nzCount, quant);
        }

        EncodeMCBPC_I(IPPVC_MBTYPE_INTRA, pattern & 3);

        if (mVideoPicture.advIntra)
          EncodeAdvIntraPredMode(scan);

        EncodeCBPY_I(pattern >> 2);

        EncodeMacroBlockIntra_H263(coeffMB, pattern, nzCount, scan);

        if (!mVideoPicture.advIntra && (mIPicdist != 1 || mCalcPSNR))
          ReconMacroBlockIntra_H263(pY, pU, pV, coeffMB, quant, pattern);

        pY += 16; pU += 8; pV += 8;
        MBcurr ++;
        nmbf ++;
      }
    }
  }
  EncodeZeroBitsAlign();
}

inline Ipp32s h263e_MC_type(IppMotionVector *mv)
{
    return (((mv->dy & 1) << 2) + ((mv->dx & 1) << 3));
}

inline Ipp32s h263e_MC_offs(IppMotionVector *mv, Ipp32s step)
{
    return ((mv->dy >> 1) * step + (mv->dx >> 1));

⌨️ 快捷键说明

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