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

📄 mode_decision.c

📁 H.264编码实现
💻 C
📖 第 1 页 / 共 3 页
字号:
          {
            for (j=j0; j<j0+8; j++)    
            {
              memcpy(&dataTr->rec_mb8x8_cr[0][j][i0],&enc_picture->imgUV[0][img->pix_y + j][img->pix_x + i0], BLOCK_SIZE_8x8 * sizeof(imgpel));
              memcpy(&dataTr->rec_mb8x8_cr[1][j][i0],&enc_picture->imgUV[1][img->pix_y + j][img->pix_x + i0], BLOCK_SIZE_8x8 * sizeof(imgpel));
              memcpy(&dataTr->mpr8x8CbCr[0][j][i0],&img->mb_pred[1][j][i0], BLOCK_SIZE_8x8 * sizeof(imgpel));
              memcpy(&dataTr->mpr8x8CbCr[1][j][i0],&img->mb_pred[2][j][i0], BLOCK_SIZE_8x8 * sizeof(imgpel));
            }
          }
          
        }
        if (img->AdaptiveRounding)
        {
          for (j=j0; j<j0+8; j++)
          {
            memcpy(&fadjust[j][i0], &fadjustTransform[0][j][i0], 8 * sizeof(int));
          }

          if (params->AdaptRndChroma || (img->P444_joined))
          {
            int j0_cr = (j0 * img->mb_cr_size_y) / MB_BLOCK_SIZE;
            int i0_cr = (i0 * img->mb_cr_size_x) / MB_BLOCK_SIZE;
            for (k = 0; k < 2; k++)
            {
              for (j=j0_cr; j < j0_cr + (img->mb_cr_size_y >> 1); j++)
              {
                memcpy(&fadjustCr[k][j][i0_cr], &fadjustTransformCr[k][0][j][i0_cr], (img->mb_cr_size_x >> 1) * sizeof(int));
              }
            }
          }
        }
        //--- store best 8x8 coding state ---
        if (block < 3)
          store_coding_state (currMB, cs_b8);
      } // if (rdcost <= min_rdcost)

      //--- re-set coding state as it was before coding with current mode was performed ---
      reset_coding_state (currMB, cs_cm);
    } // if ((enc_mb->valid[mode] && (transform8x8 == 0 || mode != 0 || (mode == 0 && active_sps->direct_8x8_inference_flag)))
  } // for (min_rdcost=1e30, index=(bslice?0:1); index<6; index++)

#ifdef BEST_NZ_COEFF
  for(i = 0; i <= 1; i++)  
  {
    for(j = 0; j <= 1; j++)
      img->nz_coeff[img->current_mb_nr][i1 + i][j1 + j] = best_nz_coeff[i][j];
  }
#endif

  if (!transform8x8)
    dataTr->mb_p8x8_cost += min_cost8x8;

  if (!params->rdopt)
  {
    if (transform8x8)
    {
      dataTr->mb_p8x8_cost += min_cost8x8;
      mode = dataTr->part8x8mode[block];
      pdir = dataTr->part8x8pdir[block];
    }
    else
    {
      mode = dataTr->part8x8mode[block];
      pdir = dataTr->part8x8pdir[block];
    }

    curr_cbp_blk  = 0;
    currMB->bipred_me[block] = dataTr->part8x8bipred[block];
    best_cnt_nonz = LumaResidualCoding8x8 (currMB, &dummy, &curr_cbp_blk, block, pdir,
      (pdir == 0 || pdir == 2 ? mode : 0), (pdir == 1 || pdir == 2 ? mode : 0), 
      dataTr->part8x8l0ref[block], dataTr->part8x8l1ref[block], is_cavlc);

    if (img->P444_joined)
      best_cnt_nonz += coeff_cost_cr[1] + coeff_cost_cr[2];

    cbp_blk8x8   &= (~(0x33 << (((block>>1)<<3)+((block & 0x01)<<1)))); // delete bits for block
    cbp_blk8x8   |= curr_cbp_blk;

    //--- store coefficients ---
    memcpy(cofACtr[0][0],img->cofAC[block][0][0],4 * 2 * 65 * sizeof(int));

    if(img->P444_joined) 
    {
      //--- store coefficients ---
      memcpy(cofACCbCrtr1[0][0],img->cofAC[block + 4][0][0], 4 * 2 * 65 * sizeof(int));
      memcpy(cofACCbCrtr2[0][0],img->cofAC[block + 8][0][0], 4 * 2 * 65 * sizeof(int));
    }


    //--- store reconstruction and prediction ---
    for (j = j0; j < j0 + BLOCK_SIZE_8x8; j++)
    {
      memcpy(&dataTr->rec_mbY8x8[j][i0], &enc_picture->imgY[img->pix_y + j][img->pix_x + i0], BLOCK_SIZE_8x8 * sizeof (imgpel));
    }
    for (j = j0; j < j0 + BLOCK_SIZE_8x8; j++)
    {
      memcpy(&dataTr->mpr8x8[j][i0], &mb_pred[j][i0], BLOCK_SIZE_8x8 * sizeof (imgpel));
    }


    //--- store reconstruction and prediction ---
    if(img->type==SP_SLICE &&(!si_frame_indicator))
    {
      for (j=j0; j < j0 + BLOCK_SIZE_8x8; j++)
      {
        memcpy(&dataTr->lrec[j][i0],&lrec[img->pix_y+j][img->pix_x+i0],BLOCK_SIZE_8x8 * sizeof(int)); // store coefficients for primary SP slice
      }
    }
    if(img->P444_joined) 
    {
      for (j=j0; j < j0 + BLOCK_SIZE_8x8; j++)
      {   
        memcpy(&dataTr->rec_mb8x8_cr[0][j][i0], &enc_picture->imgUV[0][img->pix_y + j][img->pix_x + i0], BLOCK_SIZE_8x8 * sizeof (imgpel));
        memcpy(&dataTr->rec_mb8x8_cr[1][j][i0], &enc_picture->imgUV[1][img->pix_y + j][img->pix_x + i0], BLOCK_SIZE_8x8 * sizeof (imgpel));
        memcpy(&dataTr->mpr8x8CbCr[0][j][i0], &img->mb_pred[1][j][i0], BLOCK_SIZE_8x8 * sizeof (imgpel)); 
        memcpy(&dataTr->mpr8x8CbCr[1][j][i0], &img->mb_pred[2][j][i0], BLOCK_SIZE_8x8 * sizeof (imgpel));
      }
    }   
  }

  //----- set cbp and count of nonzero coefficients ---
  if (best_cnt_nonz)
  {
    cbp8x8       |= (1 << block);
    cnt_nonz_8x8 += best_cnt_nonz;
  }

  if (!transform8x8)
  {
    if (block<3)
    {
      //===== re-set reconstructed block =====
      j0   = 8*(block >> 1);
      i0   = 8*(block & 0x01);
      for (j = j0; j < j0 + BLOCK_SIZE_8x8; j++)
      {
        memcpy(&enc_picture->imgY[img->pix_y + j][img->pix_x], dataTr->rec_mbY8x8[j], BLOCK_SIZE_8x8 * sizeof(imgpel));
      }

      if (params->rdopt == 3)
      {
        errdo_get_best_block(img, enc_picture->p_dec_img[0], decs->dec_mbY8x8, j0, BLOCK_SIZE_8x8);
      }

      if(img->type==SP_SLICE &&(!si_frame_indicator))
      {
        for (j = j0; j < j0 + BLOCK_SIZE_8x8; j++)
        {
          memcpy(&lrec[img->pix_y + j][img->pix_x], dataTr->lrec[j],2*BLOCK_SIZE*sizeof(imgpel)); // reset the coefficients for SP slice
        }
      }

      if(img->P444_joined) 
      {
        for (k=0; k<2; k++)
        {
          for (j = j0; j < j0 + BLOCK_SIZE_8x8; j++)
          {
            memcpy(&enc_picture->imgUV[k][img->pix_y + j][img->pix_x], dataTr->rec_mb8x8_cr[k][j], BLOCK_SIZE_8x8 * sizeof(imgpel));
          }
        }
      }
    } // if (block<3)
  }
  else
  {
    //======= save motion data for 8x8 partition for transform size 8x8 ========
    StoreNewMotionVectorsBlock8x8(0, block, dataTr->part8x8mode[block], dataTr->part8x8l0ref[block], dataTr->part8x8l1ref[block], dataTr->part8x8pdir[block], dataTr->part8x8bipred[block], bslice);
  }
  //===== set motion vectors and reference frames (prediction) =====
  SetRefAndMotionVectors (currMB, block, dataTr->part8x8mode[block], dataTr->part8x8pdir[block], dataTr->part8x8l0ref[block], dataTr->part8x8l1ref[block], dataTr->part8x8bipred[block]);

  //===== set the coding state after current block =====
  //if (transform8x8 == 0 || block < 3)
  if (block < 3)
    reset_coding_state (currMB, cs_b8);

  if (img->AdaptiveRounding)
  {
    for (j=j0; j < j0 + BLOCK_SIZE_8x8; j++)
    {
      memcpy(&fadjustTransform  [lumaAdjustIndex][j][i0], &fadjust[j][i0], BLOCK_SIZE_8x8 * sizeof(int));
    }

    if (params->AdaptRndChroma || (img->P444_joined))
    {
      int j0_cr = (j0 * img->mb_cr_size_y) >> MB_BLOCK_SHIFT;
      int i0_cr = (i0 * img->mb_cr_size_x) >> MB_BLOCK_SHIFT;
      for (k = 0; k < 2; k++)
      {
        for (j=j0_cr; j<j0_cr+(img->mb_cr_size_y >> 1); j++)
        {
          memcpy(&fadjustTransformCr[k][chromaAdjustIndex][j][i0_cr], &fadjustCr[k][j][i0_cr], (img->mb_cr_size_x >> 1) * sizeof(int));
        }
      }
    }
  }
}


/*!
*************************************************************************************
* \brief
*    Checks whether a primary SP slice macroblock was encoded as I16
*************************************************************************************
*/
int check_for_SI16()
{
  int i,j;
  for(i=img->pix_y;i<img->pix_y+MB_BLOCK_SIZE;i++)
  {
    for(j=img->pix_x;j<img->pix_x+MB_BLOCK_SIZE;j++)
      if(lrec[i][j]!=-16)
        return 0;
  }
  return 1;
}

void get_initial_mb16x16_cost(Macroblock* currMB)
{
  if (currMB->mb_available_left && currMB->mb_available_up)
  {
    mb16x16_cost = (mb16x16_cost_frame[img->current_mb_nr - 1] +
      mb16x16_cost_frame[img->current_mb_nr - (img->width>>4)] + 1)/2.0;
  }
  else if (currMB->mb_available_left)
  {
    mb16x16_cost = mb16x16_cost_frame[img->current_mb_nr - 1];
  }
  else if (currMB->mb_available_up)
  {
    mb16x16_cost = mb16x16_cost_frame[img->current_mb_nr - (img->width>>4)];
  }
  else
  {
    mb16x16_cost = CALM_MF_FACTOR_THRESHOLD;
  }

  lambda_mf_factor = mb16x16_cost < CALM_MF_FACTOR_THRESHOLD ? 1.0 : sqrt(mb16x16_cost / (CALM_MF_FACTOR_THRESHOLD * img->lambda_mf_factor[img->type][img->qp]));
}

void adjust_mb16x16_cost(int cost)
{
  mb16x16_cost = (double) cost;
  mb16x16_cost_frame[img->current_mb_nr] = mb16x16_cost;

  lambda_mf_factor = (mb16x16_cost < CALM_MF_FACTOR_THRESHOLD)
  ? 1.0
  : sqrt(mb16x16_cost / (CALM_MF_FACTOR_THRESHOLD * img->lambda_mf_factor[img->type][img->qp]));
}

void update_lambda_costs(RD_PARAMS *enc_mb, int lambda_mf[3])
{
  int MEPos;
  for (MEPos = 0; MEPos < 3; MEPos ++)
  {
    lambda_mf[MEPos] = params->CtxAdptLagrangeMult == 0 ? enc_mb->lambda_mf[MEPos] : (int)(enc_mb->lambda_mf[MEPos] * sqrt(lambda_mf_factor));
  }
}

/*!
 *************************************************************************************
 * \brief
 *    Return array's minimum and its index
 *************************************************************************************
 */
int iminarray ( int arr[], int size, int *minind )
{
  int i; 
  int mincand = arr[0];
  *minind = 0;
  for ( i = 1; i < size; i++ )
  {
    if (arr[i] < mincand)
    {
      mincand = arr[i];
      *minind = i;
    }
  }
  return mincand;
} 

/*!
 *************************************************************************************
 * \brief
 *    Determines whether bi prediction is enabaled for current mode
 *************************************************************************************
 */
int is_bipred_enabled(int mode) 
{
  int enabled = 0;
  mode = (mode == P8x8) ? 4: mode;
  if (params->BiPredMotionEstimation)
  {
    if (mode > 0 && mode < 5)
    {
      enabled = (params->BiPredSearch[mode - 1]) ? 1: 0;
    }    
    else
    {
      enabled = 0;
    }
  }
  else
  {
    enabled = 0;
  }
  return enabled;
}


/*!
 *************************************************************************************
 * \brief
 *    Update prediction direction for mode P16x16 to check all prediction directions
 *************************************************************************************
 */
void update_prediction_for_mode16x16(Block8x8Info *b8x8info, int ctr16x16, int *index)
{
  char pdir = 0;
  short i, bipred_me = 0;
  switch (ctr16x16)
  {
    case 0:
      *index = *index - 1;
      break;
    case 1:
      pdir = 1;
      *index = *index - 1;
      break;
    case 2:
      pdir = 2;
      if (params->BiPredMotionEstimation)
      {
        *index = *index - 1;
      }
      break;
    case 3:
      pdir = 2;
      bipred_me = 1;
      *index = *index - 1;
      break;
    case 4:
      pdir = 2;
      bipred_me = 2;
      break;
    default:
      error("invalid 'ctr16x16' value", -1);
      break;
  }
  for (i = 0; i< 4; i++)
  {
    b8x8info->bipred8x8me[1][i] = bipred_me;
    b8x8info->best8x8pdir[1][i] = pdir;
  }
}

⌨️ 快捷键说明

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