📄 mv_competition.c
字号:
/*!
************************************************************************
* \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 + -