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

📄 md_low.c

📁 H.264编码实现
💻 C
📖 第 1 页 / 共 2 页
字号:
        if(params->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 (params->RCEnable)
        rc_store_diff(img->opix_x, img->opix_y, mb_pred);

      min_cost  = cost;
      best_mode = 0;
      tmp_8x8_flag = currMB->luma_transform_size_8x8_flag;
    }
    else
    {
      currMB->luma_transform_size_8x8_flag = tmp_8x8_flag; // restore if not best
      currMB->NoMbPartLessThan8x8Flag = tmp_no_mbpart; // restore if not best
    }
  }

  min_rd_cost = (double) min_cost;

  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 (currMB, enc_mb.lambda_md, &rd_cost);


    if (rd_cost <= min_rd_cost) //HYU_NOTE. bug fix. 08/15/07
    {
      currMB->cbp = temp_cpb;
      if (img->P444_joined)
      {
        curr_cbp[0] = cmp_cbp[1];  
        curr_cbp[1] = cmp_cbp[2];
      }

      if(enc_mb.valid[I4MB])   //KHHan. bug fix. Oct.15.2007
      {
        //coeffs
        if (params->Transform8x8Mode != 2) 
        {
          i4p=cofAC; cofAC=img->cofAC; img->cofAC=i4p;
        }
      }

      for(j=0; j<MB_BLOCK_SIZE; j++)
      {
        memcpy(temp_imgY[j], &enc_picture->imgY[img->pix_y + j][img->pix_x], MB_BLOCK_SIZE * sizeof (imgpel));
      }

      if (img->P444_joined)
      {
        for(j=0; j<MB_BLOCK_SIZE; j++)
        {
          memcpy(temp_imgU[j], &enc_picture->imgUV[0][img->pix_y + j][img->pix_x], MB_BLOCK_SIZE * sizeof (imgpel));
          memcpy(temp_imgV[j], &enc_picture->imgUV[1][img->pix_y + j][img->pix_x], MB_BLOCK_SIZE * sizeof (imgpel));
        }
      }

      //Rate control
      if (params->RCEnable)
        rc_store_diff(img->opix_x, img->opix_y, mb_pred);

      min_rd_cost  = rd_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 (img->P444_joined)
      {
        cmp_cbp[1] = curr_cbp[0]; 
        cmp_cbp[2] = curr_cbp[1]; 
        currMB->cbp |= cmp_cbp[1];    
        currMB->cbp |= cmp_cbp[2];    
        cmp_cbp[1] = currMB->cbp;   
        cmp_cbp[2] = currMB->cbp;
      }
    }
  }

  if (enc_mb.valid[I4MB]) // check INTRA4x4
  {
    currMB->luma_transform_size_8x8_flag = 0;
    currMB->mb_type = I4MB;
    temp_cpb = Mode_Decision_for_Intra4x4Macroblock (currMB, enc_mb.lambda_md, &rd_cost, is_cavlc);

    if (rd_cost <= min_rd_cost) 
    {
      currMB->cbp = temp_cpb;

      //Rate control
      if (params->RCEnable)
        rc_store_diff(img->opix_x, img->opix_y, mb_pred);

      min_rd_cost  = rd_cost; 
      best_mode = I4MB;
      tmp_8x8_flag = currMB->luma_transform_size_8x8_flag;

      if (img->AdaptiveRounding)
        store_adaptive_rounding_parameters_luma (currMB, best_mode);
    }
    else
    {
      currMB->luma_transform_size_8x8_flag = tmp_8x8_flag; // restore if not best
      if (img->P444_joined)
      {
        cmp_cbp[1] = curr_cbp[0]; 
        cmp_cbp[2] = curr_cbp[1]; 
        currMB->cbp |= cmp_cbp[1];    
        currMB->cbp |= cmp_cbp[2];    
        cmp_cbp[1] = currMB->cbp;   
        cmp_cbp[2] = currMB->cbp;
      }
      //coeffs
      i4p=cofAC; cofAC=img->cofAC; img->cofAC=i4p;
    }
  }
  if (enc_mb.valid[I16MB]) // check INTRA16x16
  {
    currMB->luma_transform_size_8x8_flag = 0;
    intrapred_16x16 (currMB, PLANE_Y);
    if (img->P444_joined)
    {
      select_plane(PLANE_U);
      intrapred_16x16 (currMB, PLANE_U);
      select_plane(PLANE_V);
      intrapred_16x16 (currMB, PLANE_V);
      select_plane(PLANE_Y);
    }
    switch(params->FastIntra16x16)
    {
    case 0:
    default:
      find_sad_16x16 = find_sad_16x16_JM;
      break;
    }

    rd_cost = find_sad_16x16 (currMB, &i16mode);

    if (rd_cost < min_rd_cost)
    {
      //Rate control      
      if (params->RCEnable)
        rc_store_diff(img->opix_x,img->opix_y,img->mpr_16x16[0][i16mode]);

      best_mode   = I16MB;      
      min_rd_cost  = rd_cost; 
      currMB->cbp = pDCT_16x16 (currMB, PLANE_Y, i16mode, is_cavlc);

      if (img->AdaptiveRounding)
        store_adaptive_rounding_parameters_luma (currMB, best_mode);

      if (img->P444_joined)
      {
        select_plane(PLANE_U);
        cmp_cbp[1] = pDCT_16x16(currMB, PLANE_U, i16mode, is_cavlc);
        select_plane(PLANE_V);
        cmp_cbp[2] = pDCT_16x16(currMB, PLANE_V, i16mode, is_cavlc);   

        select_plane(PLANE_Y);
        currMB->cbp |= cmp_cbp[1];    
        currMB->cbp |= cmp_cbp[2];    
        cmp_cbp[1] = currMB->cbp;   
        cmp_cbp[2] = currMB->cbp;
      }

    }
    else
    {
      currMB->luma_transform_size_8x8_flag = tmp_8x8_flag; // restore
      currMB->NoMbPartLessThan8x8Flag = tmp_no_mbpart;     // restore
    }
  }

  intra1 = IS_INTRA(currMB);

  //=====  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 ======
  //---------------------------------------------------------------------------
  {
    //===== set parameters for chosen mode =====
    SetModesAndRefframeForBlocks (currMB, best_mode);

    if (best_mode==P8x8)
    {
      if (currMB->luma_transform_size_8x8_flag && (cbp8_8x8ts == 0) && params->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));
        }
        if (img->P444_joined)
        {
          for(j=0; j<MB_BLOCK_SIZE; j++)
          {
            memcpy(&enc_picture->imgUV[0][img->pix_y + j][img->pix_x],temp_imgU[j], MB_BLOCK_SIZE * sizeof(imgpel)); 
            memcpy(&enc_picture->imgUV[1][img->pix_y + j][img->pix_x],temp_imgV[j], MB_BLOCK_SIZE * sizeof(imgpel));
          }
        }
      }

      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 (currMB, is_cavlc);

          if (img->AdaptiveRounding)
            store_adaptive_rounding_parameters_luma (currMB, best_mode);

          if (img->P444_joined)
          {
            if((currMB->cbp==0 && cmp_cbp[1] == 0 && cmp_cbp[2] == 0) &&(best_mode==0))
              currMB->luma_transform_size_8x8_flag = 0;
          }
          else if((currMB->cbp==0)&&(best_mode==0))
            currMB->luma_transform_size_8x8_flag = 0;

          //Rate control
          if (params->RCEnable)
            rc_store_diff(img->opix_x,img->opix_y,mb_pred);
        }
      }
    }
    //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;

    // precompute all chroma intra prediction modes
    if ((img->yuv_format != YUV400) && (img->yuv_format != YUV444))
      IntraChromaPrediction(currMB, NULL, NULL, NULL);

    img->i16offset = 0;
    dummy = 0;

    if ((img->yuv_format != YUV400) && (img->yuv_format != YUV444))
      ChromaResidualCoding (currMB, is_cavlc);

    if (img->AdaptiveRounding)
      store_adaptive_rounding_parameters_chroma (currMB, best_mode);

    if (best_mode==I16MB)
    {
      img->i16offset = I16Offset  (currMB->cbp, i16mode);
    }

    SetMotionVectorsMB (currMB, bslice);

    //===== check for SKIP mode =====
    if(img->P444_joined)
    {
      if ((pslice) && best_mode==1 && currMB->cbp==0 && cmp_cbp[1] == 0 && cmp_cbp[2] == 0 &&
        enc_picture->motion.ref_idx[LIST_0][img->block_y][img->block_x]    == 0 &&
        enc_picture->motion.mv     [LIST_0][img->block_y][img->block_x][0] == allmvs[0] &&
        enc_picture->motion.mv     [LIST_0][img->block_y][img->block_x][1] == allmvs[1])
      {
        currMB->mb_type = currMB->b8mode[0] = currMB->b8mode[1] = currMB->b8mode[2] = currMB->b8mode[3] = 0;
        currMB->luma_transform_size_8x8_flag = 0;
      }
    }
    else if ((pslice) && best_mode==1 && currMB->cbp==0 &&
      enc_picture->motion.ref_idx[LIST_0][img->block_y][img->block_x]    == 0 &&
      enc_picture->motion.mv     [LIST_0][img->block_y][img->block_x][0] == allmvs[0] &&
      enc_picture->motion.mv     [LIST_0][img->block_y][img->block_x][1] == allmvs[1])
    {
      currMB->mb_type = currMB->b8mode[0] = currMB->b8mode[1] = currMB->b8mode[2] = currMB->b8mode[3] = 0;
      currMB->luma_transform_size_8x8_flag = 0;
    }

    if (img->MbaffFrameFlag || (params->UseRDOQuant && params->RDOQ_QP_Num > 1))
      set_mbaff_parameters(currMB);
  }

  // Rate control
  if(params->RCEnable && params->RCUpdateMode <= MAX_RC_MODE)
    rc_store_mad(currMB);
  update_qp_cbp(currMB, best_mode);

  rdopt->min_rdcost = min_rd_cost;
  rdopt->min_dcost = min_rd_cost;

  if ( (img->MbaffFrameFlag)
    && (img->current_mb_nr%2)
    && (currMB->mb_type ? 0:((bslice) ? !currMB->cbp:1))  // bottom is skip
    && (prevMB->mb_type ? 0:((bslice) ? !prevMB->cbp:1))
    && !(field_flag_inference(currMB) == enc_mb.curr_mb_field)) // top is skip
  {
    rdopt->min_rdcost = 1e30;  // don't allow coding of a MB pair as skip if wrong inference
  }

  //===== Decide if this MB will restrict the reference frames =====
  if (params->RestrictRef)
    update_refresh_map(intra, intra1, currMB);

  if(params->SearchMode == UM_HEX)
  {
    UMHEX_skip_intrabk_SAD(best_mode, listXsize[enc_mb.list_offset[LIST_0]]);
  }
  else if(params->SearchMode == UM_HEX_SIMPLE)
  {
    smpUMHEX_skip_intrabk_SAD(best_mode, listXsize[enc_mb.list_offset[LIST_0]]);
  }

  //--- constrain intra prediction ---
  if(params->UseConstrainedIntraPred && (img->type==P_SLICE || img->type==B_SLICE))
  {
    img->intra_block[img->current_mb_nr] = IS_INTRA(currMB);
  }

  /*update adaptive rounding offset params*/
  if (img->AdaptiveRounding)
  {
    update_offset_params(currMB, best_mode, currMB->luma_transform_size_8x8_flag);
  }
}

⌨️ 快捷键说明

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