mode_decision.c

来自「the newest JM software by h.264 JVT offi」· C语言 代码 · 共 1,390 行 · 第 1/4 页

C
1,390
字号
      for(j = 0; j <= 1; j++)
        img->nz_coeff[currMB->mb_nr][i1 + i][j1 + j] = best_nz_coeff[i][j];
    }
#endif

    if (!transform8x8)
    {
      if (min_cost8x8 != INT_MAX)
        dataTr->mb_p8x8_cost += min_cost8x8;
      else
        dataTr->mb_p8x8_cost = INT_MAX;
    }


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

      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];
    currMB->ar_mode = (mode != 0)? mode: P8x8;
    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][0],img->cofAC[block][0][0], 4 * 2 * 65 * sizeof(int));

    if(img->P444_joined) 
    {
      //--- store coefficients ---
      memcpy(cofACtr[1][0][0],img->cofAC[block + 4][0][0], 4 * 2 * 65 * sizeof(int));
      memcpy(cofACtr[2][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(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 (&enc_picture->motion, 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 (stored_state_8x8 == TRUE)
      reset_coding_state (currSlice, currMB, cs_b8);
    else
    {
      update_adaptive_rounding_8x8(dataTr, fadjust);
    }
  }
}

/*!
*************************************************************************************
* \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[currMB->mb_nr - 1] +
      mb16x16_cost_frame[currMB->mb_nr - (img->width>>4)] + 1)/2.0;
  }
  else if (currMB->mb_available_left)
  {
    mb16x16_cost = mb16x16_cost_frame[currMB->mb_nr - 1];
  }
  else if (currMB->mb_available_up)
  {
    mb16x16_cost = mb16x16_cost_frame[currMB->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
 *    Decides whether to perform tranform 8x8 for this mode
 *************************************************************************************
 */
int transform_termination_control(Macroblock* currMB, int mode, int bslice) 
{
  // Go through transform modes.
  // Note that if currMB->cbp is 0 one could choose to skip 8x8 mode
  // although this could be due to deadzoning decisions.
  //if (params->Transform8x8Mode==1 && currMB->cbp!=0)
  if (params->Transform8x8Mode == 1)
  {
    //=========== try the 8x8 transform with mb_types 16x16,16x8, 8x16, 8x8, and DIRECT 16x16 ===========
    if (currMB->luma_transform_size_8x8_flag == 0 && 
      ((mode >= 1 && mode <= 3) || (bslice && mode == 0 && active_sps->direct_8x8_inference_flag) || (mode == P8x8)))
    {
      //try with 8x8 transform size
      currMB->luma_transform_size_8x8_flag = 1;
      return 0;
    }
    else
    {
      currMB->luma_transform_size_8x8_flag = 0;
      return 1;
    }
  }
  else
  {
    return 1;
  }
}

/*!
 *************************************************************************************
 * \brief
 *    Update prediction direction for mode P16x16 to check all prediction directions
 *************************************************************************************
 */
int bslice_16x16_termination_control(Block8x8Info *b8x8info, int *ctr16x16, int mode, int bslice)
{  
  char pdir = 0;
  short i, bipred_me = 0;
  int lastcheck = 1;
  //--- for INTER16x16 in BSLICEs check all prediction directions ---
  if (mode == 1 && bslice)
  {
    switch (*ctr16x16)
    {
      case 0:
        pdir = 0;
        lastcheck = 0;
        break;
      case 1:
        pdir = 1;
        lastcheck = 0;
        break;
      case 2:
        pdir = 2;
        if (params->BiPredMotionEstimation)
        {
          lastcheck = 0;
        }
        break;
      case 3:
        pdir = 2;
        bipred_me = 1;
        lastcheck = 0;
        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;
    }
    (*ctr16x16)++;
  }
  return lastcheck;
}

⌨️ 快捷键说明

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