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

📄 h263decfuncs.c

📁 audio-video-codecs.rar语音编解码器
💻 C
📖 第 1 页 / 共 4 页
字号:
h263_Status h263_PredictDecode4MV(h263_Info *pInfo, h263_MacroBlock *MBcurr, Ipp32s frGOB, Ipp32s y, Ipp32s x)
{
  IppMotionVector *mvLeft, *mvTop, *mvRight, *mvCurr;
  h263_VideoPicture *VPic = &pInfo->VideoSequence.VideoPicture;
  Ipp32s mbInRow = VPic->MacroBlockPerRow;
  Ipp32s mvdx, mvdy;
  h263_Status status;
  Ipp32s noUMVplus = !VPic->oppmodes.UMV;
  Ipp32s noUMV = noUMVplus && !VPic->modes.UMV;

  mvCurr = MBcurr[0].mv;
  mvLeft  = MBcurr[-1].mv;
  mvTop   = MBcurr[-mbInRow].mv;
  mvRight = MBcurr[-mbInRow+1].mv;
  /* block 0 */
  if (y == frGOB && x == 0) {
    mvCurr[0].dx = mvCurr[0].dy = 0;
  } else if (x == 0) {
    mvCurr[0].dx = h263_Median(0, mvTop[2].dx, mvRight[2].dx);
    mvCurr[0].dy = h263_Median(0, mvTop[2].dy, mvRight[2].dy);
  } else if (y == frGOB) {
    mvCurr[0] = mvLeft[1];
  } else if (x == mbInRow - 1) {
    mvCurr[0].dx = h263_Median(0, mvLeft[1].dx, mvTop[2].dx);
    mvCurr[0].dy = h263_Median(0, mvLeft[1].dy, mvTop[2].dy);
  } else {
    mvCurr[0].dx = h263_Median(mvLeft[1].dx, mvTop[2].dx, mvRight[2].dx);
    mvCurr[0].dy = h263_Median(mvLeft[1].dy, mvTop[2].dy, mvRight[2].dy);
  }
  if (noUMV) {
    status = h263_DecodeMV(pInfo, &mvCurr[0], -32, 31);
  } else if (noUMVplus) {
    status = h263_DecodeMV(pInfo, &mvCurr[0], -63, 63);
  } else {
    status = h263_DecodeMVD_umvplus(pInfo, &mvdx, &mvdy);
    mvCurr[0].dx = mvCurr[0].dx + (Ipp16s)mvdx;
    mvCurr[0].dy = mvCurr[0].dy + (Ipp16s)mvdy;
  }
  if (status != H263_STATUS_OK)
    return status;

  /* block 1 */
  if (y == frGOB) {
    mvCurr[1] = mvCurr[0];
  } else if (x == mbInRow - 1) {
    mvCurr[1].dx = h263_Median(mvCurr[0].dx, mvTop[3].dx, 0);
    mvCurr[1].dy = h263_Median(mvCurr[0].dy, mvTop[3].dy, 0);
  } else {
    mvCurr[1].dx = h263_Median(mvCurr[0].dx, mvTop[3].dx, mvRight[2].dx);
    mvCurr[1].dy = h263_Median(mvCurr[0].dy, mvTop[3].dy, mvRight[2].dy);
  }
  if (noUMV) {
    status = h263_DecodeMV(pInfo, &mvCurr[1], -32, 31);
  } else if (noUMVplus) {
    status = h263_DecodeMV(pInfo, &mvCurr[1], -63, 63);
  } else {
    status = h263_DecodeMVD_umvplus(pInfo, &mvdx, &mvdy);
    mvCurr[1].dx = mvCurr[1].dx + (Ipp16s)mvdx;
    mvCurr[1].dy = mvCurr[1].dy + (Ipp16s)mvdy;
  }
  if (status != H263_STATUS_OK)
    return status;

  /* block 2 */
  if (x == 0) {
    mvCurr[2].dx = h263_Median(0, mvCurr[0].dx, mvCurr[1].dx);
    mvCurr[2].dy = h263_Median(0, mvCurr[0].dy, mvCurr[1].dy);
  } else {
    mvCurr[2].dx = h263_Median(mvLeft[3].dx, mvCurr[0].dx, mvCurr[1].dx);
    mvCurr[2].dy = h263_Median(mvLeft[3].dy, mvCurr[0].dy, mvCurr[1].dy);
  }
  if (noUMV) {
    status = h263_DecodeMV(pInfo, &mvCurr[2], -32, 31);
  } else if (noUMVplus) {
    status = h263_DecodeMV(pInfo, &mvCurr[2], -63, 63);
  } else {
    status = h263_DecodeMVD_umvplus(pInfo, &mvdx, &mvdy);
    mvCurr[2].dx = mvCurr[2].dx + (Ipp16s)mvdx;
    mvCurr[2].dy = mvCurr[2].dy + (Ipp16s)mvdy;
  }
  if (status != H263_STATUS_OK)
    return status;

  /* block 3 */
  mvCurr[3].dx = h263_Median(mvCurr[2].dx, mvCurr[0].dx, mvCurr[1].dx);
  mvCurr[3].dy = h263_Median(mvCurr[2].dy, mvCurr[0].dy, mvCurr[1].dy);
  if (noUMV) {
    status = h263_DecodeMV(pInfo, &mvCurr[3], -32, 31);
  } else if (noUMVplus) {
    status = h263_DecodeMV(pInfo, &mvCurr[3], -63, 63);
  } else {
    status = h263_DecodeMVD_umvplus(pInfo, &mvdx, &mvdy);
    mvCurr[3].dx = mvCurr[3].dx + (Ipp16s)mvdx;
    mvCurr[3].dy = mvCurr[3].dy + (Ipp16s)mvdy;
  }
  if (status != H263_STATUS_OK)
    return status;

  return H263_STATUS_OK;
}

void h263_OBMC(h263_Info *pInfo, h263_MacroBlock *pMBinfo, IppMotionVector *mvCur, Ipp32s colNum, Ipp32s rowNum, IppiRect limitRectL, Ipp8u *pYc, Ipp32s stepYc, Ipp8u *pYr, Ipp32s stepYr, Ipp32s cbpy, Ipp16s *coeffMB)
{
  IppMotionVector mvOBMCL, mvOBMCU, mvOBMCR, mvOBMCB, *mvLeft, *mvUpper, *mvRight;
  h263_VideoPicture *VPic = &pInfo->VideoSequence.VideoPicture;
  Ipp32s mbPerRow = VPic->MacroBlockPerRow, dx, dy, rt;

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

  dx = colNum * 16;
  dy = rowNum * 16;
  rt = VPic->rtype;

  h263_LimitMV(&mvLeft[1], &mvOBMCL, &limitRectL, dx, dy, 8);
  h263_LimitMV(&mvUpper[2], &mvOBMCU, &limitRectL, dx, dy, 8);
  h263_LimitMV(&mvCur[1], &mvOBMCR, &limitRectL, dx, dy, 8);
  h263_LimitMV(&mvCur[2], &mvOBMCB, &limitRectL, dx, dy, 8);
  ippiOBMC8x8HP_MPEG4_8u_C1R(pYr, stepYr, pYc, stepYc, &mvCur[0], &mvOBMCL, &mvOBMCR, &mvOBMCU, &mvOBMCB, rt);
  h263_LimitMV(&mvCur[0], &mvOBMCL, &limitRectL, dx+8, dy, 8);
  h263_LimitMV(&mvUpper[3], &mvOBMCU, &limitRectL, dx+8, dy, 8);
  h263_LimitMV(&mvRight[0], &mvOBMCR, &limitRectL, dx+8, dy, 8);
  h263_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);
  h263_LimitMV(&mvLeft[3], &mvOBMCL, &limitRectL, dx, dy+8, 8);
  h263_LimitMV(&mvCur[0], &mvOBMCU, &limitRectL, dx, dy+8, 8);
  h263_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);
  h263_LimitMV(&mvCur[2], &mvOBMCL, &limitRectL, dx+8, dy+8, 8);
  h263_LimitMV(&mvCur[1], &mvOBMCU, &limitRectL, dx+8, dy+8, 8);
  h263_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);

  h263_AddResidual(cbpy & 8, pYc, stepYc, coeffMB);
  h263_AddResidual(cbpy & 4, pYc+8, stepYc, coeffMB+64);
  h263_AddResidual(cbpy & 2, pYc+stepYc*8, stepYc, coeffMB+128);
  h263_AddResidual(cbpy & 1, pYc+stepYc*8+8, stepYc, coeffMB+192);
}

Ipp32s h263_UpdateQuant_Mod(h263_Info *pInfo)
{
  h263_VideoPicture *VPic = &pInfo->VideoSequence.VideoPicture;
  Ipp32s quant = VPic->pic_quant;
  Ipp32s dquant, quant_c;
  Ipp32u code;

  code = h263_ShowBits9(pInfo, 6);
  if (code >= 32) {
    dquant = (code >> 4) & 1;
    VPic->pic_quant = h263_dquant_Mod[dquant][quant - 1];
    h263_FlushBits(pInfo, 2);
  } else {
    VPic->pic_quant = code;
    h263_FlushBits(pInfo, 6);
  }

  quant_c = h263_quant_c[VPic->pic_quant];

  return quant_c;
}

/* intra-macroblock horizontal boundaries are processed in h263_DecodeFrame_P() */
void h263_DeblockingFilter_P(h263_Info *pInfo, h263_Frame *frame)
{
  Ipp8u *pYc, *pCbc, *pCrc;
  Ipp32s stepYc, stepCbc, stepCrc, mbPerRow, mbPerCol;
  h263_MacroBlock *pMBinfo;
  Ipp32s quant, quant_c;
  Ipp32s i, j;
  h263_VideoPicture *VPic = &pInfo->VideoSequence.VideoPicture;

  stepYc = frame->stepY;
  stepCbc = frame->stepCb;
  stepCrc = frame->stepCr;
  mbPerRow = frame->mbPerRow;
  mbPerCol = frame->mbPerCol;

  /* Horizontal */
  for (i = 1; i < mbPerCol; i++) {
    if (pInfo->VideoSequence.GOBboundary[i] > 0)
      continue; /* no filtering across GOB boundaries */
    pYc = frame->pY + (stepYc << 4)*i;
    pCbc = frame->pCb + (stepCbc << 3)*i;
    pCrc = frame->pCr + (stepCrc << 3)*i;
    pMBinfo = pInfo->VideoSequence.MBinfo + mbPerRow*i;

    for (j = 0; j < mbPerRow; j++) {
      if (pMBinfo[j].type != IPPVC_MB_STUFFING) {
        quant = pMBinfo[j].quant;
        quant_c = VPic->oppmodes.modQuant ? h263_quant_c[quant] : quant;
        H263_MB_HOR_DEBLOCKING(pYc, stepYc, pCbc, stepCbc, pCrc, stepCrc, quant, quant_c);
      } else if (pMBinfo[j-mbPerRow].type != IPPVC_MB_STUFFING) {
        quant = pMBinfo[j-mbPerRow].quant;
        quant_c = VPic->oppmodes.modQuant ? h263_quant_c[quant] : quant;
        H263_MB_HOR_DEBLOCKING(pYc, stepYc, pCbc, stepCbc, pCrc, stepCrc, quant, quant_c);
      }
      pYc += 16;
      pCbc += 8;
      pCrc += 8;
    }
  }

  /* Vertical */
  for (i = 0; i < mbPerCol; i++) {
    if (pInfo->VideoSequence.GOBboundary[i] > 1)
      continue; /* the row belongs to a skipped GOB */
    pYc = frame->pY + (stepYc << 4)*i;
    pCbc = frame->pCb + (stepCbc << 3)*i;
    pCrc = frame->pCr + (stepCrc << 3)*i;
    pMBinfo = pInfo->VideoSequence.MBinfo + mbPerRow*i;

    if (pMBinfo[0].type != IPPVC_MB_STUFFING) {
      H263_MB_INTERNAL_VER_DEBLOCKING_LUM(pYc, stepYc, quant);
    }
    for (j = 1; j < mbPerRow; j++) {
      pYc += 16;
      pCbc += 8;
      pCrc += 8;
      if (pMBinfo[j].type != IPPVC_MB_STUFFING) {
        quant = pMBinfo[j].quant;
        quant_c = VPic->oppmodes.modQuant ? h263_quant_c[quant] : quant;
        H263_MB_VER_DEBLOCKING(pYc, stepYc, pCbc, stepCbc, pCrc, stepCrc, quant, quant_c);
        H263_MB_INTERNAL_VER_DEBLOCKING_LUM(pYc, stepYc, quant);
      } else if (pMBinfo[j-1].type != IPPVC_MB_STUFFING) {
        quant = pMBinfo[j-1].quant;
        quant_c = VPic->oppmodes.modQuant ? h263_quant_c[quant] : quant;
        H263_MB_VER_DEBLOCKING(pYc, stepYc, pCbc, stepCbc, pCrc, stepCrc, quant, quant_c);
      }
    }
  }
}

void h263_DeblockingFilter_I(h263_Info *pInfo, h263_Frame *frame)
{
  Ipp8u *pYc, *pCbc, *pCrc;
  Ipp32s stepYc, stepCbc, stepCrc, mbPerRow, mbPerCol;
  h263_MacroBlock *pMBinfo;
  Ipp32s quant, quant_c;
  Ipp32s i, j;
  h263_VideoPicture *VPic = &pInfo->VideoSequence.VideoPicture;
  Ipp32s modQ = VPic->oppmodes.modQuant;

  stepYc = frame->stepY;
  stepCbc = frame->stepCb;
  stepCrc = frame->stepCr;
  mbPerRow = frame->mbPerRow;
  mbPerCol = frame->mbPerCol;

  for (i = 1; i < mbPerCol; i++) {
    pYc = frame->pY + (stepYc << 4)*i;
    pCbc = frame->pCb + (stepCbc << 3)*i;
    pCrc = frame->pCr + (stepCrc << 3)*i;
    pMBinfo = pInfo->VideoSequence.MBinfo + mbPerRow*i;
    if (pInfo->VideoSequence.GOBboundary[i] > 0) {
      if (pInfo->VideoSequence.GOBboundary[i] > 1) {
        continue; /* the row belongs to a skipped GOB */
      } else { /* no horizontal filtering across GOB boundary */
        quant = pMBinfo[-mbPerRow].quant;
        H263_MB_INTERNAL_VER_DEBLOCKING_LUM(pYc-16*stepYc, stepYc, quant);
        for (j = 1; j < mbPerRow; j++) {
          pYc += 16;
          pCbc += 8;
          pCrc += 8;
          quant = pMBinfo[j-mbPerRow].quant;
          quant_c = modQ ? h263_quant_c[quant] : quant;
          H263_MB_VER_DEBLOCKING(pYc-16*stepYc, stepYc, pCbc-8*stepCbc, stepCbc, pCrc-8*stepCrc, stepCrc, quant, quant_c);
          H263_MB_INTERNAL_VER_DEBLOCKING_LUM(pYc - 16*stepYc, stepYc, quant);
        }
      }
    } else {
      quant = pMBinfo[0].quant;
      quant_c = modQ ? h263_quant_c[quant] : quant;
      H263_MB_HOR_DEBLOCKING(pYc, stepYc, pCbc, stepCbc, pCrc, stepCrc, quant, quant_c);
      H263_MB_INTERNAL_VER_DEBLOCKING_LUM(pYc - 16*stepYc, stepYc, pMBinfo[-mbPerRow].quant);

      for (j = 1; j < mbPerRow; j++) {
        pYc += 16;
        pCbc += 8;
        pCrc += 8;

        quant = pMBinfo[j].quant;
        quant_c = modQ ? h263_quant_c[quant] : quant;
        H263_MB_HOR_DEBLOCKING(pYc, stepYc, pCbc, stepCbc, pCrc, stepCrc, quant, quant_c);

        quant = pMBinfo[j-mbPerRow].quant;
        quant_c = modQ ? h263_quant_c[quant] : quant;

        H263_MB_VER_DEBLOCKING(pYc-16*stepYc, stepYc, pCbc-8*stepCbc, stepCbc, pCrc-8*stepCrc, stepCrc, quant, quant_c);
        H263_MB_INTERNAL_VER_DEBLOCKING_LUM(pYc - 16*stepYc, stepYc, quant);
      }
    }
  }

  pYc = frame->pY + (stepYc << 4)*(mbPerCol - 1);
  pCbc = frame->pCb + (stepCbc << 3)*(mbPerCol - 1);
  pCrc = frame->pCr + (stepCrc << 3)*(mbPerCol - 1);
  pMBinfo = pInfo->VideoSequence.MBinfo + mbPerRow*(mbPerCol - 1);

  quant = pMBinfo[0].quant;
  quant_c = modQ ? h263_quant_c[quant] : quant;
  H263_MB_INTERNAL_VER_DEBLOCKING_LUM(pYc, stepYc, quant);

  for (j = 1; j < mbPerRow; j++) {
    pYc += 16;
    pCbc += 8;
    pCrc += 8;
    quant = pMBinfo[j].quant;
    quant_c = modQ ? h263_quant_c[quant] : quant;
    H263_MB_VER_DEBLOCKING(pYc, stepYc, pCbc, stepCbc, pCrc, stepCrc, quant, quant_c);
    H263_MB_INTERNAL_VER_DEBLOCKING_LUM(pYc, stepYc, quant);
  }
}

#ifdef _OMP_KARABAS

Ipp32s h263_GetNumOfThreads(void)
{
    Ipp32s maxThreads = 1;
#ifdef _OPENMP
#pragma omp parallel shared(maxThreads)
#endif
    {
#ifdef _OPENMP
#pragma omp master
#endif

⌨️ 快捷键说明

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