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

📄 h263decfuncs.c

📁 audio-video-codecs.rar语音编解码器
💻 C
📖 第 1 页 / 共 4 页
字号:
/* ///////////////////////////////////////////////////////////////////////
//
//               INTEL CORPORATION PROPRIETARY INFORMATION
//  This software is supplied under the terms of a license agreement or
//  nondisclosure agreement with Intel Corporation and may not be copied
//  or disclosed except in accordance with the terms of that agreement.
//        Copyright (c) 2005-2006 Intel Corporation. All Rights Reserved.
//
//  Description:  H.263 decoder functions
//
*/

#include "h263.h"
#include "h263dec.h"

h263_Status h263_PredictDecodeMV(h263_Info *pInfo, h263_MacroBlock *MBcurr, Ipp32s frGOB, Ipp32s y, Ipp32s x, Ipp32s adv)
{
  IppMotionVector *mvLeft, *mvTop, *mvRight, *mvCurr;
  h263_Status status;
  h263_VideoPicture *VPic = &pInfo->VideoSequence.VideoPicture;
  Ipp32s  mbInRow = VPic->MacroBlockPerRow;
  Ipp32s i1, i2;

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

  mvCurr  = MBcurr[0].mv;
  mvLeft  = MBcurr[-1].mv;
  mvTop   = MBcurr[-mbInRow].mv;
  mvRight = MBcurr[-mbInRow+1].mv;
  if (y == frGOB && x == 0) {
    mvCurr->dx = mvCurr->dy = 0;
  } else if (x == 0) {
    mvCurr->dx = h263_Median(0, mvTop[i2].dx, mvRight[i2].dx);
    mvCurr->dy = h263_Median(0, mvTop[i2].dy, mvRight[i2].dy);
  } else if (y == frGOB) {
    MBcurr->mv[0] = mvLeft[i1];
  } else if (x == mbInRow - 1) {
    mvCurr->dx = h263_Median(0, mvLeft[i1].dx, mvTop[i2].dx);
    mvCurr->dy = h263_Median(0, mvLeft[i1].dy, mvTop[i2].dy);
  } else {
    mvCurr->dx = h263_Median(mvLeft[i1].dx, mvTop[i2].dx, mvRight[i2].dx);
    mvCurr->dy = h263_Median(mvLeft[i1].dy, mvTop[i2].dy, mvRight[i2].dy);
  }

  if (!VPic->oppmodes.UMV && !VPic->modes.UMV) {
    status = h263_DecodeMV(pInfo, mvCurr, -32, 31);
  } else if (!VPic->oppmodes.UMV) {
    status = h263_DecodeMV(pInfo, mvCurr, -63, 63);
  } else {
    Ipp32s mvdx, mvdy;
    status = h263_DecodeMVD_umvplus(pInfo, &mvdx, &mvdy);
    mvCurr->dx = mvCurr->dx + (Ipp16s)mvdx;
    mvCurr->dy = mvCurr->dy + (Ipp16s)mvdy;
  }
  return status;
}

h263_Status h263_DecodeMVD(h263_Info *pInfo, Ipp32s *mvdx, Ipp32s *mvdy, Ipp32s fcode)
{
    const h263_VLC1 *pTab;
    Ipp32s          mvd, sign;
    Ipp32u          code;
    Ipp32s          factor = fcode - 1;

    /* decode MVDx */
    code = h263_ShowBits(pInfo, 12);
    if (code >= 128)
        pTab = h263_MVD_T14_2 + ((code - 128) >> 5);
    else if (code >= 2)
        pTab = h263_MVD_T14_1 + (code - 2);
    else
        return H263_STATUS_ERROR;
    mvd = pTab->code;
    h263_FlushBits(pInfo, pTab->len);
    if (mvd) {
        sign = h263_GetBit(pInfo);
        if (factor) {
            code = h263_GetBits9(pInfo, factor);
            mvd = ((mvd - 1) << factor) + code + 1;
        }
        if (sign)
            mvd = -mvd;
    }
    *mvdx = mvd;
    /* decode MVDy */
    code = h263_ShowBits(pInfo, 12);
    if (code >= 128)
        pTab = h263_MVD_T14_2 + ((code - 128) >> 5);
    else if (code >= 2)
        pTab = h263_MVD_T14_1 + (code - 2);
    else
        return H263_STATUS_ERROR;
    mvd = pTab->code;
    h263_FlushBits(pInfo, pTab->len);
    if (mvd) {
        sign = h263_GetBit(pInfo);
        if (factor) {
            code = h263_GetBits9(pInfo, factor);
            mvd = ((mvd - 1) << factor) + code + 1;
        }
        if (sign)
            mvd = -mvd;
    }
    *mvdy = mvd;
    return H263_STATUS_OK;
}

h263_Status h263_DecodeMV(h263_Info *pInfo, IppMotionVector *mv, Ipp32s leftlim, Ipp32s rightlim)
{
  Ipp32s  mvdx, mvdy, dx, dy;

  if (h263_DecodeMVD(pInfo, &mvdx, &mvdy, 1) != H263_STATUS_OK)
    return H263_STATUS_ERROR;

  dx = mv->dx + mvdx;
  if (dx < leftlim)
    dx += 64;
  else if (dx > rightlim)
    dx -= 64;
  mv->dx = (Ipp16s)dx;
  dy = mv->dy + mvdy;
  if (dy < leftlim)
    dy += 64;
  else if (dy > rightlim)
    dy -= 64;
  mv->dy = (Ipp16s)dy;
  return H263_STATUS_OK;
}

h263_Status h263_DecodeMVD_umvplus(h263_Info *pInfo, Ipp32s *mvdx, Ipp32s *mvdy)
{
  Ipp32s mvx, mvy;
  Ipp32u code;

  code = h263_GetBit(pInfo);
  if (code)
    mvx = 0;
  else {
    mvx = 1;
    for (;;) {
      code = h263_GetBits9(pInfo, 2);
      if ((code & 1) == 0)
        break;
      mvx = (mvx << 1) | (code >> 1);
    }
    if (code & 2)
      mvx = -mvx;
  }

  code = h263_GetBit(pInfo);
  if (code)
    mvy = 0;
  else {
    mvy = 1;
    for (;;) {
      code = h263_GetBits9(pInfo, 2);
      if ((code & 1) == 0)
        break;
      mvy = (mvy << 1) | (code >> 1);
    }
    if (code & 2)
      mvy = -mvy;
  }
  if (mvx == 1 && mvy == 1)
    code = h263_GetBit(pInfo);

#ifdef H263_METICULOUS
  if (!code) {
    h263_Error("Error: Zero anti-emulation bit");
    return H263_STATUS_PARSE_ERROR;
  }
#endif

  *mvdx = mvx;
  *mvdy = mvy;

  return H263_STATUS_OK;
}

/*
//  Intra DC and AC reconstruction for macroblock
*/
h263_Status h263_DecodeMacroBlockIntra(h263_Info *pInfo, Ipp32s pat, Ipp32s quant, Ipp32s quant_c, Ipp8u *pR[], Ipp32s stepR[])
{
  __ALIGN16(Ipp16s, coeff, 64);
  Ipp32s blockNum, pm = 32, lnz;
  Ipp32s modQ = pInfo->VideoSequence.VideoPicture.oppmodes.modQuant;

  for (blockNum = 0; blockNum < 6; blockNum++) {
    if (blockNum > 3)
      quant = quant_c;
    if (ippiReconstructCoeffsIntra_H263_1u16s(&pInfo->bufptr, &pInfo->bitoff, coeff, &lnz, pat & pm, quant, 0, IPPVC_SCAN_ZIGZAG, modQ) != ippStsNoErr) {
      return H263_STATUS_ERROR;
    }
    if (lnz > 0) {
      ippiDCT8x8Inv_16s8u_C1R(coeff, pR[blockNum], stepR[blockNum]);
      h263_StatisticInc_(&pInfo->VideoSequence.Statistic.nB_INTRA_AC);
    } else {
      h263_Set8x8_8u(pR[blockNum], stepR[blockNum], (Ipp8u)((coeff[0] + 4) >> 3));
      h263_StatisticInc_(&pInfo->VideoSequence.Statistic.nB_INTRA_DC);
    }
    pm >>= 1;
  }
  return H263_STATUS_OK;
}

h263_Status h263_DecodeMacroBlockIntra_AdvI(h263_Info *pInfo, Ipp32s x, Ipp32s pat, Ipp32s quant, Ipp32s quant_c, Ipp32s scan, Ipp8u *pR[], Ipp32s stepR[])
{
  __ALIGN16(Ipp16s, coeff, 64);
  Ipp32s      blockNum, pm = 32, lnz, dc, ac, k, nz;
  Ipp16s      *predC, *predA;
  h263_IntraPredBlock *bCurr;
  Ipp32s modQ = pInfo->VideoSequence.VideoPicture.oppmodes.modQuant;

  for (blockNum = 0; blockNum < 6; blockNum ++) {
    bCurr = &pInfo->VideoSequence.IntraPredBuff.block[6*x+blockNum];
    if (blockNum > 3)
      quant = quant_c;
    if (pat & pm) {
      if (ippiReconstructCoeffsIntra_H263_1u16s(&pInfo->bufptr, &pInfo->bitoff, coeff, &lnz, pat & pm, quant, 1, scan, modQ) != ippStsNoErr)
        return H263_STATUS_ERROR;
      if (lnz) {
        h263_StatisticInc_(&pInfo->VideoSequence.Statistic.nB_INTRA_AC);
      } else {
        h263_StatisticInc_(&pInfo->VideoSequence.Statistic.nB_INTRA_DC);
      }
    } else {
      if (scan != IPPVC_SCAN_ZIGZAG) {
        h263_Zero64_16s(coeff);
      } else
        coeff[0] = 0;
      lnz = 0;
    }

    nz = 0;
    if (scan == IPPVC_SCAN_ZIGZAG) {
      if (bCurr->predA->dct_dc >= 0) {
        dc = bCurr->predA->dct_dc;
        dc = bCurr->predC->dct_dc >= 0 ? ((dc + bCurr->predC->dct_dc) >> 1) : dc;
      } else
        dc = bCurr->predC->dct_dc >= 0 ? bCurr->predC->dct_dc : 1024;
      if (lnz && ((quant > 8) || modQ)) { /* ??? */
        for (k = 1; k < 64; k ++) {
          h263_CLIP(coeff[k], -2048, 2047);
        }
      }
    } else if (scan == IPPVC_SCAN_HORIZONTAL) {
      if (bCurr->predC->dct_dc >= 0) {
        dc = bCurr->predC->dct_dc;
        predC = bCurr->predC->dct_acC;
        for (k = 1; k < 8; k ++) {
          ac = coeff[k] + predC[k];
          h263_CLIP(ac, -2048, 2047); /* ??? */
          coeff[k] = (Ipp16s)ac;
          if (ac)
            nz = 1;
        }
        if ((lnz > 7) && ((quant > 8) || modQ)) { /* ??? */
          for (k = 8; k < 64; k ++) {
            h263_CLIP(coeff[k], -2048, 2047);
          }
        }
      } else {
        dc = 1024;
        if (lnz && ((quant > 8) || modQ)) { /* ??? */
          for (k = 1; k < 64; k ++) {
            h263_CLIP(coeff[k], -2048, 2047);
          }
        }
      }
    } else { /* scan == IPPVC_SCAN_VERTICAL */
      if (bCurr->predA->dct_dc >= 0) {
        dc = bCurr->predA->dct_dc;
        predA = bCurr->predA->dct_acA;
        for (k = 1; k < 8; k ++) {
          ac = coeff[k*8] + predA[k];
          h263_CLIP(ac, -2048, 2047); /* ??? */
          coeff[k*8] = (Ipp16s)ac;
          if (ac)
            nz = 1;
        }
      } else
        dc = 1024;
      if (lnz && ((quant > 8) || modQ)) { /* ??? */
        for (k = 1; k < 64; k ++) {
          h263_CLIP(coeff[k], -2048, 2047);
        }
      }
    }
    dc += coeff[0];
    dc |= 1; /* oddify */
    h263_CLIP(dc, 0, 2047); /* ??? h263_CLIPR(dc, 2047); */
    coeff[0] = (Ipp16s)dc;

    if (lnz | nz) {
      ippiDCT8x8Inv_16s8u_C1R(coeff, pR[blockNum], stepR[blockNum]);
      /* copy predicted coeffs for future Prediction */
      for (k = 1; k < 8; k ++) {
        bCurr[6].dct_acC[k] = coeff[k];
        bCurr[6].dct_acA[k] = coeff[k*8];
      }
    } else {
      k = (coeff[0] + 4) >> 3;
      h263_CLIPR(k, 255);
      h263_Set8x8_8u(pR[blockNum], stepR[blockNum], (Ipp8u)k);
      for (k = 1; k < 8; k ++) {
        bCurr[6].dct_acC[k] = bCurr[6].dct_acA[k] = 0;
      }
    }
    bCurr[6].dct_dc = coeff[0];
    pm >>= 1;
  }
  return H263_STATUS_OK;
}

h263_Status h263_DecodeMacroBlockInter(h263_Info *pInfo, Ipp16s *coeffMB, Ipp32s quant, Ipp32s quant_c, Ipp32s pat)
{
  Ipp32s i, lnz, pm = 32;
  Ipp16s *coeff = coeffMB;
  Ipp32s modQ = pInfo->VideoSequence.VideoPicture.oppmodes.modQuant;
  Ipp32s altInterVLC = pInfo->VideoSequence.VideoPicture.oppmodes.altInterVLC;

  for (i = 0; i < 6; i ++) {
    if (i > 3)
      quant = quant_c;
    if ((pat) & pm) {
      if (!altInterVLC) {
        if (ippiReconstructCoeffsInter_H263_1u16s(&pInfo->bufptr, &pInfo->bitoff, coeff, &lnz, quant, modQ) != ippStsNoErr)
          return H263_STATUS_ERROR;
      } else {
        __ALIGN16(Ipp16s, coeffZ, 64);
        if (ippiDecodeCoeffsInter_H263_1u16s(&pInfo->bufptr, &pInfo->bitoff, coeffZ, &lnz, modQ, IPPVC_SCAN_NONE) != ippStsNoErr)
          if (ippiDecodeCoeffsIntra_H263_1u16s(&pInfo->bufptr, &pInfo->bitoff, coeffZ, &lnz, 1, modQ, IPPVC_SCAN_NONE) != ippStsNoErr)
            return H263_STATUS_ERROR;
        ippiQuantInvInter_H263_16s_C1I(coeffZ, lnz, quant, modQ);
        ippiScanInv_16s_C1(coeffZ, coeff, lnz, IPPVC_SCAN_ZIGZAG);
      }
      if (lnz != 0) {
        if ((lnz <= 4) && (coeff[16] == 0))

⌨️ 快捷键说明

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