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

📄 umc_mpeg2_enc_b.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*//////////////////////////////////////////////////////////////////////////////
//
//                  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) 2002-2007 Intel Corporation. All Rights Reserved.
//
*/

#include "umc_defs.h"
#if defined (UMC_ENABLE_MPEG2_VIDEO_ENCODER)

#include "ippi.h"
#include "ipps.h"
#include "umc_mpeg2_enc_defs.h"

////////////////////////////////////////////////////////////////////////////////
/////////////////////////////// Coding B picture ///////////////////////////////
////////////////////////////////////////////////////////////////////////////////

using namespace UMC;

void MPEG2VideoEncoderBase::encodeB(Ipp32s numTh)
{
  const Ipp8u *pRef[2]; // parity same/opposite
  const Ipp8u *pRec[2]; // parity same/opposite
  Ipp32s      i, j, ic, jc, k, pred_ind;
  Ipp32s      macroblock_address_increment;
  Ipp32s      dc_dct_pred[3];
  Ipp16s      *pMBlock, *pDiff;
  Ipp32s      Count[12], CodedBlockPattern;
  IppMotionVector2   vector[3][2] = {0,}; // top/bottom/frame F/B
  MB_prediction_info pred_info[2];
  MB_prediction_info *best = pred_info;
  MB_prediction_info *curr = pred_info + 1;
  Ipp32s      me_bound_left[2], me_bound_right[2];
  Ipp32s      me_bound_top[2], me_bound_bottom[2];
  Ipp32s      me_bound_2_top[2], me_bound_1_bottom[2];
  Ipp32s      cur_offset;
  const Ipp8u *YBlock;
  const Ipp8u *UBlock;
  const Ipp8u *VBlock;
  Ipp32s      mean_frm[4], mean_fld[4];
  Ipp32s      slice_past_intra_address;
  Ipp32s      slice_macroblock_address;
  Ipp32s      start_y;
  Ipp32s      start_uv;
  Ipp32s      stop_y;
  Ipp32s      skip_flag;
  Ipp32s      dir0, dir1;

  dir0 = 2*B_count > encodeInfo.IPDistance ? 1 : 0;
  dir1 = 1 ^ dir0;

  CALC_START_STOP_ROWS

  best->pDiff = threadSpec[numTh].pDiff;
  curr->pDiff = threadSpec[numTh].pDiff1;
  threadSpec[numTh].fieldCount = 0;

  if (!bQuantiserChanged) {
    Ipp32s mf, mb;
    mb = B_count - encodeInfo.IPDistance;
    mf = B_count;
    for(j=start_y; j < stop_y; j += 16)
    {
      for(i=0; i < encodeInfo.info.clip_info.width; i += 16, k++)
      {
        pMBInfo[k].MV[0][0].x = pMBInfo[k].MV_P[0].x*mf/256;
        pMBInfo[k].MV[0][0].y = pMBInfo[k].MV_P[0].y*mf/256;
        pMBInfo[k].MV[0][1].x = pMBInfo[k].MV_P[0].x*mb/256;
        pMBInfo[k].MV[0][1].y = pMBInfo[k].MV_P[0].y*mb/256;
        pMBInfo[k].MV[1][0].x = pMBInfo[k].MV_P[1].x*mf/256;
        pMBInfo[k].MV[1][0].y = pMBInfo[k].MV_P[1].y*mf/256;
        pMBInfo[k].MV[1][1].x = pMBInfo[k].MV_P[1].x*mb/256;
        pMBInfo[k].MV[1][1].y = pMBInfo[k].MV_P[1].y*mb/256;
      }
    }
    k = (threads) ? (start_y/16)*MBcountH : 0;
  }

  for (j = start_y, jc = start_uv; j < stop_y; j += 16, jc += BlkHeight_c)
  {
    PutSliceHeader(j >> 4, numTh);
    macroblock_address_increment = 1;
    slice_macroblock_address = 0;
    slice_past_intra_address = 0;

    // reset predictors at the start of slice
    dc_dct_pred[0] = dc_dct_pred[1] = dc_dct_pred[2] = ResetTbl[intra_dc_precision];

    ippsZero_8u((Ipp8u*)threadSpec[numTh].PMV, sizeof(threadSpec[0].PMV));
    BOUNDS_V(0,j)
    BOUNDS_V(1,j)
    if(picture_structure != FRAME_PICTURE) {
      BOUNDS_V_FIELD(0,j)
      BOUNDS_V_FIELD(1,j)
      // to avoid reference below bottom in 16x8 mode when trying to skip MB
      me_bound_1_bottom[0] = me_bound_bottom[0];
      me_bound_1_bottom[1] = me_bound_bottom[1];
    }

    for(i=ic=0; i < encodeInfo.info.clip_info.width; i += 16, ic += BlkWidth_c)
    {
      Ipp32s goodpred = 0;
      cur_offset = i + j * YFrameHSize;

      YBlock = Y_src + i  + j  * YFrameHSize;
      UBlock = U_src + ic + jc * UVFrameHSize;
      VBlock = V_src + ic + jc * UVFrameHSize;

      slice_macroblock_address = i >> 4;

      if (bQuantiserChanged && pMBInfo[k].mb_type) {
        best->pred_type = pMBInfo[k].prediction_type;
        best->dct_type = pMBInfo[k].dct_type;
        best->mb_type = pMBInfo[k].mb_type;
        if (!(pMBInfo[k].mb_type & MB_INTRA)) {
          pDiff = best->pDiff;
          if (pMBInfo[k].prediction_type == MC_FRAME) {
            SET_MOTION_VECTOR((&vector[2][0]), pMBInfo[k].MV[0][0].x, pMBInfo[k].MV[0][0].y);
            SET_MOTION_VECTOR((&vector[2][1]), pMBInfo[k].MV[0][1].x, pMBInfo[k].MV[0][1].y);
            if (pMBInfo[k].mb_type == (MB_FORWARD|MB_BACKWARD)) {
              GETDIFF_FRAME_FB(Y, Y, l, pDiff);
            }
            else if (pMBInfo[k].mb_type & MB_FORWARD) {
              GETDIFF_FRAME(Y, Y, l, pDiff, 0);
            }
            else { // if(pMBInfo[k].mb_type & MB_BACKWARD)
              GETDIFF_FRAME(Y, Y, l, pDiff, 1);
            }
            VARMEAN_FRAME(pDiff, best->var, best->mean, best->var_sum);
          } else {
            Ipp32s mv_shift = (picture_structure == FRAME_PICTURE) ? 1 : 0;
            SET_FIELD_VECTOR((&vector[0][0]), pMBInfo[k].MV[0][0].x, pMBInfo[k].MV[0][0].y >> mv_shift);
            SET_FIELD_VECTOR((&vector[1][0]), pMBInfo[k].MV[1][0].x, pMBInfo[k].MV[1][0].y >> mv_shift);
            SET_FIELD_VECTOR((&vector[0][1]), pMBInfo[k].MV[0][1].x, pMBInfo[k].MV[0][1].y >> mv_shift);
            SET_FIELD_VECTOR((&vector[1][1]), pMBInfo[k].MV[1][1].x, pMBInfo[k].MV[1][1].y >> mv_shift);
            if (pMBInfo[k].mb_type == (MB_FORWARD|MB_BACKWARD)) {
              GETDIFF_FIELD_FB(Y, Y, l, pDiff);
            }
            else if (pMBInfo[k].mb_type & MB_FORWARD) {
              GETDIFF_FIELD(Y, Y, l, pDiff, 0);
            }
            else { // if(pMBInfo[k].mb_type & MB_BACKWARD)
              GETDIFF_FIELD(Y, Y, l, pDiff, 1);
            }
            VARMEAN_FIELD(pDiff, best->var, best->mean, best->var_sum);
          }
        }
        goto encodeMB;
      }

      pMBInfo[k].mb_type = 0;
      pMBInfo[k].dct_type = DCT_FRAME;
      pMBInfo[k].prediction_type = MC_FRAME;
      VARMEAN_FRAME_Y(curr->var, mean_frm, curr->var_sum);
      pMBInfo[k].var_sum = curr->var_sum;

      // try skip MB
      if (i != 0 && i != MBcountH*16-16 &&
        !(pMBInfo[k-1].mb_type & MB_INTRA)
        && (!(pMBInfo[k - 1].mb_type & MB_FORWARD)
        || i+((threadSpec[numTh].PMV[0][0].x+1)>>1)+15 < MBcountH*16)
        && (!(pMBInfo[k - 1].mb_type & MB_BACKWARD)
        || i+((threadSpec[numTh].PMV[0][1].x+1)>>1)+15 < MBcountH*16) )
      {
        Ipp32s blk;
        Ipp32s var, mean;
        Ipp32s mb_type;

        pMBInfo[k].mv_field_sel[2][0] = curr_field;
        pMBInfo[k].mv_field_sel[2][1] = curr_field;

        mb_type = pMBInfo[k - 1].mb_type & (MB_FORWARD | MB_BACKWARD);
        pMBInfo[k].mb_type = mb_type;

        pDiff = threadSpec[numTh].pDiff;

        SET_MOTION_VECTOR((&vector[2][0]), threadSpec[numTh].PMV[0][0].x, threadSpec[numTh].PMV[0][0].y);
        SET_MOTION_VECTOR((&vector[2][1]), threadSpec[numTh].PMV[0][1].x, threadSpec[numTh].PMV[0][1].y);

        if (mb_type == (MB_FORWARD|MB_BACKWARD))
        {
          GETDIFF_FRAME_FB(Y, Y, l, pDiff);
        }
        else if (mb_type & MB_FORWARD)
        {
          GETDIFF_FRAME(Y, Y, l, pDiff, 0);
        }
        else // if(mb_type & MB_BACKWARD)
        {
          GETDIFF_FRAME(Y, Y, l, pDiff, 1);
        }

        skip_flag = 1;
        for (blk = 0; blk < 4; blk++) {
          ippiVarSum8x8_16s32s_C1R(pDiff + frm_diff_off[blk], 32, &var, &mean);
          if(var > varThreshold) {
            skip_flag = 0;
            break;
          }
          mean /= 8;
          if(mean >= quantiser_scale_value || mean <= -quantiser_scale_value) {
            skip_flag = 0;
            break;
          }
        }
        if (skip_flag) { // check UV
          if (mb_type == (MB_FORWARD|MB_BACKWARD))
          {
            GETDIFF_FRAME_FB(U, UV, c, pDiff);
            GETDIFF_FRAME_FB(V, UV, c, pDiff);
          }
          else if (mb_type & MB_FORWARD)
          {
            GETDIFF_FRAME(U, UV, c, pDiff, 0);
            GETDIFF_FRAME(V, UV, c, pDiff, 0);
          }
          else // if(mb_type & MB_BACKWARD)
          {
            GETDIFF_FRAME(U, UV, c, pDiff, 1);
            GETDIFF_FRAME(V, UV, c, pDiff, 1);
          }
          for (blk = 4; blk < block_count; blk++) {
            ippiVarSum8x8_16s32s_C1R(pDiff + frm_diff_off[blk], 32, &var, &mean);
            if(var > varThreshold) {
              skip_flag = 0;
              break;
            }
            mean /= 8;
            if(mean >= quantiser_scale_value || mean <= -quantiser_scale_value) {
              skip_flag = 0;
              break;
            }
          }
        }

        if (skip_flag)
        {
skip_macroblock:
          //pMBInfo[k].cbp = -1;
          macroblock_address_increment++;
          ippsCopy_8u((Ipp8u*)threadSpec[numTh].PMV, (Ipp8u*)pMBInfo[k].MV, sizeof(threadSpec[0].PMV));
          k++;
          continue;
        }
      } // try skip

      pMBInfo[k].mb_type = 0;
      best->var_sum = (1 << 30);

      //VARMEAN_FRAME_Y(curr->var, mean_frm, curr->var_sum);
      curr->var_sum = SCALE_VAR_INTRA(curr->var_sum);
      //var_intra_frame = curr->var_sum;
      if(curr->var_sum < best->var_sum)
      {
        curr->mb_type = MB_INTRA;
        curr->dct_type = DCT_FRAME;
        SWAP_PTR(best, curr);
      }

      BOUNDS_H(dir0,i)
      ME_FRAME(dir0, curr->var_sum, curr->pDiff, curr->dct_type);
      curr->var_sum = SCALE_VAR(curr->var_sum, SC_VAR_1V);

      if(curr->var_sum < best->var_sum)
      {
        curr->mb_type = dir0 == 0 ? MB_FORWARD : MB_BACKWARD;
        curr->pred_type = MC_FRAME;
        SWAP_PTR(best, curr);

⌨️ 快捷键说明

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