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

📄 rdopt.c

📁 h.264/avc 视频编码程序,实现分数像素匹配功能,非原创.
💻 C
📖 第 1 页 / 共 5 页
字号:
                  //--- get cost for backward prediction ---
                  bw_mcost   = motion_cost[mode][0][block];

                  //--- get cost for bidirectional prediction ---
                  bid_mcost  = (input->rdopt ? write_ref ? REF_COST (lambda_motion_factor, best_fw_ref) : 0 : (int)(2*lambda_motion*min(best_fw_ref,1)));
                  bid_mcost += BIDPartitionCost (mode, block, best_fw_ref, lambda_motion_factor);

                  //--- get prediction direction ----
                  if      (fw_mcost<=bw_mcost && fw_mcost<=bid_mcost)    {best_pdir = 0;  cost = fw_mcost; }
                  else if (bw_mcost<=fw_mcost && bw_mcost<=bid_mcost)    {best_pdir = 1;  cost = bw_mcost; }
                  else                                                   {best_pdir = 2;  cost = bid_mcost;}
                } // if (bframe)
                else
                {
                  best_pdir = 0;
                  cost      = fw_mcost;
                }
              } // if (mode!=IBLOCK && mode!=0)

              //--- store coding state before coding with current mode ---
              store_coding_state (cs_cm);

              if (input->rdopt)
              {
                //--- get and check rate-distortion cost ---
                rdcost = RDCost_for_8x8blocks (&cnt_nonz, &curr_cbp_blk, lambda_mode,
                                               block, mode, best_pdir, best_fw_ref);
              }
              else
              {
                cost += (REF_COST (lambda_motion_factor, B8Mode2Value (mode, best_pdir)) - 1);
              }

              //--- set variables if best mode has changed ---
              if (( input->rdopt && rdcost < min_rdcost) ||
                  (!input->rdopt && cost   < min_cost  )   )
              {
                min_cost                 = cost;
                min_rdcost               = rdcost;
                best8x8mode      [block] = mode;
                best8x8pdir[P8x8][block] = best_pdir;
                best8x8ref [P8x8][block] = best_fw_ref;

                //--- 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++)
                  for (i=0; i<18; i++)  cofAC8x8[block][k][j][i] = img->cofAC[block][k][j][i];

                  //--- store reconstruction and prediction ---
                  for (j=j0; j<j0+8; j++)
                  for (i=i0; i<i0+8; i++)
                  {
                    rec_mbY8x8[j][i] = imgY[img->pix_y+j][img->pix_x+i];
                    mpr8x8    [j][i] = img->mpr[i][j];
                  }
                }

                //--- store coding state ---
                store_coding_state (cs_b8);
              } // if (rdcost <= min_rdcost)

              //--- re-set coding state as it was before coding with current mode was performed ---
              reset_coding_state (cs_cm);
            } // if (valid[mode=b8_mode_table[index]])
          } // for (min_rdcost=1e30, index=(bframe?0:1); index<6; index++)

          cost8x8 += min_cost;

          if (!input->rdopt)
          {
            mode = best8x8mode[block];
            pdir = best8x8pdir[P8x8][block];

            if (mode!=IBLOCK)
            {
              curr_cbp_blk  = 0;
              best_cnt_nonz = LumaResidualCoding8x8 (&dummy, &curr_cbp_blk, block,
                                                     (pdir==0||pdir==2?mode:0),
                                                     (pdir==1||pdir==2?mode:0),
                                                     (mode!=0?best8x8ref[P8x8][block]:max(0,refFrArr[img->block_y+j1][img->block_x+i1])));
              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++)
            for (i=0; i<18; i++)  cofAC8x8[block][k][j][i] = img->cofAC[block][k][j][i];

            //--- store reconstruction and prediction ---
            for (j=j0; j<j0+8; j++)
            for (i=i0; i<i0+8; i++)
            {
              rec_mbY8x8[j][i] = imgY[img->pix_y+j][img->pix_x+i];
              mpr8x8    [j][i] = img->mpr[i][j];
            }
          }

          //----- set cbp and count of nonzero coefficients ---
          if (best_cnt_nonz)
          {
            cbp8x8        |= (1<<block);
            cnt_nonz_8x8  += (best8x8mode[block]==IBLOCK ? MAX_VALUE : best_cnt_nonz);
          }
          else if (best8x8mode[block]==IBLOCK && cnt_nonz_8x8)
          {
            // coefficients cannot be discarded if a following INTRA4x4 blocks needs they for prediction
            cnt_nonz_8x8  += MAX_VALUE;
          }

          if ((mode=best8x8mode[block])!=IBLOCK)
          {
            //===== reset intra prediction modes (needed for prediction, must be stored after 8x8 mode dec.) =====
            j0 = img->block_y+1+2*(block/2);
            i0 = img->block_x+1+2*(block%2);
            for (j=j0; j<j0+2; j++)
            for (i=i0; i<i0+2; i++)    img->ipredmode[i][j]         = 0;
            i0 = 4*block;
            for (i=i0; i<i0+4; i++)    currMB->intra_pred_modes[i]  = 0;
          }

          if (block<3)
          {
            //===== set motion vectors and reference frames (prediction) =====
            SetRefAndMotionVectors (block, mode, best8x8ref[P8x8][block], best8x8pdir[P8x8][block]);

            //===== re-set reconstructed block =====
            j0   = 8*(block/2);
            i0   = 8*(block%2);
            for (j=j0; j<j0+8; j++)
            for (i=i0; i<i0+8; i++)  imgY[img->pix_y+j][img->pix_x+i] = rec_mbY8x8[j][i];
          } // if (block<3)

          //===== set the coding state after current block =====
          reset_coding_state (cs_b8);
        } // for (cbp8x8=cbp_blk8x8=cnt_nonz_8x8=0, block=0; block<4; block++)

        //===== store intra prediction modes for 8x8+ macroblock mode =====
        for (k=0, j=img->block_y+1; j<img->block_y+5; j++)
        for (     i=img->block_x+1; i<img->block_x+5; i++, k++)
        {
          b8_ipredmode       [k] = img   ->ipredmode    [i][j];
          b8_intra_pred_modes[k] = currMB->intra_pred_modes[k];
        }

        //--- re-set coding state (as it was before 8x8 block coding) ---
        reset_coding_state (cs_mb);
      }
      else // if (valid[P8x8])
      {
        cost8x8 = (1<<20);
      }



      //===== MOTION ESTIMATION FOR 16x16, 16x8, 8x16 BLOCKS =====
      for (min_cost=cost8x8, best_mode=P8x8, mode=3; mode>0; mode--)
      {
        if (valid[mode])
        {
          for (cost=0, block=0; block<(mode==1?1:2); block++)
          {
            PartitionMotionSearch (mode, block, lambda_motion);

            //--- set 4x4 block indizes (for getting MV) ---
            j = (block==1 && mode==2 ? 2 : 0);
            i = (block==1 && mode==3 ? 2 : 0);

            //--- get cost and reference frame for forward prediction ---
            for (fw_mcost=max_mcost, ref=0; ref<max_ref; ref++)
            {
              if (!checkref || ref==0 || CheckReliabilityOfRef (block, ref, mode))
              {
                mcost  = (input->rdopt ? write_ref ? REF_COST (lambda_motion_factor, ref) : 0 : (int)(2*lambda_motion*min(ref,1)));
                mcost += motion_cost[mode][ref+1][block];
                if (mcost < fw_mcost)
                {
                  fw_mcost    = mcost;
                  best_fw_ref = ref;
                }
              }
            }

            if (bframe)
            {
              //--- get cost for backward prediction ---
              bw_mcost   = motion_cost[mode][0][block];

              //--- get cost for bidirectional prediction ---
              bid_mcost  = (input->rdopt ? write_ref ? REF_COST (lambda_motion_factor, best_fw_ref) : 0 : (int)(2*lambda_motion*min(best_fw_ref,1)));
              bid_mcost += BIDPartitionCost (mode, block, best_fw_ref, lambda_motion_factor);

              //--- get prediction direction ----
              if      (fw_mcost<=bw_mcost && fw_mcost<=bid_mcost)    {best_pdir = 0;  cost += fw_mcost; }
              else if (bw_mcost<=fw_mcost && bw_mcost<=bid_mcost)    {best_pdir = 1;  cost += bw_mcost; }
              else                                                   {best_pdir = 2;  cost += bid_mcost;}
            }
            else // if (bframe)
            {
              best_pdir  = 0;
              cost      += fw_mcost;
            }


            //----- set reference frame and direction parameters -----
            if (mode==3)
            {
              best8x8ref [3][  block] = best8x8ref [3][  block+2] = best_fw_ref;
              best8x8pdir[3][  block] = best8x8pdir[3][  block+2] = best_pdir;
            }
            else if (mode==2)
            {
              best8x8ref [2][2*block] = best8x8ref [2][2*block+1] = best_fw_ref;
              best8x8pdir[2][2*block] = best8x8pdir[2][2*block+1] = best_pdir;
            }
            else
            {
              best8x8ref [1][0] = best8x8ref [1][1] = best8x8ref [1][2] = best8x8ref [1][3] = best_fw_ref;
              best8x8pdir[1][0] = best8x8pdir[1][1] = best8x8pdir[1][2] = best8x8pdir[1][3] = best_pdir;
            }

            //--- set reference frames and motion vectors ---
            if (mode>1 && block==0)   SetRefAndMotionVectors (block, mode, best_fw_ref, best_pdir);

          } // for (block=0; block<(mode==1?1:2); block++)

          if (cost < min_cost)
          {
            best_mode = mode;
            min_cost  = cost;
          }
        } // if (valid[mode])
      } // for (mode=3; mode>0; mode--)
    }
    else // if (img->type!=INTRA_IMG)
    {
      min_cost = (1<<20);
    }


    if (input->rdopt)
    {
      //===== GET BEST MACROBLOCK MODE =====
      for (ctr16x16=0, min_rdcost=max_rdcost, index=0; index<7; index++)
      {
        mode = mb_mode_table[index];

        //--- for INTER16x16 check all prediction directions ---
        if (mode==1 && bframe)
        {
          best8x8pdir[1][0] = best8x8pdir[1][1] = best8x8pdir[1][2] = best8x8pdir[1][3] = ctr16x16;
          if (ctr16x16 < 2) index--;
          ctr16x16++;
        }

        if (valid[mode])
        {
          if (RDCost_for_macroblocks (lambda_mode, mode, &min_rdcost))
          {
            store_macroblock_parameters (mode);
          }
        }
      }
    }
    else
    {
      if (valid[0] && bframe) // check DIRECT MODE
      {
        cost  = (have_direct?cost_direct:Get_Direct_CostMB (lambda_mode));
        cost -= (int)floor(16*lambda_motion+0.4999);
        if (cost <= min_cost)
        {
          min_cost  = cost;
          best_mode = 0;
        }
      }
      if (valid[I4MB]) // check INTRA4x4
      {
        currMB->cbp = Mode_Decision_for_Intra4x4Macroblock (lambda_mode, &cost);
        if (cost <= min_cost)
        {
          min_cost  = cost;
          best_mode = I4MB;
        }
      }
      if (valid[I16MB]) // check INTRA16x16
      {
        intrapred_luma_2 ();
        cost = find_sad2 (&i16mode);
        if (cost < min_cost)
        {
          best_mode   = I16MB;
          currMB->cbp = dct_luma2 (i16mode);
        }
      }
    }

    if (rerun==0)
    {
      intra1[0] = (currMB->mb_type==I16MB || currMB->b8mode[0]==IBLOCK ? 1 : 0);
      intra1[1] = (currMB->mb_type==I16MB || currMB->b8mode[1]==IBLOCK ? 1 : 0);
      intra1[2] = (currMB->mb_type==I16MB || currMB->b8mode[2]==IBLOCK ? 1 : 0);
      intra1[3] = (currMB->mb_type==I16MB || currMB->b8mode[3]==IBLOCK ? 1 : 0);
    }
  } // for (rerun=0; rerun<runs; rerun++)


  if (input->rdopt)
  {
    set_stored_macroblock_parameters ();
  }
  else
  {
    //===== set parameters for chosen mode =====
    SetModesAndRefframeForBlocks (best_mode);
    if (best_mode==P8x8)
    {
      SetCoeffAndReconstruction8x8 (currMB);
    }
    else
    {
      if (best_mode!=I4MB)
      {
        for (k=0, j=img->block_y+1; j<img->block_y+5; j++)
        for (     i=img->block_x+1; i<img->block_x+5; i++, k++)
        {
          img   ->ipredmode    [i][j] = 0;
          currMB->intra_pred_modes[k] = 0;
        }
        if (best_mode!=I16MB)
        {
          LumaResidualCoding ();
        }
      }
    }
    ChromaResidualCoding (&dummy);
    if (best_mode==I16MB)
    {
      img->i16offset = I16Offset  (currMB->cbp, i16mode);
    }
    SetMotionVectorsMB (currMB, bframe);

    //===== check for COPY mode =====
    if (img->type==INTER_IMG && best_mode==1 && currMB->cbp==0 &&
        refFrArr [img->block_y][img->block_x  ]==0 &&
        tmp_mv[0][img->block_y][img->block_x+4]==0 &&
        tmp_mv[1][img->block_y][img->block_x+4]==0               )
    {
      currMB->mb_type=currMB->b8mode[0]=currMB->b8mode[1]=currMB->b8mode[2]=currMB->b8mode[3]=0;
    }
  }
/*
  if (input->rdopt==2 && !bframe)
  {
    for (j=0 ;j<input->NoOfDecoders; j++)  DeblockMb(img, decs->decY_best[j], NULL);
  }
*/
  //===== init and update number of intra macroblocks =====
  if (img->current_mb_nr==0)                      intras=0;
  if (img->type==INTER_IMG && IS_INTRA(currMB))   intras++;

  //===== Decide if this MB will restrict the reference frames =====
  if (input->RestrictRef==1)
  {
    if (input->rdopt==1)
    {
      refresh_map[2*img->mb_y  ][2*img->mb_x  ] = (intra ? 1 : 0);
      refresh_map[2*img->mb_y  ][2*img->mb_x+1] = (intra ? 1 : 0);
      refresh_map[2*img->mb_y+1][2*img->mb_x  ] = (intra ? 1 : 0);
      refresh_map[2*img->mb_y+1][2*img->mb_x+1] = (intra ? 1 : 0);
    }
    else if (input->rdopt==2)
    {
      refresh_map[2*img->mb_y  ][2*img->mb_x  ] = (intra1[0]==0 && (currMB->mb_type==I16MB || currMB->b8mode[0]==IBLOCK) ? 1 : 0);
      refresh_map[2*img->mb_y  ][2*img->mb_x+1] = (intra1[1]==0 && (currMB->mb_type==I16MB || currMB->b8mode[1]==IBLOCK) ? 1 : 0);
      refresh_map[2*img->mb_y+1][2*img->mb_x  ] = (intra1[2]==0 && (currMB->mb_type==I16MB || currMB->b8mode[2]==IBLOCK) ? 1 : 0);
      refresh_map[2*img->mb_y+1][2*img->mb_x+1] = (intra1[3]==0 && (currMB->mb_type==I16MB || currMB->b8mode[3]==IBLOCK) ? 1 : 0);
    }
  }
  else if (input->RestrictRef==2)
  {
    refresh_map[2*img->mb_y  ][2*img->mb_x  ] = (currMB->mb_type==I16MB || currMB->b8mode[0]==IBLOCK ? 1 : 0);
    refresh_map[2*img->mb_y  ][2*img->mb_x+1] = (currMB->mb_type==I16MB || currMB->b8mode[1]==IBLOCK ? 1 : 0);
    refresh_map[2*img->mb_y+1][2*img->mb_x  ] = (currMB->mb_type==I16MB || currMB->b8mode[2]==IBLOCK ? 1 : 0);
    refresh_map[2*img->mb_y+1][2*img->mb_x+1] = (currMB->mb_type==I16MB || currMB->b8mode[3]==IBLOCK ? 1 : 0);
  }
}

⌨️ 快捷键说明

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