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

📄 mode_decision.c

📁 H264视频编解码程序
💻 C
📖 第 1 页 / 共 5 页
字号:
                ctr16x16--;
              if (ctr16x16 < 2) 
                index--;
              ctr16x16++;
            }
            
            // Skip intra modes in inter slices if best inter mode is 
            // a MB partition and cbp is 0.
            if (input->SkipIntraInInterSlices && !intra && mode >= I16MB 
              && best_mode <=3 && currMB->cbp == 0)
              continue;
            
            if (enc_mb.valid[mode])
              compute_mode_RD_cost(mode, currMB, enc_mb, &min_rdcost, &min_rate, i16mode, bslice, &inter_skip);
            
            if ((input->BiPredMotionEstimation) && (bslice) && ctr16x16 == 2 
              && img->bi_pred_me[mode] < 2 && mode == 1 && best8x8pdir[1][0] == 2) 
              img->bi_pred_me[mode] = img->bi_pred_me[mode] + 1;
          }// for (ctr16x16=0, index=0; index<max_index; index++)
        }// for (currMB->c_ipred_mode=DC_PRED_8; currMB->c_ipred_mode<=max_chroma_pred_mode; currMB->c_ipred_mode++)
        
        // Selective Intra Coding
        if(img->type!=I_SLICE && input->rdopt == 2 && input->SelectiveIntraEnable && input->ProfileIDC<FREXT_HP)
        {
          fast_mode_intra_decision(&intra_skip, min_rate);
          
          if(!intra_skip)
          {
            // precompute all new chroma intra prediction modes
            if (img->yuv_format != YUV400)
            {
              // precompute all new chroma intra prediction modes
              IntraChromaPrediction(&mb_available_up, &mb_available_left, &mb_available_up_left);
              max_chroma_pred_mode = PLANE_8;
            }
            else
              max_chroma_pred_mode = DC_PRED_8;
            
            max_index = 9;
            
            for (currMB->c_ipred_mode=DC_PRED_8; currMB->c_ipred_mode<=max_chroma_pred_mode; currMB->c_ipred_mode++)
            {
              
              // bypass if c_ipred_mode is not allowed
              if ( (img->yuv_format != YUV400) &&
                (  ((!intra || !input->IntraDisableInterOnly) && input->ChromaIntraDisable == 1 && currMB->c_ipred_mode!=DC_PRED_8) 
                || (currMB->c_ipred_mode == VERT_PRED_8 && !mb_available_up) 
                || (currMB->c_ipred_mode == HOR_PRED_8  && !mb_available_left) 
                || (currMB->c_ipred_mode == PLANE_8     && (!mb_available_left || !mb_available_up || !mb_available_up_left))))
                continue;           
              
              //===== GET BEST MACROBLOCK MODE =====
              for (index = 5; index < max_index; index++)
              {
                mode = mb_mode_table[index];
                
                if (input->SkipIntraInInterSlices && !intra && mode >= I16MB 
                  && best_mode <=3 && currMB->cbp == 0)
                  continue;
                
                if (img->yuv_format != YUV400)
                {           
                  if (input->rdopt == 2)
                  {
                    i16mode = 0;              
                    // RDcost of mode 1 in P-slice and mode 0, 1 in B-slice are already available
                    if(((bslice && mode == 0) || (!islice && mode == 1)))
                      continue;
                  }
                  else
                  {
                    // Residue Color Transform
                    if(img->residue_transform_flag)
                    {
                      mode = mb_mode_table_RCT[index];
                      if( mode == I16MB) 
                        i16mode = index -5;
                      // bypass if i16mode is not allowed
                      if (mode == I16MB &&
                        (  (i16mode==VERT_PRED_16 && !mb_available_up) 
                        || (i16mode==HOR_PRED_16  && !mb_available_left) 
                        || (i16mode==PLANE_16    && (!mb_available_left || !mb_available_up || !mb_available_up_left))))
                        continue;
                    }
                    else
                    {
                      mode = mb_mode_table[index];
                      i16mode = 0; 
                    }
                  }
                }
                
                if (enc_mb.valid[mode])
                  compute_mode_RD_cost(mode, currMB, enc_mb, &min_rdcost, &min_rate, i16mode, bslice, &inter_skip);                            
              } // for (index = 5; index < max_index; index++)
            }
          }
        }          
      }
#ifdef BEST_NZ_COEFF
      for (j=0;j<4;j++)
        for (i=0; i<(4+img->num_blk8x8_uv); i++)
          img->nz_coeff[img->current_mb_nr][j][i] = gaaiMBAFF_NZCoeff[j][i]; 
#endif
   }
   else //rdopt off
   {
     tmp_8x8_flag = currMB->luma_transform_size_8x8_flag;	//save 8x8_flag
     tmp_no_mbpart = currMB->NoMbPartLessThan8x8Flag;		  //save no-part-less
     
     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   

⌨️ 快捷键说明

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