📄 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 "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 + -