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

📄 rdopt.c

📁 JM 11.0 KTA 2.1 Source Code
💻 C
📖 第 1 页 / 共 5 页
字号:

/*!
***************************************************************************
* \file rdopt.c
*
* \brief
*    Rate-Distortion optimized mode decision
*
* \author
*    - Heiko Schwarz              <hschwarz@hhi.de>
*    - Valeri George              <george@hhi.de>
*    - Lowell Winger              <lwinger@lsil.com>
*    - Alexis Michael Tourapis    <alexismt@ieee.org>
* \date
*    12. April 2001
**************************************************************************
*/

#include <stdlib.h>
#include <math.h>
#include <assert.h>
#include <limits.h>
#include <memory.h>
#include <string.h>

#include "global.h"

#include "rdopt_coding_state.h"
#include "memalloc.h"
#include "mb_access.h"
#include "elements.h"
#include "intrarefresh.h"
#include "image.h"
#include "transform8x8.h"
#include "cabac.h"   
#include "vlc.h"
#include "fast_me.h"
#include "ratectl.h"            // head file for rate control
#include "mode_decision.h"
#include "fmo.h"
#define KS_MV
#ifdef ADAPTIVE_FILTER
#include "adaptive_filter.h"
#endif

#ifdef MV_COMPETITION
#include "mv_competition.h"
extern MV_Competition mv_comp;
extern int skip_mode;
#endif

#ifdef RDO_Q
int saved_cbp, saved_I16cbp, saved_I8cbp;
int saved_i16mode;
int saved_cofAC[4][4][2][65];
int saved_I16cofAC[4][4][2][65], saved_I8cofAC[4][4][2][65];
int saved_cofDC[3][2][65];
imgpel saved_enc_picture_imgY[16][16], saved_I16enc_picture_imgY[16][16], saved_I8enc_picture_imgY[16][16];
imgpel saved_img_mpr[16][16], saved_I8img_mpr[16][16];
#endif
#ifdef USE_INTRA_MDDT
extern long quant_stat_rd[16];
extern long quant_stat_rd16x16[256];

int   bestCofAC16[2][16*17];
#endif 


//Rate control

int QP,QP2;
int DELTA_QP,DELTA_QP2;

imgpel pred[16][16];

#define FASTMODE 1
//#define RESET_STATE

extern const int LEVELMVLIMIT[17][6];
extern int   QP2QUANT[40];

extern short OffsetList4x4[15][16];
extern short OffsetList8x8[5][64];
extern const int OffsetBits;

imgpel   rec_mbY[16][16], rec_mbU[16][16], rec_mbV[16][16];    // reconstruction values

int lrec_rec[16][16],lrec_rec_U[16][16],lrec_rec_V[16][16]; // store the transf. and quantized coefficients for SP frames

RD_8x8DATA tr4x4, tr8x8;

#ifdef ADAPTIVE_FD_SD_CODING
int   best_SD_or_FD           [2][2];
int   best_SD_or_FD_t8x8;    
int   best_quantizer_indices  [16][16];
int   best_SD_Coding_on_off;
#endif

int   bestInterFAdjust4x4[16][16], bestIntraFAdjust4x4[16][16];
int   bestInterFAdjust8x8[16][16], bestIntraFAdjust8x8[16][16];
int   bestInterFAdjust4x4Cr[2][16][16], bestIntraFAdjust4x4Cr[2][16][16];
int   fadjust8x8[16][16], fadjust4x4[16][16], fadjust4x4Cr[2][16][16], fadjust8x8Cr[2][16][16];    

#ifdef ADAPTIVE_FD_SD_CODING
float adjust_adaptive_f_spatial_domain_8x8;
float adjust_adaptive_f_spatial_domain_4x4;
float best_adjust_adaptive_f_spatial_domain_8x8;
float best_adjust_adaptive_f_spatial_domain_4x4;
#endif

int   ****cofAC=NULL, ****cofAC8x8=NULL;        // [8x8block][4x4block][level/run][scan_pos]
int   ***cofDC=NULL;                       // [yuv][level/run][scan_pos]
int   **cofAC4x4=NULL, ****cofAC4x4intern=NULL; // [level/run][scan_pos]
int   cbp, cbp8x8, cnt_nonz_8x8;
int64 cbp_blk;
int   cbp_blk8x8;
char  frefframe[4][4], brefframe[4][4];
int   b8mode[4], b8pdir[4];
short best8x8mode [4];                // [block]
short best8x8pdir  [MAXMODE][4];       // [mode][block]
short best8x8fwref [MAXMODE][4];       // [mode][block]
short best8x8bwref [MAXMODE][4];       // [mode][block]

#ifdef ADAPTIVE_QUANTIZATION
int   best_mb_iaqms_idx;
#endif
CSptr cs_mb=NULL, cs_b8=NULL, cs_cm=NULL, cs_imb=NULL, cs_ib8=NULL, cs_ib4=NULL, cs_pc=NULL;
#ifdef USE_INTRA_MDDT
CSptr cs_i16 = NULL;
#endif 
int   best_c_imode;
int   best_i16offset;
short best_mode;
short  bi_pred_me;

//mixed transform sizes definitions
int   luma_transform_size_8x8_flag;

short all_mv8x8[2][2][4][4][2];       //[8x8_data/temp_data][LIST][block_x][block_y][MVx/MVy]
short pred_mv8x8[2][2][4][4][2];

int   ****cofAC_8x8ts = NULL;        // [8x8block][4x4block][level/run][scan_pos]

int64    cbp_blk8_8x8ts;
int      cbp8_8x8ts;
int      cost8_8x8ts;
int      cnt_nonz8_8x8ts;

#ifdef RDO_Q
imgpel rec_mbY_intra[4][4][16][16], rec_mbU_intra[4][4][16][16], rec_mbV_intra[4][4][16][16];    // reconstruction values
int   lrec_rec_intra[4][4][16][16],lrec_rec_U_intra[4][4][16][16],lrec_rec_V_intra[4][4][16][16]; // store the transf. and quantized coefficients for SP frames
int   i16offset_intra[4][4];
int   cbp_intra[4][4];
int64 cbp_blk_intra[4][4];
double rdcost_intra[4][4];
int   cofAC_intra[4][4][12][4][2][65];
int   cofDC_intra[4][4][3][2][65];                       // [yuv][level/run][scan_pos]
char   b4_ipredmode_intra[4][4][16];
char   b8_ipredmode8x8_intra[4][4][4][4];
char   b4_ipredmode_mb_intra[4][4][16];
char   b8_ipredmode8x8_mb_intra[4][4][16];
#define IS_INTRA_MODE(mode)  ((mode==I4MB)||(mode==I8MB)||(mode==I16MB)||(mode==IPCM))
#define IS_INTER_SLICE(type) ((type) == B_SLICE || (type) == P_SLICE)
#endif

void StoreMV8x8(int dir);
void RestoreMV8x8(int dir);
// end of mixed transform sizes definitions

//Adaptive Rounding update function
void update_offset_params(int mode, int luma_transform_size_8x8_flag);

// Residue Color Transform
int   cofAC4x4_chroma[2][2][18];
int   rec_resG_8x8[16][16], resTrans_R_8x8[16][16], resTrans_B_8x8[16][16];
int   rec_resG_8x8ts[16][16], resTrans_R_8x8ts[16][16], resTrans_B_8x8ts[16][16];
int   mprRGB_8x8[3][16][16], mprRGB_8x8ts[3][16][16];
char  b4_ipredmode[16], b4_intra_pred_modes[16];

/*!
************************************************************************
* \brief
*    delete structure for RD-optimized mode decision
************************************************************************
*/
void clear_rdopt ()
{
  free_mem_DCcoeff (cofDC);
  free_mem_ACcoeff (cofAC);
  free_mem_ACcoeff (cofAC8x8);
  free_mem_ACcoeff (cofAC4x4intern);
  
  if (input->Transform8x8Mode)
  {
    free_mem_ACcoeff (cofAC_8x8ts);
  }
  
  // structure for saving the coding state
  delete_coding_state (cs_mb);
  delete_coding_state (cs_b8);
  delete_coding_state (cs_cm);
  delete_coding_state (cs_imb);
  delete_coding_state (cs_ib8);
  delete_coding_state (cs_ib4);
  delete_coding_state (cs_pc);
#ifdef USE_INTRA_MDDT
  delete_coding_state (cs_i16);
#endif 
  
#ifdef ADAPTIVE_FD_SD_CODING
  delete_coding_state (cs_spatial_domain_coding);
  delete_coding_state (cs_spatial_domain_coding_rd_opt);
  delete_coding_state (cs_slice_coding);
  delete_coding_state (cs_slice_coding1);
#endif
  
}


/*!
************************************************************************
* \brief
*    create structure for RD-optimized mode decision
************************************************************************
*/
void init_rdopt ()
{
  rdopt = NULL;
  
  get_mem_DCcoeff (&cofDC);
  get_mem_ACcoeff (&cofAC);
  get_mem_ACcoeff (&cofAC8x8);
  get_mem_ACcoeff (&cofAC4x4intern);
  cofAC4x4 = cofAC4x4intern[0][0];
  
  if (input->Transform8x8Mode)
  {
    get_mem_ACcoeff (&cofAC_8x8ts);
  }
  
  // structure for saving the coding state
  cs_mb  = create_coding_state ();
  cs_b8  = create_coding_state ();
  cs_cm  = create_coding_state ();
  cs_imb = create_coding_state ();
  cs_ib8 = create_coding_state ();
  cs_ib4 = create_coding_state ();
  cs_pc  = create_coding_state ();
#ifdef USE_INTRA_MDDT
  cs_i16  = create_coding_state ();
#endif 
  
#ifdef ADAPTIVE_FD_SD_CODING
  cs_spatial_domain_coding                = create_coding_state ();
  cs_spatial_domain_coding_rd_opt         = create_coding_state ();
  cs_slice_coding                         = create_coding_state ();
  cs_slice_coding1                        = create_coding_state ();
#endif
  
}



/*!
*************************************************************************************
* \brief
*    Updates the pixel map that shows, which reference frames are reliable for
*    each MB-area of the picture.
*
* \note
*    The new values of the pixel_map are taken from the temporary buffer refresh_map
*
*************************************************************************************
*/
void UpdatePixelMap()
{
  int mx,my,y,x,i,j;
  if (img->type==I_SLICE)
  {
    for (y=0; y<img->height; y++)
      for (x=0; x<img->width; x++)
      {
        pixel_map[y][x]=1;
      }
  }
  else
  {
    for (my=0; my<img->height >> 3; my++)
      for (mx=0; mx<img->width >> 3;  mx++)
      {
        j = my*8 + 8;
        i = mx*8 + 8;
        if (refresh_map[my][mx])
        {
          for (y=my*8; y<j; y++)
            for (x=mx*8; x<i; x++)  
              pixel_map[y][x] = 1;
        }
        else
        {
          for (y=my*8; y<j; y++)
            for (x=mx*8; x<i; x++)  
              pixel_map[y][x] = min(pixel_map[y][x] + 1, input->num_ref_frames+1);
        }
      }
  }
}

/*!
*************************************************************************************
* \brief
*    Checks if a given reference frame is reliable for the current
*    macroblock, given the motion vectors that the motion search has
*    returned.
*
* \return
*    If the return value is 1, the reference frame is reliable. If it
*    is 0, then it is not reliable.
*
* \note
*    A specific area in each reference frame is assumed to be unreliable
*    if the same area has been intra-refreshed in a subsequent frame.
*    The information about intra-refreshed areas is kept in the pixel_map.
*
*************************************************************************************
*/
int CheckReliabilityOfRef (int block, int list_idx, int ref, int mode)
{
  int y,x, block_y, block_x, dy, dx, y_pos, x_pos, yy, xx, pres_x, pres_y;
  int maxold_x  = img->width-1;
  int maxold_y  = img->height-1;
  int ref_frame = ref+1;
  
  int by0 = (mode>=4?2*(block >> 1):mode==2?2*block:0);
  int by1 = by0 + (mode>=4||mode==2?2:4);
  int bx0 = (mode>=4?2*(block & 0x01):mode==3?2*block:0);
  int bx1 = bx0 + (mode>=4||mode==3?2:4);
  
  for (block_y=by0; block_y<by1; block_y++)
  {
    for (block_x=bx0; block_x<bx1; block_x++)
    {
      y_pos  = img->all_mv[block_y][block_x][list_idx][ref][mode][1];
      y_pos += (img->block_y + block_y) * BLOCK_SIZE * 4;
      x_pos  = img->all_mv[block_y][block_x][list_idx][ref][mode][0];
      x_pos += (img->block_x + block_x) * BLOCK_SIZE * 4;
      
      /* Here we specify which pixels of the reference frame influence
      the reference values and check their reliability. This is
      based on the function Get_Reference_Pixel */
      
      dy = y_pos & 3;
      dx = x_pos & 3;
      
      y_pos = (y_pos-dy) >> 2;
      x_pos = (x_pos-dx) >> 2;
      
      if (dy==0 && dx==0) //full-pel
      {
        for (y=y_pos ; y < y_pos + BLOCK_SIZE ; y++)
          for (x=x_pos ; x < x_pos + BLOCK_SIZE ; x++)
            if (pixel_map[max(0,min(maxold_y,y))][max(0,min(maxold_x,x))] < ref_frame)
              return 0;
      }
      else  /* other positions */
      {
        if (dy == 0)
        {
          for (y = y_pos ; y < y_pos + BLOCK_SIZE ; y++)
          {
            pres_y = max(0,min(maxold_y,y));
            for (x = x_pos ; x < x_pos + BLOCK_SIZE ; x++)
            {
              for(xx = -2 ; xx < 4 ; xx++)
              {
                pres_x = max(0, min( maxold_x, x + xx));
                if (pixel_map[pres_y][pres_x] < ref_frame)
                  return 0;
              }
            }
          }
        }        
        else if (dx == 0)
        {
          for (y = y_pos ; y < y_pos + BLOCK_SIZE ; y++)
            for (x=x_pos ; x < x_pos + BLOCK_SIZE ; x++)
            {
              pres_x = max(0,min(maxold_x,x));
              for(yy=-2;yy<4;yy++) 
              {
                pres_y = max(0,min(maxold_y, yy + y));
                if (pixel_map[pres_y][pres_x] < ref_frame)
                  return 0;
              }
            }

⌨️ 快捷键说明

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