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

📄 mode_decision.c

📁 H.264ITU-T 标准源码JM98 ITU推荐的免费解码器
💻 C
📖 第 1 页 / 共 5 页
字号:
     
     if (img->yuv_format != YUV400)
       // precompute all chroma intra prediction modes
       IntraChromaPrediction(NULL, NULL, NULL);
     
     if (enc_mb.valid[0] && bslice) // check DIRECT MODE
     {
       if(have_direct)
       {
         switch(input->Transform8x8Mode)
         {
         case 1: // Mixture of 8x8 & 4x4 transform
           cost = ((cost8x8_direct < cost_direct) || !(enc_mb.valid[5] && enc_mb.valid[6] && enc_mb.valid[7])) 
             ? cost8x8_direct : cost_direct;
           break;
         case 2: // 8x8 Transform only
           cost = cost8x8_direct;
           break;
         default: // 4x4 Transform only
           cost = cost_direct;
           break;
         }
       }
       else
       { //!have_direct
         cost = Get_Direct_CostMB (enc_mb.lambda_mf);
       }
       if (cost!=INT_MAX)
       {
         cost -= (int)floor(16*enc_mb.lambda_me+0.4999);
       }
       
       if (cost <= min_cost)
       {
         if(active_sps->direct_8x8_inference_flag && input->Transform8x8Mode)
         {
           if(input->Transform8x8Mode==2)
             currMB->luma_transform_size_8x8_flag=1;
           else
           {
             if(cost8x8_direct < cost_direct)
               currMB->luma_transform_size_8x8_flag=1;
             else
               currMB->luma_transform_size_8x8_flag=0;
           }
         }
         else
           currMB->luma_transform_size_8x8_flag=0;
         
         //Rate control
         if (input->RCEnable)
           rc_store_diff(img->opix_x,img->opix_y,img->mpr);
         
         min_cost  = cost;
         best_mode = 0;
       }
       else
       {
         currMB->luma_transform_size_8x8_flag = tmp_8x8_flag; // restore if not best
         currMB->NoMbPartLessThan8x8Flag = tmp_no_mbpart; // restore if not best
       }        
     }
     
     if (enc_mb.valid[I8MB]) // check INTRA8x8
     {
       currMB->luma_transform_size_8x8_flag = 1; // at this point cost will ALWAYS be less than min_cost 
       
       currMB->mb_type = I8MB;
       temp_cpb = Mode_Decision_for_new_Intra8x8Macroblock (enc_mb.lambda_md, &cost);
       
       if (cost <= min_cost)
       {
         // Residue Color Transform
         if(img->residue_transform_flag)
         {            
           for(i=0; i<2; i++) 
           {
             for(j=0; j<4; j++) 
               for(k=0; k<4; k++)
                 if(cbp_chroma_block[i][j][k]) cr_cbp = 2;
           }            
           cr_cbp = dct_chroma_DC(0, cr_cbp);
           cr_cbp = dct_chroma_DC(1, cr_cbp);
           
           temp_cpb += (cr_cbp<<4);
           for(j=0; j<MB_BLOCK_SIZE; j++) 
           {
             pix_y = img->pix_y + j;
             for(i=0; i<MB_BLOCK_SIZE; i++) 
             {
               pix_x = img->pix_x + i;
               temp_imgU[j][i] = enc_picture->imgUV[0][pix_y][pix_x];
               temp_imgV[j][i] = enc_picture->imgUV[1][pix_y][pix_x];
             }
           }
         }          
         currMB->cbp = temp_cpb;
         
         //coeffs
         if (input->Transform8x8Mode != 2)
         {
           i4p=cofAC; cofAC=img->cofAC; img->cofAC=i4p;
         }
         
         for(j=0; j<MB_BLOCK_SIZE; j++) 
         {
           pix_y = img->pix_y + j;
           for(i=0; i<MB_BLOCK_SIZE; i++) 
           {
             pix_x = img->pix_x + i;
             temp_imgY[j][i] = enc_picture->imgY[pix_y][pix_x];
           }
         }
         
         //Rate control
         if (input->RCEnable)
           rc_store_diff(img->opix_x,img->opix_y,img->mpr);
         
         min_cost  = cost;
         best_mode = I8MB;
         tmp_8x8_flag = currMB->luma_transform_size_8x8_flag;
       } 
       else
         currMB->luma_transform_size_8x8_flag = tmp_8x8_flag; // restore if not best
     }
     
     if (enc_mb.valid[I4MB]) // check INTRA4x4
     {
       currMB->luma_transform_size_8x8_flag = 0;
       currMB->mb_type = I4MB;
       temp_cpb = Mode_Decision_for_Intra4x4Macroblock (enc_mb.lambda_md, &cost);
       
       if (cost <= min_cost)
       {
         // Residue Color Transform
         if(img->residue_transform_flag)
         {
           for(i=0; i<2; i++) 
           { 
             for(j=0; j<4; j++) 
               for(k=0; k<4; k++) 
                 if(cbp_chroma_block[i][j][k]) 
                   cr_cbp = 2;
           }
           cr_cbp = dct_chroma_DC(0, cr_cbp);
           cr_cbp = dct_chroma_DC(1, cr_cbp);
           
           temp_cpb += (cr_cbp<<4);
         }
         currMB->cbp = temp_cpb;
         
         //Rate control
         if (input->RCEnable)
           rc_store_diff(img->opix_x,img->opix_y,img->mpr);
         
         min_cost  = cost;
         best_mode = I4MB;
         tmp_8x8_flag = currMB->luma_transform_size_8x8_flag;
       } 
       else
       {
         currMB->luma_transform_size_8x8_flag = tmp_8x8_flag; // restore if not best
         //coeffs
         i4p=cofAC; cofAC=img->cofAC; img->cofAC=i4p;
       }
     }
     if (enc_mb.valid[I16MB]) // check INTRA16x16
     {
       currMB->luma_transform_size_8x8_flag = 0;
       intrapred_luma_16x16 ();
       cost = find_sad_16x16 (&i16mode);
       
       if (cost < min_cost)
       {
         //Rate control
         // should this access opix or pix?
         if (input->RCEnable)
           rc_store_diff(img->opix_x,img->opix_y,img->mprr_2[i16mode]);
         
         // Residue Color Transform
         if(img->residue_transform_flag)
         {
           for (j = 0; j < MB_BLOCK_SIZE; j++) 
           {
             pix_y = img->pix_y + j;
             for (i = 0; i < MB_BLOCK_SIZE; i++) 
             {
               pix_x = img->pix_x + i;
               residue_G = imgY_org    [pix_y][pix_x] - img->mprr_2   [i16mode]             [j][i];
               residue_B = imgUV_org[0][pix_y][pix_x] - img->mprr_c[0][currMB->c_ipred_mode][j][i];
               residue_R = imgUV_org[1][pix_y][pix_x] - img->mprr_c[1][currMB->c_ipred_mode][j][i];                
               /* Forward Residue Transform */
               resTrans_R[j][i] = residue_R - residue_B;
               temp             = residue_B + (resTrans_R[j][i] >> 1);
               resTrans_B[j][i] = residue_G-temp;
               resTrans_G[j][i] = temp+(resTrans_B[j][i] >> 1);                
               img->m7[j][i]    = resTrans_G[j][i];
             }
           }
         }
         
         best_mode   = I16MB;
         currMB->cbp = dct_luma_16x16 (i16mode);
         
         // Residue Color Transform
         if(img->residue_transform_flag)
         {
           for (j = 0; j < MB_BLOCK_SIZE; j++) 
           {
             for (i=0; i < MB_BLOCK_SIZE; i++) 
             {
               rec_resG[j][i] = img->m7[j][i];
               img->m7[j][i]  = resTrans_B[j][i];
             }
           }
           cr_cbp = dct_chroma(0, 0);
           
           for (j=0; j < MB_BLOCK_SIZE; j++) 
           {
             for (i=0; i < MB_BLOCK_SIZE; i++) 
             {
               rec_resB[j][i] = img->m7[j][i];
               img->m7[j][i]  = resTrans_R[j][i];
             }
           } 
           cr_cbp = dct_chroma(1, cr_cbp);
           
           for (j=0; j < MB_BLOCK_SIZE; j++) 
           {
             for (i=0; i < MB_BLOCK_SIZE; i++) 
               rec_resR[j][i] = img->m7[j][i];
           } 
           currMB->cbp += (cr_cbp<<4);
           
           /* Inverse Residue Transform */
           for (j=0; j < MB_BLOCK_SIZE; j++) 
           {
             pix_y = img->pix_y + j;
             for (i=0; i < MB_BLOCK_SIZE; i++) 
             {
               pix_x = img->pix_x + i;
               temp      = rec_resG[j][i] - (rec_resB[j][i] >> 1);
               residue_G = rec_resB[j][i]+temp;
               residue_B = temp - (rec_resR[j][i]>>1);
               residue_R = residue_B+rec_resR[j][i];                
               enc_picture->imgY    [pix_y][pix_x] = 
                 min(img->max_imgpel_value   ,max(0, residue_G + (int) img->mprr_2[i16mode][j][i]));
               enc_picture->imgUV[0][pix_y][pix_x] = 
                 min(img->max_imgpel_value_uv,max(0, residue_B + (int) img->mprr_c[0][currMB->c_ipred_mode][j][i]));
               enc_picture->imgUV[1][pix_y][pix_x] = 
                 min(img->max_imgpel_value_uv,max(0, residue_R + (int) img->mprr_c[1][currMB->c_ipred_mode][j][i]));
             }
           }
         }
       }
       else
       {
         currMB->luma_transform_size_8x8_flag = tmp_8x8_flag; // restore
         currMB->NoMbPartLessThan8x8Flag = tmp_no_mbpart;     // restore
       }
     }
     }    
     if (rerun==0)
       intra1 = IS_INTRA(currMB);
  } // for (rerun=0; rerun<runs; rerun++) 
  
  //=====  S E T   F I N A L   M A C R O B L O C K   P A R A M E T E R S ======
  //---------------------------------------------------------------------------  
  if (input->rdopt)
  {   
    if ((cbp!=0 || best_mode==I16MB ))
      currMB->prev_cbp = 1;    
    else if (cbp==0 && !input->RCEnable)
    {
      currMB->delta_qp = 0;
      currMB->qp = currMB->prev_qp;
      img->qp = currMB->qp;
      currMB->prev_cbp = 0;
    }    
    set_stored_macroblock_parameters ();
  }
  else
  {
    //===== set parameters for chosen mode =====
    SetModesAndRefframeForBlocks (best_mode);
    
    if (best_mode==P8x8)
    {
      if (currMB->luma_transform_size_8x8_flag && (cbp8_8x8ts == 0) && input->Transform8x8Mode != 2)
        currMB->luma_transform_size_8x8_flag = 0;
      
      SetCoeffAndReconstruction8x8 (currMB);
      
      memset(currMB->intra_pred_modes, DC_PRED, MB_BLOCK_PARTITIONS * sizeof(char));
      for (k=0, j = img->block_y; j < img->block_y + BLOCK_MULTIPLE; j++)
        memset(&ipredmodes[j][img->block_x], DC_PRED, BLOCK_MULTIPLE * sizeof(char));
    }
    else
    {
      //===== set parameters for chosen mode =====
      if (best_mode == I8MB)
      {
        memcpy(currMB->intra_pred_modes,currMB->intra_pred_modes8x8, MB_BLOCK_PARTITIONS * sizeof(char));
        for(j = img->block_y; j < img->block_y + BLOCK_MULTIPLE; j++)
          memcpy(&img->ipredmode[j][img->block_x],&img->ipredmode8x8[j][img->block_x], BLOCK_MULTIPLE * sizeof(char));

        //--- restore reconstruction for 8x8 transform ---
        for(j=0; j<MB_BLOCK_SIZE; j++) 
        {
          memcpy(&enc_picture->imgY[img->pix_y + j][img->pix_x],temp_imgY[j], MB_BLOCK_SIZE * sizeof(imgpel));
        }
        
        // Residue Color Transform
        if(img->residue_transform_flag)
        {          
          for(j=0; j<MB_BLOCK_SIZE; j++) 
          {
            pix_y = img->pix_c_y + j;
            for(i=0; i<MB_BLOCK_SIZE; i++) 
            {
              pix_x = img->pix_c_x + i;
              enc_picture->imgUV[0][pix_y][pix_x] = temp_imgU[j][i] ;
              enc_picture->imgUV[1][pix_y][pix_x] = temp_imgV[j][i] ;
            }
          }                
        }
      }
      
      if ((best_mode!=I4MB)&&(best_mode != I8MB))
      {
        memset(currMB->intra_pred_modes,DC_PRED, MB_BLOCK_PARTITIONS * sizeof(char));
        for(j = img->block_y; j < img->block_y + BLOCK_MULTIPLE; j++)
          memset(&ipredmodes[j][img->block_x],DC_PRED, BLOCK_MULTIPLE * sizeof(char));

        if (best_mode!=I16MB)
        {
          if((best_mode>=1) && (best_mode<=3))
            currMB->luma_transform_size_8x8_flag = best_transform_flag;
          LumaResidualCoding ();
          
          if((currMB->cbp==0)&&(best_mode==0))
            currMB->luma_transform_size_8x8_flag = 0;
          
          //Rate control
          if (input->RCEnable)
            rc_store_diff(img->opix_x,img->opix_y,img->mpr);
        }
      }
    }
    //check luma cbp for transform size flag
    if (((currMB->cbp&15) == 0) && !(IS_OLDINTRA(currMB) || currMB->mb_type == I8MB))
      currMB->luma_transform_size_8x8_flag = 0;
    
    if (img->yuv_format != YUV400)
      // precompute all chroma intra prediction modes
      IntraChromaPre

⌨️ 快捷键说明

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