📄 mv_competition.c
字号:
}
return rate;
}
/*!
*************************************************************************************
* \brief
*
*
* \param
*
*
* \return
*
*************************************************************************************
*/
int writeMotionVectorPredictorSKIP (int predictor)
{
int rate = 0;
Macroblock* currMB = &img->mb_data[img->current_mb_nr];
SyntaxElement* currSE = &img->MB_SyntaxElements[currMB->currSEnr];
int* bitCount = currMB->bitcounter;
Slice* currSlice = img->currentSlice;
const int* partMap = assignSE2partition[input->partition_mode];
DataPartition* dataPart;
currSE->value1 = predictor;
currSE->type = SE_MV_PREDICTOR;
currSE->value2 = (mv_comp.nb_mode_for_skip / 2) + (mv_comp.nb_mode_for_skip % 2);
if (input->symbol_mode == UVLC)
{
dataPart = &(currSlice->partArr[partMap[currSE->type]]);
currSE->len = u_v(currSE->value2, "predictor for the SKIP mode", currSE->value1,dataPart->bitstream);
}
else
{
currSE->writing = writeMB_Motion_predictor_CABAC;
dataPart = &(currSlice->partArr[partMap[currSE->type]]);
dataPart->writeSyntaxElement (currSE, dataPart);
}
bitCount[BITS_SKIP_PRED] += currSE->len;
rate += currSE->len;
currSE++;
currMB->currSEnr++;
return rate;
}
/*!
*************************************************************************************
* \brief
*
*
* \param
*
*
* \return
*
*************************************************************************************
*/
int writeIndexForMotionVectorPrediction (int refframe, int list_idx,
int mv_mode,
int i,
int j)
{
int rate = 0;
Macroblock* currMB = &img->mb_data[img->current_mb_nr];
int* bitCount = currMB->bitcounter;
SyntaxElement* currSE = &img->MB_SyntaxElements[currMB->currSEnr];
Slice* currSlice = img->currentSlice;
const int* partMap = assignSE2partition[input->partition_mode];
DataPartition* dataPart;
int maxmode = 0;
if (img->type == I_SLICE)
maxmode = 1;
else if (img->type == P_SLICE)
maxmode = mv_comp.nb_mode_for_mvp;
else if (img->type == B_SLICE)
maxmode = mv_comp.nb_mode_for_mvb;
currSE->value1 = predModeMV[mv_mode][refframe][list_idx][j][i];
currSE->type = SE_MV_PREDICTOR;
currSE->value2 = (maxmode / 2) + (maxmode % 2);
if (maxmode > 1)
{
if (input->symbol_mode == UVLC)
{
dataPart = &(currSlice->partArr[partMap[currSE->type]]);
currSE->len = u_v(currSE->value2, "predictor of MV", currSE->value1,dataPart->bitstream);
}
else
{
currSE->writing = writeMB_Motion_predictor_CABAC;
dataPart = &(currSlice->partArr[partMap[currSE->type]]);
dataPart->writeSyntaxElement (currSE, dataPart);
}
}
bitCount[BITS_MV_PRED] += currSE->len;
rate += currSE->len;
currSE++;
currMB->currSEnr++;
return rate;
}
/*!
*************************************************************************************
* \brief
* This function is used to arithmetically encode the Motion vector
* predictor
*
* \param
*
*
* \return
*
*************************************************************************************
*/
void writeMB_Motion_predictor_CABAC(SyntaxElement *se, EncodingEnvironmentPtr eep_dp)
{
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
int act_ctx = 0;
MotionInfoContexts *ctx = (img->currentSlice)->mot_ctx;
int nb_symbol;
int curr_symbol;
if(se->value2 != 0)
{
nb_symbol = se->value2;
curr_symbol = se->value1;
while(nb_symbol!=0)
{
if(currMB->mb_type == 0)
biari_encode_symbol(eep_dp, (signed short) (curr_symbol % 2), &ctx->mv_predictor_skip_contexts[act_ctx]);
else
if(img->type == P_SLICE)
biari_encode_symbol(eep_dp, (signed short) (curr_symbol % 2), &ctx->mv_predictor_mvp_contexts[act_ctx]);
else if(img->type == B_SLICE)
biari_encode_symbol(eep_dp, (signed short) (curr_symbol % 2), &ctx->mv_predictor_mvb_contexts[act_ctx]);
nb_symbol--;
curr_symbol = curr_symbol / 2;
}
}
}
/*!
*************************************************************************************
* \brief
* Returns 0 if no motion vector is available for the previous frame
* at macrobloc position (pos_j, pos_i), 1 otherwise
* because of INTRA_MODE or out of frame (checked here)Writes motion vectors predictor for SKIP
*
* \param
*
*
* \return
*
*************************************************************************************
*/
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);
}
/*!
*************************************************************************************
* \brief
* Writes motion vectors predictor for SKIP
*
* \param
*
*
* \return
*
*************************************************************************************
*/
short collocated_mv_available_previous_B_frame(int pos_y, int pos_x, int list)
{
short return_val = TRUE;
if (ref_idx_previous_B_frame[list][pos_y*4][pos_x*4] == -1) // Collocated block in INTRA
return_val = FALSE;
return (return_val);
}
/*!
*************************************************************************************
* \brief
*
*
* \param
*
*
* \return
*
*************************************************************************************
*/
short send_index_for_skip_prediction(int best_mode_skip)
{
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[best_mode_skip][0];
mv_y_ref = mv_comp.mv_pred_skip[best_mode_skip][1];
for (i=0; i<mv_comp.nb_mode_for_skip; i++)
{
//Check if among all modes enabled, one single is AVAILABLE (all others are NOT_AVAILABLE)
if (mv_comp.mv_pred_skip[i][0] != NOT_AVAILABLE)
nb_of_available++;
}
if (nb_of_available > 1) //Otherwise does not need to be sent: only one is available
{
for (i=0; 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);
}
/*!
*************************************************************************************
* \brief
* Set motion vector predictor
*
* \param
*
*
* \return
*
*************************************************************************************
*/
void SetMotionVectorPredictor_Competition (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)
{
int mb_x = 4*block_x;
int mb_y = 4*block_y;
short pmv2[2];
short predictor;
int maxmode=0;
int modeblock;
int prediction_mode;
int *predictors=NULL;
modeblock = determine_mode_block(blockshape_x,blockshape_y);
if (img->type == I_SLICE)
maxmode = 1;
else if (img->type == P_SLICE)
{
maxmode = mv_comp.nb_mode_for_mvp;
predictors = mv_comp.predictor_for_mvp;
}
else if (img->type == B_SLICE)
{
maxmode = mv_comp.nb_mode_for_mvb;
predictors = mv_comp.predictor_for_mvb;
}
predictor = 0;
for (prediction_mode = 0; prediction_mode<maxmode; prediction_mode++)
{
if (predictors[prediction_mode] == PRED_H264_MEDIAN)
{
SetMotionVectorPredictor(pmv2,refPic,tmp_mv,ref_frame,list,block_x,block_y,blockshape_x,blockshape_y);
if (predictor == 0 )
{
pmv[0]=pmv2[0];
pmv[1]=pmv2[1];
}
}
else if (predictors[prediction_mode] == PRED_ZERO)
{
pmv2[0] = 0;
pmv2[1] = 0;
}
else if (predictors[prediction_mode] == PRED_A)
{
PixelPos block_a;
getLuma4x4Neighbour(img->current_mb_nr, block_x, block_y, -1, 0, &block_a);
pmv2[0] = block_a.available ? tmp_mv[block_a.pos_y][block_a.pos_x][0] : 0;
pmv2[1] = block_a.available ? tmp_mv[block_a.pos_y][block_a.pos_x][1] : 0;
}
else if (predictors[prediction_mode] == PRED_B)
{
PixelPos block_b;
getLuma4x4Neighbour(img->current_mb_nr, block_x, block_y, 0, -1, &block_b);
pmv2[0] = block_b.available ? tmp_mv[block_b.pos_y][block_b.pos_x][0] : 0;
pmv2[1] = block_b.available ? tmp_mv[block_b.pos_y][block_b.pos_x][1] : 0;
}
else if (predictors[prediction_mode] == PRED_C)
{
PixelPos block_c, block_d;
getLuma4x4Neighbour(img->current_mb_nr, block_x, block_y, blockshape_x, -1, &block_c);
getLuma4x4Neighbour(img->current_mb_nr, block_x, block_y, -1, -1, &block_d);
if (mb_y > 0)
{
if (mb_x < 8) // first column of 8x8 blocks
{
if (mb_y==8)
{
if (blockshape_x == 16) block_c.available = 0;
else block_c.available &= 1;
}
else
{
if (mb_x+blockshape_x != 8) block_c.available &= 1;
else block_c.available = 0;
}
}
else
{
if (mb_x+blockshape_x != 16) block_c.available &= 1;
else block_c.available = 0;
}
}
if (!block_c.available)
{
block_c=block_d;
}
pmv2[0] = block_c.available ? tmp_mv[block_c.pos_y][block_c.pos_x][0] : 0;
pmv2[1] = block_c.available ? tmp_mv[block_c.pos_y][block_c.pos_x][1] : 0;
}
else if (predictors[prediction_mode] == PRED_COLOCATED)
{
int y=(int)img->current_mb_nr/(img->width/16); // Vertical
int x=(int)img->current_mb_nr%(img->width/16); // Horizontal
if (img->type == P_SLICE)
{
if (collocated_mv_available(y, x, LIST_0) == TRUE)
{
// The collocated is the top left MV of the macroblock, whatever the subpartition...
// To be improved.
pmv2[0] = listX[0][0]->mv[LIST_0][y*4+block_y][x*4+block_x][0] * (ref_frame+1) / (listX[0][0]->ref_idx[0][y*4+block_y][x*4+block_x] + 1);
pmv2[1] = listX[0][0]->mv[LIST_0][y*4+block_y][x*4+block_x][1] * (ref_frame+1) / (listX[0][0]->ref_idx[0][y*4+block_y][x*4+block_x] + 1);
}
else
{
pmv2[0] = 0;//NOT_AVAILABLE;
pmv2[1] = 0;//NOT_AVAILABLE;
}
}
else if (img->type == B_SLICE)
{
// <FTRD : Compatibility with hierarchical B slices
// if(input->HierarchicalCoding == 0)
// {
// SetMotionVectorPredictor_collocated_B_SLICE(pmv2, y, x, list, ref_frame, block_y, block_x);
// }
// else
// {
SetMotionVectorPredictor_collocated_HB_SLICE(pmv2, y, x, list, ref_frame, block_y, block_x);
// }
// FTRD>
}
}
mv_predictors[block_x][block_y][modeblock][ref_frame][list][prediction_mode][0] = pmv2[0];
mv_predictors[block_x][block_y][modeblock][ref_frame][list][prediction_mode][1] = pmv2[1];
}
// Check if the index for the motion vector prediction needs to be sent or not
// Stored in predModeMV2
send_index_for_mv_prediction(block_x, block_y, modeblock, ref_frame, list, maxmode);
}
/*!
*************************************************************************************
* \brief
*
*
* \param
*
*
* \return
*
*************************************************************************************
*/
void send_index_for_mv_prediction(int block_x, int block_y, int modeblock, short ref_frame, int list, int maxmode)
{
short egality_of_predictors = 0;
short current_predictor_index;
short nb_of_available = 0;
short i;
int pred0_x, pred0_y, current_pred_x, current_pred_y;
pred0_x = mv_predictors[block_x][block_y][modeblock][ref_frame][list][0][0];
pred0_y = mv_predictors[block_x][block_y][modeblock][ref_frame][list][0][1];
for (i=0; i<maxmode; i++)
{
//Check if among all modes enabled, one single is AVAILABLE (all others are NOT_AVAILABLE)
if (mv_predictors[block_x][block_y][modeblock][ref_frame][list][i][0] != NOT_AVAILABLE)
nb_of_available++;
}
// if (nb_of_available > 1) //Otherwise does not need to be sent: only one is available
{
for(current_predictor_index=1;current_predictor_index<maxmode ;current_predictor_index++)
{
current_pred_x = mv_predictors[block_x][block_y][modeblock][ref_frame][list][current_predictor_index][0];
current_pred_y = mv_predictors[block_x][block_y][modeblock][ref_frame][list][current_predictor_index][1];
if ((current_pred_x == pred0_x) && (current_pred_y == pred0_y))
egality_of_predictors++;
}
}
if(egality_of_predictors == maxmode-1)
send_index_mv_prediction[modeblock][ref_frame][list][block_y][block_x][maxmode]=1;
else
send_index_mv_prediction[modeblock][ref_frame][list][block_y][block_x][maxmode]=0;
}
/*!
*************************************************************************************
* \brief
* return le mode associ
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -