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

📄 mv_competition.c

📁 JM 11.0 KTA 2.1 Source Code
💻 C
📖 第 1 页 / 共 2 页
字号:
/*!
************************************************************************
* \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 "global.h"
#include "mbuffer.h"
#include "mb_access.h"
#include "cabac.h"
#include "string.h"
#include "vlc.h"
#include "fmo.h"
#include "fast_me.h"
#include "image.h"

#ifdef MV_COMPETITION
#include "mv_competition.h"

int skip_mode;
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];
int ******send_index_mv_prediction;        // int predModeMV2[mode][10][list][4][4][MAX_MODEPREDMV+1]; 
int *****predModeMV;          // contient les modes de prediction des predicteur MV [mode][ref][list][i][j]; int predModeMV[10][18*22];
int  *ranking;            //int  ranking[MAX_VAL];
int MAX_VAL ;    

extern int *mvbits;
extern int *assignSE2partition[2];
extern void SetMotionVectorPredictor (short  pmv[2],
                                      char   **refPic,
                                      short  ***tmp_mv,
                                      short  ref_frame,
                                      int    list,
                                      int    block_x,
                                      int    block_y,
                                      int    blockshape_x,
                                      int    blockshape_y);

MV_Competition mv_comp;



/*! 
*************************************************************************************
* \brief
*    initialization of motion vector competition arrays
*
* \param 
*    
*
* \return
*    
*************************************************************************************
*/

void init_MV_Competition()
{
  int l,n,m,i;
  int  j, k=0;
  int nLength;
  
  nLength = strlen(input->predictors_skip)-2;
  
  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);
  
  if (input->mv_competition == 0)
  {
    mv_comp.nb_mode_for_skip = 1;
    mv_comp.nb_mode_for_mvp  = 1;
    mv_comp.nb_mode_for_mvb  = 1;
    
    mv_comp.predictor_for_skip[0] = PRED_H264_MEDIAN;
    mv_comp.predictor_for_mvp[0]  = PRED_H264_MEDIAN;
    mv_comp.predictor_for_mvb[0]  = PRED_H264_MEDIAN;
  }
  else if (input->mv_competition == 1)
  {
    mv_comp.nb_mode_for_skip = 2;
    mv_comp.nb_mode_for_mvp  = 2;
    mv_comp.nb_mode_for_mvb  = 2;
    
    for (i=1; i<8; i++)
    {
      mv_comp.predictor_for_skip[i] = 0;
      mv_comp.predictor_for_mvp[i]  = 0;
      mv_comp.predictor_for_mvb[i]  = 0;
    }
    
    mv_comp.predictor_for_skip[0] = PRED_EXTENDEDSPATIAL;
    mv_comp.predictor_for_mvp[0]  = PRED_H264_MEDIAN;
    mv_comp.predictor_for_mvb[0]  = PRED_H264_MEDIAN;
    mv_comp.predictor_for_skip[1] = PRED_A;
    mv_comp.predictor_for_mvp[1]  = PRED_COLOCATED;
    mv_comp.predictor_for_mvb[1]  = PRED_COLOCATED;
  }
  else
  {
    mv_comp.nb_mode_for_skip = 0;
    mv_comp.nb_mode_for_mvp  = 0;
    mv_comp.nb_mode_for_mvb  = 0;
    
    // Check the number of predictors + enabled predictors for skip, motion vectors for P and B frames
    for(j=1;j<nLength+1;j++)
    {
      switch (input->predictors_skip[j])
      {
      case '1':
        mv_comp.predictor_for_skip[mv_comp.nb_mode_for_skip++] = j-1;
        break;
      case '0':
        break;
      default:
        snprintf(errortext, ET_SIZE, "Invalid Predictors_skip parameter.");
        error (errortext, 400);
        break;
      }
      
      switch (input->predictors_mvp[j])
      {
      case '1':
        mv_comp.predictor_for_mvp[mv_comp.nb_mode_for_mvp++] = j-1;
        break;
      case '0':
        break;
      default:
        snprintf(errortext, ET_SIZE, "Invalid Predictors_mvp parameter.");
        error (errortext, 400);
        break;
      }
      
      switch (input->predictors_mvb[j])
      {
      case '1':
        mv_comp.predictor_for_mvb[mv_comp.nb_mode_for_mvb++] = j-1;
        break;
      case '0':
        break;
      default:
        snprintf(errortext, ET_SIZE, "Invalid Predictors_mvb parameter.");
        error (errortext, 400);
        break;
      }
      
    }
  }
  
  mv_comp.mv_pred_skip = (int**) malloc(mv_comp.nb_mode_for_skip * sizeof(int*));  
  for(j=0;j<(mv_comp.nb_mode_for_skip);j++)
  {
    mv_comp.mv_pred_skip[j] = (int*) malloc(2 * sizeof(int)) ;             
  }
  
  
  mv_predictors = (int*******)malloc(4*sizeof(int******)) ;              //block_x
  for(l=0; l<4; l++)
  {
    (mv_predictors)[l] = (int******)malloc(4*sizeof(int*****)) ;            //block_y
    for(k=0; k<4; k++)
    {
      (mv_predictors)[l][k] = (int*****)malloc(MAXMODE*sizeof(int****)) ;      //mode
      for(j=0; j<(MAXMODE); j++)
      {
        (mv_predictors)[l][k][j]=(int****)malloc((input->num_ref_frames)*sizeof(int***)); //REF FRAME
        for(n=0; n<input->num_ref_frames; n++)
        {
          (mv_predictors)[l][k][j][n] = (int***)malloc(2*sizeof(int**)) ;      //LIST_0, LIST_1
          for(m=0; m<(2); m++)
          {
            (mv_predictors)[l][k][j][n][m] = (int**)malloc(15*sizeof(int*)) ;
            for (i=0; i<15; i++)
            {
              (mv_predictors)[l][k][j][n][m][i] = (int*)malloc(2*sizeof(int));  //x,y
            }
          }
        }
      }
    }
  }
  
  send_index_mv_prediction = (int******)malloc(MAXMODE*sizeof(int*****));
  
  for (k=0; k<MAXMODE; k++)
  {
    (send_index_mv_prediction)[k] = (int*****)malloc(img->num_ref_frames*sizeof(int****)) ;   // int predModeMV2[MAXMODE][10][list][18][22][MAX_MODEPREDMV+1]; 
    for (i=0; i<img->num_ref_frames; i++)
    {
      (send_index_mv_prediction)[k][i] = (int****)malloc((2)*sizeof(int***)); 
      for (m=0; m<2; m++)
      {
        (send_index_mv_prediction)[k][i][m] = (int***)malloc(4*sizeof(int**)); 
        for(l=0; l<4; l++)
        {
          (send_index_mv_prediction)[k][i][m][l] = (int**)malloc(4*sizeof(int*)); 
          for(j=0; j<4; j++)
            (send_index_mv_prediction)[k][i][m][l][j] = (int*)malloc((max(mv_comp.nb_mode_for_mvp,mv_comp.nb_mode_for_mvb)+1)*sizeof(int));
        }
      }
    }
  }
  
  predModeMV= (int*****)malloc(MAXMODE*sizeof(int****)) ;
  for(j=0; j<(MAXMODE); j++)
  {
    (predModeMV)[j]= (int****)malloc(img->num_ref_frames*sizeof(int***)) ;       //int predModeMV[MAXMODE][10][list][18][22];
    for (i=0; i<img->num_ref_frames; i++)
    {
      (predModeMV)[j][i] = (int***)malloc(2*sizeof(int**));
      for (m=0; m<2; m++)
      {
        (predModeMV)[j][i][m] = (int**)malloc(4*sizeof(int*));
        for (k=0; k<4; k++)
          (predModeMV)[j][i][m][k] = (int*)malloc(4*sizeof(int));
      }
    }
  }
  
  if(input->successive_Bframe > 1)
  {
    mv_previous_B_frame = (short****)malloc(2*sizeof(short***));
    for (m=0; m<2; m++)
    {
      mv_previous_B_frame[m] = (short***)malloc((img->height/4)*sizeof(short**));
      for(i=0;i<img->height/4;i+=1)
      {
        mv_previous_B_frame[m][i] = (short**)malloc((img->width/4)*sizeof(short*));
        for(j=0;j<img->width/4;j+=1)
          mv_previous_B_frame[m][i][j] = (short*)malloc(2*sizeof(short));
      }
    }
    
    ref_idx_previous_B_frame = (char***)malloc(2*sizeof(char**));
    for (m=0; m<2; m++)
    {
      ref_idx_previous_B_frame[m] = (char**)malloc((img->height/4)*sizeof(char*));
      for(i=0;i<img->height/4;i+=1)
      {
        ref_idx_previous_B_frame[m][i] = (char*)malloc((img->width/4)*sizeof(char));
      }
    }
  }
  
  ranking =(int*)malloc (MAX_VAL*sizeof(int));                       //int  ranking[MAX_VAL];
  MAX_VAL=  max(mv_comp.nb_mode_for_mvp,mv_comp.nb_mode_for_mvb)*4;
  }
  
  
  /*! 
  *************************************************************************************
  * \brief
  *    free motion vector competition arrays
  *
  * \param 
  *    
  *
  * \return
  *    
  *************************************************************************************
  */
  
  void close_MV_Competition ()
  {
    int i, j, k, l, m, n;
    for(j=0;j<(mv_comp.nb_mode_for_skip);j++)
      free(mv_comp.mv_pred_skip[j]);
    
    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(n=0; n<input->num_ref_frames; n++)
          {
            for(m=0; m<(2); m++)
            {
              for (i=0; i<15; i++)
                free(mv_predictors[l][k][j][n][m][i]);
              
              free(mv_predictors[l][k][j][n][m]);
            }
            free(mv_predictors[l][k][j][n]);
          }
          free(mv_predictors[l][k][j]);
        }
        free(mv_predictors[l][k]);
      }
      free(mv_predictors[l]);
    }
    free(mv_predictors);
    
    for (k=0; k<MAXMODE; k++)
    {
      for (i=0; i<img->num_ref_frames; i++)
      {
        for (m=0; m<2; m++)
        {
          for(l=0; l<4; l++)
          {
            for(j=0; j<4; j++)
              free(send_index_mv_prediction[k][i][m][l][j]);
            free(send_index_mv_prediction[k][i][m][l]);
          }
          free(send_index_mv_prediction[k][i][m]);
        }
        free(send_index_mv_prediction[k][i]);
      }
      free(send_index_mv_prediction[k]);
    }
    free(send_index_mv_prediction);
    
    for(j=0; j<(MAXMODE); j++)
    {
      for (i=0; i<img->num_ref_frames; i++)
      {
        for (m=0; m<2; m++)
        {
          for (k=0; k<4; k++)
            free(predModeMV[j][i][m][k]);
          free(predModeMV[j][i][m]);
        }
        free(predModeMV[j][i]);
      }
      free(predModeMV[j]);
    }
    free(predModeMV);
    
    if(input->successive_Bframe > 1)
    {
      for (m=0; m<2; m++)
      {
        for(i=0;i<img->height/4;i+=1)
        {
          for(j=0;j<img->width/4;j+=1)
          {
            free(mv_previous_B_frame[m][i][j]);
          }
          free(mv_previous_B_frame[m][i]);
        }
        free(mv_previous_B_frame[m]);
      }
      free(mv_previous_B_frame);
      
      for (m=0; m<2; m++)
      {
        for(i=0;i<img->height/4;i+=1)
        {
          free(ref_idx_previous_B_frame[m][i]);
        }
        free(ref_idx_previous_B_frame[m]);
      }
      free(ref_idx_previous_B_frame);
    }
    free(ranking);
  }
  
  /*! 
  *************************************************************************************
  * \brief
  *    writes the index of the selected motion vector predictor for the skip mode
  *
  * \param 
  *    
  *
  * \return int
  *    
  *************************************************************************************
  */
  
  int write_predictor_index_for_skip_mode()
  {
    int            rate       = 0;
    Macroblock*     currMB     = &img->mb_data[img->current_mb_nr];
    
    if (input->symbol_mode == CABAC)
    { currMB->send_index_predictor_skip = send_index_for_skip_prediction(currMB->best_predictor_for_skip);
    if (currMB->send_index_predictor_skip == TRUE)
      rate += writeMotionVectorPredictorSKIP(currMB->best_predictor_for_skip);
    }
    else
    {
      int i=0;
      Macroblock*     prevMB;
      int cod_counter;
      
      if((FmoGetNextMBNr(img->current_mb_nr) == -1)&&(currMB->mb_type == 0))
        cod_counter = img->cod_counter -1;
      else
        cod_counter = img->cod_counter;
      for( i = cod_counter ; i > 0 ; i--)
      {
        prevMB = &img->mb_data[img->current_mb_nr-i];
        
        if(prevMB->send_index_predictor_skip)
          rate += writeMotionVectorPredictorSKIP(prevMB->best_predictor_for_skip);
      }
      if((FmoGetNextMBNr(img->current_mb_nr) == -1)&&(currMB->mb_type == 0))
        if(currMB->send_index_predictor_skip)
          rate += writeMotionVectorPredictorSKIP(currMB->best_predictor_for_skip);

⌨️ 快捷键说明

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