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

📄 mode_decision.c

📁 h.264 影像壓縮 必須在 .net 的環境 下操作
💻 C
📖 第 1 页 / 共 3 页
字号:
          for (j = block_y; j< block_y + 2; j++)
          {
            memset(&enc_picture->ref_idx[LIST_0][j][block_x], best_ref[LIST_0], 2 * sizeof(char));
            memset(&enc_picture->ref_idx[LIST_1][j][block_x], best_ref[LIST_1], 2 * sizeof(char));
          }
        } // if (bslice)
        else
        {
          best_pdir = 0;
          *cost     = bmcost[LIST_0];
        }
      } // if (mode!=0)

      if (input->rdopt)
      {
        //--- get and check rate-distortion cost ---
        rdcost = RDCost_for_8x8blocks (currMB, &cnt_nonz, &curr_cbp_blk, enc_mb.lambda_md,
          block, mode, best_pdir, best_ref[LIST_0], best_ref[LIST_1]);
      }
      else
      {
        if (*cost!=INT_MAX)
          *cost += (REF_COST (enc_mb.lambda_mf[Q_PEL], B8Mode2Value (mode, best_pdir),
          enc_mb.list_offset[(best_pdir<1?LIST_0:LIST_1)]) - 1);
      }

      //--- set variables if best mode has changed ---
      if ( ( input->rdopt && rdcost < min_rdcost)
        || (!input->rdopt && *cost < min_cost8x8))
      {
        min_cost8x8                 = *cost;
        min_rdcost                  = rdcost;
        dataTr->part8x8mode [block] = mode;
        dataTr->part8x8pdir [block] = best_pdir;
        dataTr->part8x8l0ref[block] = best_ref[LIST_0];
        dataTr->part8x8l1ref[block] = best_ref[LIST_1];

        currMB->b8mode[block] = mode;

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

        //--- store number of nonzero coefficients ---
        best_cnt_nonz  = cnt_nonz;

        if (input->rdopt)
        {
          //--- store block cbp ---
          cbp_blk8x8    &= (~(0x33 << (((block>>1)<<3)+((block%2)<<1)))); // delete bits for block
          cbp_blk8x8    |= curr_cbp_blk;

          //--- store coefficients ---
          for (k=0; k< 4; k++)
          {
            for (j=0; j< 2; j++)
              memcpy(&cofACtr[k][j][0],&img->cofAC[block][k][j][0], 65 * sizeof(int));
          }
          if( img->yuv_format == YUV444 && !IS_INDEPENDENT(input) ) 
          {
            //--- store coefficients ---
            for (k=0; k< 4; k++)
            {
              for (j=0; j< 2; j++)
              {
                memcpy(&cofACCbCrtr1[k][j][0],&img->cofAC[block + 4][k][j][0], 65 * sizeof(int));
                memcpy(&cofACCbCrtr2[k][j][0],&img->cofAC[block + 8][k][j][0], 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));
            memcpy(&dataTr->mpr8x8[j][i0],&curr_mpr[j][i0], BLOCK_SIZE_8x8 * sizeof(imgpel));
          }

          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));
            }
          }
          if( img->yuv_format==YUV444 && !IS_INDEPENDENT(input)) 
          {
            for (j=j0; j<j0+8; j++)    
            {
              memcpy(&dataTr->rec_mbU8x8[j][i0],&enc_picture->imgUV[0][img->pix_y + j][img->pix_x + i0], BLOCK_SIZE_8x8 * sizeof(imgpel));
              memcpy(&dataTr->rec_mbV8x8[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->mpr[1][j][i0], BLOCK_SIZE_8x8 * sizeof(imgpel));
              memcpy(&dataTr->mpr8x8CbCr[1][j][i0],&img->mpr[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 (input->AdaptRndChroma || (img->yuv_format == YUV444 && !IS_INDEPENDENT(input) ))
          {
            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->cost8x8 += min_cost8x8;

  if (!input->rdopt)
  {
    if (transform8x8)
    {
      dataTr->cost8x8 += min_cost8x8;
      mode = dataTr->part8x8mode[block];
      pdir = dataTr->part8x8pdir[block];
    }
    else
    {
      mode = dataTr->part8x8mode[block];
      pdir = dataTr->part8x8pdir[block];
    }
    curr_cbp_blk  = 0;
    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]);

    if(img->yuv_format == YUV444 && ! IS_INDEPENDENT(input))
      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 ---
    for (k=0; k< 4; k++)
    {
        for (j=0; j< 2; j++)
          memcpy(cofACtr[k][j],img->cofAC[block][k][j],65 * sizeof(int));
    }
    if( img->yuv_format==YUV444 && !IS_INDEPENDENT(input) ) 
    {
      //--- store coefficients ---
      for (k=0; k< 4; k++)
      {
        for (j=0; j< 2; j++)
        {
          memcpy(cofACCbCrtr1[k][j],img->cofAC[block + 4][k][j],65 * sizeof(int));
          memcpy(cofACCbCrtr2[k][j],img->cofAC[block + 8][k][j],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));
      memcpy(&dataTr->mpr8x8[j][i0], &curr_mpr[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->yuv_format==YUV444 && !IS_INDEPENDENT(input) ) 
    {
      for (j=j0; j < j0 + BLOCK_SIZE_8x8; j++)
      {   
        memcpy(&dataTr->rec_mbU8x8[j][i0], &enc_picture->imgUV[0][img->pix_y + j][img->pix_x + i0], BLOCK_SIZE_8x8 * sizeof (imgpel));
        memcpy(&dataTr->rec_mbV8x8[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->mpr[1][j][i0], BLOCK_SIZE_8x8 * sizeof (imgpel)); 
        memcpy(&dataTr->mpr8x8CbCr[1][j][i0], &img->mpr[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))
          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->yuv_format==YUV444 && !IS_INDEPENDENT(input)) 
      {
        for (j = j0; j < j0 + BLOCK_SIZE_8x8; j++)
        {
          memcpy(&enc_picture->imgUV[0][img->pix_y + j][img->pix_x], dataTr->rec_mbU8x8[j], BLOCK_SIZE_8x8 * sizeof(imgpel));
          memcpy(&enc_picture->imgUV[1][img->pix_y + j][img->pix_x], dataTr->rec_mbV8x8[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], bslice);
  }
  //===== set motion vectors and reference frames (prediction) =====
  SetRefAndMotionVectors (currMB, block, dataTr->part8x8mode[block], dataTr->part8x8pdir[block], dataTr->part8x8l0ref[block], dataTr->part8x8l1ref[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 (input->AdaptRndChroma || (img->yuv_format == YUV444 && !IS_INDEPENDENT(input) ))
    {
      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] = input->CtxAdptLagrangeMult == 0 ? enc_mb->lambda_mf[MEPos] : (int)(enc_mb->lambda_mf[MEPos] * sqrt(lambda_mf_factor));
  }
}


⌨️ 快捷键说明

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