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

📄 mv_competition.c

📁 JM 11.0 KTA 2.1 Source Code
💻 C
📖 第 1 页 / 共 3 页
字号:
/*!
************************************************************************
* \file mv_competition.c
*
* \brief
*    competition based motion vector coding
*
* \author
*  Joel Jung              <joelb.jung@orange-ftgroup.com>           \n
*  Guillaume Laroche      <guillaume.laroche@orange-ftgroup.com>    \n
*
* This software may be used for research purposes only.
* Orange FTR&D would also appreciate that any technical report, conference 
* or journal paper which uses the software includes one of the following references:
*    - J. Jung, G. Laroche, "Competition-Based Scheme for Motion Vector Selection and Coding: new results",
*      VCEG contribution VCEG-???, Geneva, November 2006.
*    - J. Jung, G. Laroche, "Competition-Based Scheme for Motion Vector Selection and Coding",
*      VCEG contribution VCEG-AC06, Klagenfurt, July 2006.
*    - G. Laroche, J. Jung, B. Pesquet-Popescu, "A Spatio Temporal Competing Scheme for the 
*      Rate Distortion Optimized Selection and Coding of Motion Vectors",
*      EUSIPCO'06, Firenza, September 2006.
************************************************************************
*/


// CONFIGURATION
////////////////

// Configuration of the .Cfg file:
// In section KTA STUFF:
//
// MV_Competition        = 0 disabled
//                       = 1 enabled with default parameters for motion vectors of p and b frames and skip
//                       = 2 enabled with user parameters
//
// Predictors_skip, Predictors_MVp, Predictors_MVb are user parameters, describes the predictors that are enabled.
//
// Order of predictors for Predictors_skip: H.264 Median - ExtendedSpatial - a - b - c - 0 - Collocated - Empty
// Order of predictors for Predictors_MVp and MVb: H.264 Median - Empty - a - b - c - 0 - Collocated - Empty 
// Examples:
//          Predictors_skip     = '10100000' : 2 predictors enabled : 'H.264 Median' and 'a'
//          Predictors_skip     = '10000010' : 2 predictors enabled : 'H.264 Median' and 'Colocated'
//          Predictors_skip     = '10000000' : 1 predictor enabled : 'H.264 Median'
//
//          Predictors_MVp      = '10000000' : 1 predictor enabled : 'H.264 Median'
//          Predictors_MVp      = '10000010' : 2 predictors enabled : 'H.264 Median' and 'Colocated'
//

// KNOWN LIMITATIONS
////////////////////
// Enabling 'Empty' predictors or '00000000' configuration will lead to errors.
// Not compatible with:                
//    - interlace coding
//    - RdOpt != 1     

// VERSIONS
//////////
//////////
// 1.0  31 October 06 - first implementation for P and B frames 
// 1.1  9 February 07 - compatibility added with UseFME=3 and other tools
// 1.2  20 June 08    - compatibility added with RDO_Q
//                      compatibility added with AIF=1, 2, 3
//                      compatibility added with 1/8pel
//                      compatibility added with APEC
//                      compatibility added with hierarchical B slices
//                      MVCompetition chroma bug fix (slightly modifies the results)
//                      cleaning - improvements to increase compliance with JM coding rules


#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include "defines.h"
#include "global.h"
#include "image.h"
#include "mb_access.h"
#include "biaridecod.h"
#include "vlc.h"



#ifdef MV_COMPETITION
#include "mv_competition.h"

MV_Competition mv_comp;
extern int assignSE2partition[][SE_MAX_ELEMENTS];

int *****mv_predictors;        // Stores the predictor for each sub-partition and for each predictor  
// predMVXY[block_x][block_y][mode][Ref_Frame][list][prediction number][xy];


/*!
************************************************************************
* \brief
*    Read MVP for Skip Mode
*
************************************************************************
*/
int readPredictorForSkip(struct img_par  *img, struct inp_par *inp)
{
  SyntaxElement currSE;
  Slice *currSlice    = img->currentSlice;
  DataPartition *dP;
  int *partMap        = assignSE2partition[currSlice->dp_mode];
  
  currSE.type = SE_MV_PREDICTOR;
  dP = &(currSlice->partArr[partMap[currSE.type]]);
  currSE.value2 = (mv_comp.nb_mode_for_skip /2) + (mv_comp.nb_mode_for_skip % 2);
  
  if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
  {
    currSE.value1 = u_v(currSE.value2, "predictor for the SKIP mode", dP->bitstream);  
  }
  else
  {  
    currSE.reading = read_MV_predictor_CABAC;
    dP->readSyntaxElement(&currSE,img,inp,dP);
  }
  
  return currSE.value1;
}

/*!
************************************************************************
* \brief
*    Read MVP for Skip Mode
*
************************************************************************
*/
int readPredictorMV(struct img_par  *img, struct inp_par *inp)
{
  SyntaxElement currSE;
  Slice *currSlice    = img->currentSlice;
  DataPartition *dP;
  int *partMap        = assignSE2partition[currSlice->dp_mode];
  int maxmode=0;
  
  currSE.type = SE_MV_PREDICTOR;
  dP = &(currSlice->partArr[partMap[currSE.type]]);
  if(img->type == P_SLICE)
  {
    maxmode = mv_comp.nb_mode_for_mvp;
    currSE.value2 = (mv_comp.nb_mode_for_mvp / 2) + (mv_comp.nb_mode_for_mvp % 2);
  }
  else if (img->type == B_SLICE)
  {
    maxmode = mv_comp.nb_mode_for_mvb;
    currSE.value2 = (mv_comp.nb_mode_for_mvb / 2) + (mv_comp.nb_mode_for_mvb % 2);
  }
  
  if(maxmode > 1)
  {
    if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
    {
      currSE.value1 = u_v(currSE.value2, "predictor MV", dP->bitstream);  
    }
    else
    {  
      currSE.reading = read_MV_predictor_CABAC;
      dP->readSyntaxElement(&currSE,img,inp,dP);
    }
  }else currSE.value1 = 0;
  
  //  if(img->type == B_SLICE) printf("MB%i\t%i\n",img->current_mb_nr,currSE.value1);
  return currSE.value1;
}
/*!
************************************************************************
* \brief
*    Read Motion vector predictor in H.264 bitstream
*
************************************************************************
*/
void read_MV_predictor_CABAC( SyntaxElement *se,
                             struct inp_par *inp,
                             struct img_par *img,
                             DecodingEnvironmentPtr dep_dp)
{
  Macroblock          *currMB = &img->mb_data[img->current_mb_nr];
  int act_ctx = 0;
  MotionInfoContexts *ctx = (img->currentSlice)->mot_ctx;
  int nb_symbol;
  int two_power = 2;
  
  if(se->value2 != 0)
  {
    if(currMB->mb_type == 0)
      se->value1 = biari_decode_symbol(dep_dp, &ctx->mv_predictor_skip_contexts[act_ctx]);
    else 
      if(img->type == P_SLICE)
        se->value1 = biari_decode_symbol(dep_dp, &ctx->mv_predictor_mvp_contexts[act_ctx]);
      else //B_SLICE
        se->value1 = biari_decode_symbol(dep_dp, &ctx->mv_predictor_mvb_contexts[act_ctx]);
      
      nb_symbol = se->value2-1;
      
      while(nb_symbol != 0)
      {
        if(currMB->mb_type == 0)
          se->value1 = (se->value1) + (two_power * biari_decode_symbol(dep_dp, &ctx->mv_predictor_skip_contexts[act_ctx]));
        else 
          if(img->type == P_SLICE)
            se->value1 = (se->value1) + (two_power * biari_decode_symbol(dep_dp, &ctx->mv_predictor_mvp_contexts[act_ctx]));
          else //B_SLICE
            se->value1 = (se->value1) + (two_power * biari_decode_symbol(dep_dp, &ctx->mv_predictor_mvb_contexts[act_ctx]));
          
          nb_symbol--;
          two_power = two_power *2;
      }  
  }
  
}


void reinit_MV_Competition()
{
  int i;
  
  mv_comp.nb_mode_for_skip = 0;
  mv_comp.nb_mode_for_mvp = 0;
  mv_comp.nb_mode_for_mvb = 0;
  
  for (i=0; i<MAX_MV_PREDICTOR; i++)
  {
    if (mv_comp.predictors_skip[i] == 1)
    {
      mv_comp.predictor_for_skip[mv_comp.nb_mode_for_skip++]=i;
    }
    if (mv_comp.predictors_mvp[i] == 1)
    {
      mv_comp.predictor_for_mvp[mv_comp.nb_mode_for_mvp++]=i;
    }
    if (mv_comp.predictors_mvb[i] == 1)
    {
      mv_comp.predictor_for_mvb[mv_comp.nb_mode_for_mvb++]=i;
    }
  }
  if(img->type ==  B_SLICE)
    if( type_of_the_previous_frame != B_SLICE)  
      successive_Bframe = (listX[LIST_1][0]->poc/2 - listX[LIST_0][0]->poc/2)/(dec_picture->frame_poc/2-listX[LIST_0][0]->poc/2)-1;
    
    type_of_the_previous_frame = img->type;
}

void init_MV_Competition()
{
  int i,j, k, l;
  
  mv_comp.predictor_for_skip = (int *) malloc(sizeof(int) * MAX_MV_PREDICTOR);
  mv_comp.predictor_for_mvp  = (int *) malloc(sizeof(int) * MAX_MV_PREDICTOR);
  mv_comp.predictor_for_mvb  = (int *) malloc(sizeof(int) * MAX_MV_PREDICTOR);
  
  mv_predictors = (int*****)malloc(4*sizeof(int****)) ;
  for(l=0;l<4;l++)
  {
    (mv_predictors)[l] = (int****)malloc(4*sizeof(int***)) ;
    for(k=0;k<4;k++)
    {
      (mv_predictors)[l][k] = (int***)malloc(MAXMODE*sizeof(int**)) ;
      for(j=0;j<(MAXMODE);j++)
      {
        mv_predictors[l][k][j] = (int**)malloc(15*sizeof(int*)) ;                     //int predMVXY[block_x][block_y][MAXMODE][15][2];  
        for (i=0; i<15; i++)
        {
          (mv_predictors)[l][k][j][i] = (int*)malloc(2*sizeof(int));
        } 
      }
    }
  }
}

void init_MV_Competition_mv_previous_tab()
{
  int i,j, k;
  
  if(successive_Bframe > 1)
  { 
    if(mv_previous_B_frame == NULL)
    {
      mv_previous_B_frame = (short****)malloc(2*sizeof(short***));
      for (k=0; k<2; k++)
      {
        mv_previous_B_frame[k] = (short***)malloc((img->height/4)*sizeof(short**));
        for(i=0;i<img->height/4;i+=1)
        {
          mv_previous_B_frame[k][i] = (short**)malloc((img->width/4)*sizeof(short*));
          for(j=0;j<img->width/4;j+=1)
          {
            mv_previous_B_frame[k][i][j] = (short*)malloc(2*sizeof(short));
          }
        }
      }
    }
    if(ref_idx_previous_B_frame == NULL)
    {
      ref_idx_previous_B_frame = (char***)malloc(2*sizeof(char**));
      for (k=0; k<2; k++)
      {
        ref_idx_previous_B_frame[k] = (char**)malloc((img->height/4)*sizeof(char*));
        for(i=0;i<img->height/4;i+=1)
        {
          ref_idx_previous_B_frame[k][i] = (char*)malloc((img->width/4)*sizeof(char));
        }
      }
    }
  }
}
void close_MV_Competition()
{
  int i, j, k, l;
  free (mv_comp.predictor_for_skip);
  free (mv_comp.predictor_for_mvp);
  free (mv_comp.predictor_for_mvb);
  
  for(l=0;l<4;l++)
  {
    for(k=0;k<4;k++)
    {
      for(j=0;j<(MAXMODE);j++)
      {
        for (i=0; i<15; i++)
        {
          free(mv_predictors[l][k][j][i]);
        }
        free(mv_predictors[l][k][j]);
      }
      free(mv_predictors[l][k]);
    }
    free(mv_predictors[l]);
  }
  free(mv_predictors);
  
  if(successive_Bframe > 1)
  { 
    for (k=0; k<2; k++)
    {
      for(i=0;i<img->height/4;i+=1)
      {
        for(j=0;j<img->width/4;j+=1)
        {
          free(mv_previous_B_frame[k][i][j]);
        }
        free(mv_previous_B_frame[k][i]);
      }
      free(mv_previous_B_frame[k]);
    }
    free(mv_previous_B_frame);
    
    
    for (k=0; k<2; k++)
    {
      for(i=0;i<img->height/4;i+=1)
      {
        free(ref_idx_previous_B_frame[k][i]);
      }
      free(ref_idx_previous_B_frame[k]);
    }
    free(ref_idx_previous_B_frame);
    
  }
}

short collocated_mv_available(int pos_y, int pos_x, int list)
{
  short return_val = TRUE;
  
  if (listX[list][0]->ref_idx[0][pos_y*4][pos_x*4] == -1)  // Collocated block in INTRA
  {
    
    return_val = FALSE;
  }
  
  return (return_val);
}

short collocated_mv_available_previous_B_frame(int pos_y, int pos_x, int list)
{
  short return_val = TRUE;
  
  // Macrobloc belongs to the picture ?
  //if ((pos_v < 0) || (pos_h < 0) || (pos_v>=(img->height/16)) || (pos_h>=(img->width/16)))
  //  return_val = 0;
  
  // Macrobloc has a motion vector ?
  //else 
  //  if (coding_modes_previous_frame[img->current_mb_nr * 4] >= 9)
  if (ref_idx_previous_B_frame[list][pos_y*4][pos_x*4] == -1)  // Collocated block in INTRA
  {
    return_val = FALSE;
  }
  
  return (return_val);
}

short read_index_for_skip_mode()
{
  short mv_x_ref, mv_y_ref;
  short i;
  short return_val = FALSE;      // Assumes it can be guessed
  short nb_of_available = 0;    // Number of modes available
  
  mv_x_ref = mv_comp.mv_pred_skip[0][0];
  mv_y_ref = mv_comp.mv_pred_skip[0][1];
  
  // If all the mv_skip_jj (for all modes except 'best_mode_skip' are equal to NOT_AVAILABLE
  // then the mode can be guessed
  
  
  for (i=0; i<mv_comp.nb_mode_for_skip; i++)
  {
    //Check if among all modes enabled, more than one is AVAILABLE 
    if (mv_comp.mv_pred_skip[i][0] != NOT_AVAILABLE) 
      nb_of_available++;
  }
  
  if (nb_of_available == 1)
    return_val = FALSE;
  else
  {
    for (i=1; i<mv_comp.nb_mode_for_skip; i++)
    {
      if ((mv_comp.mv_pred_skip[i][0] != mv_x_ref) 
        || (mv_comp.mv_pred_skip[i][1] != mv_y_ref))
        
        return_val = TRUE;    // One of the component for one prediction is different
      // We can return 0, the mode cannot be guessed
    }
  }
  
  return (return_val);
}

void SetMotionVectorPredictor_Competition (struct img_par  *img,
                                           struct inp_par *inp,
                                           short           *pmv_x,
                                           short           *pmv_y,
                                           char            ref_frame,
                                           byte            list,

⌨️ 快捷键说明

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