Added (basic) motion vector prediction

This commit is contained in:
Marko Viitanen 2013-09-16 16:37:24 +03:00
parent 182381a23c
commit 8e776366dc
4 changed files with 110 additions and 8 deletions

View file

@ -969,6 +969,10 @@ void encode_coding_tree(encoder_control* encoder,uint16_t xCtb,uint16_t yCtb, ui
else
{
uint32_t uiRefListIdx;
int16_t mv_cand[2][2];
/*
// Void TEncSbac::codeInterDir( TComDataCU* pcCU, UInt uiAbsPartIdx )
if(encoder->in.cur_pic->slicetype == SLICE_B)
@ -989,6 +993,7 @@ void encode_coding_tree(encoder_control* encoder,uint16_t xCtb,uint16_t yCtb, ui
*/
for(uiRefListIdx = 0; uiRefListIdx < 2; uiRefListIdx++)
{
//if(encoder->ref_idx_num[uiRefListIdx] > 0)
@ -1029,13 +1034,14 @@ void encode_coding_tree(encoder_control* encoder,uint16_t xCtb,uint16_t yCtb, ui
}
}
/* Get MV candidates */
inter_get_mv_cand(encoder, xCtb, yCtb, depth, mv_cand);
cur_CU->inter.mv_ref = 0;
if (!(/*pcCU->getSlice()->getMvdL1ZeroFlag() &&*/ encoder->ref_list == REF_PIC_LIST_1 && cur_CU->inter.mv_dir==3))
{
/*const TComCUMvField* pcCUMvField = pcCU->getCUMvField( eRefList );*/
//TODO: calculate MV field difference
const int32_t mvd_hor = cur_CU->inter.mv[0];//pcCUMvField->getMvd( uiAbsPartIdx ).getHor();
const int32_t mvd_ver = cur_CU->inter.mv[1];//pcCUMvField->getMvd( uiAbsPartIdx ).getVer();
const int32_t mvd_hor = cur_CU->inter.mv[0]-mv_cand[cur_CU->inter.mv_ref][0];
const int32_t mvd_ver = cur_CU->inter.mv[1]-mv_cand[cur_CU->inter.mv_ref][1];
const int8_t bHorAbsGr0 = mvd_hor != 0;
const int8_t bVerAbsGr0 = mvd_ver != 0;
const uint32_t mvd_hor_abs = abs(mvd_hor);
@ -1077,10 +1083,14 @@ void encode_coding_tree(encoder_control* encoder,uint16_t xCtb,uint16_t yCtb, ui
/* Inter reconstruction */
inter_recon(encoder->ref->pics[0],xCtb*CU_MIN_SIZE_PIXELS,yCtb*CU_MIN_SIZE_PIXELS,LCU_WIDTH>>depth,cur_CU->inter.mv,encoder->in.cur_pic);
/* Mark this block as "coded" (can be used for predictions..) */
picture_setBlockCoded(encoder->in.cur_pic,xCtb, yCtb, depth, 1);
}
{
int32_t iSymbol = cur_CU->inter.mv_ref;//pcCU->getMVPIdx(eRefList, uiAbsPartIdx);
/* Signal which candidate MV to use */
int32_t iSymbol = cur_CU->inter.mv_ref;
int32_t iNum = AMVP_MAX_NUM_CANDS;
cabac_writeUnaryMaxSymbol(&cabac,g_cMVPIdxSCModel, iSymbol,1,iNum-1);
}

View file

@ -164,3 +164,92 @@ void inter_recon(picture* ref,int32_t xpos, int32_t ypos,int32_t width, int16_t
}
}
/*!
\brief Get MV prediction for current block
\param encoder encoder control struct to use
\param xCtb block x position in SCU
\param yCtb block y position in SCU
\param depth current block depth
\param mv_pred[2][2] 2x motion vector prediction
\returns Void
*/
void inter_get_mv_cand(encoder_control *encoder,int32_t xCtb, int32_t yCtb,int8_t depth, int16_t mv_cand[2][2])
{
uint8_t cur_block_in_scu = (LCU_WIDTH>>depth) / CU_MIN_SIZE_PIXELS;
CU_info *cur_cu = &encoder->in.cur_pic->CU[depth][xCtb+yCtb*(encoder->in.width_in_LCU<<MAX_DEPTH)];
uint8_t candidates = 0;
/*
Predictor block locations
____ ______
|B2|______|B1|B0|
| |
| Cur CU |
__| |
|A1|_________|
|A0|
*/
CU_info *b0, *b1, *b2, *a0, *a1;
b0 = b1 = b2 = a0 = a1 = NULL;
if (xCtb != 0) {
a1 = &encoder->in.cur_pic->CU[depth][xCtb-1+(yCtb+cur_block_in_scu-1)*(encoder->in.width_in_LCU<<MAX_DEPTH)];
if(!a1->coded) a1 = NULL;
if (yCtb+cur_block_in_scu < encoder->in.height_in_LCU<<MAX_DEPTH) {
a0 = &encoder->in.cur_pic->CU[depth][xCtb-1+(yCtb+cur_block_in_scu)*(encoder->in.width_in_LCU<<MAX_DEPTH)];
if(!a0->coded) a0 = NULL;
}
}
if (yCtb != 0) {
b0 = &encoder->in.cur_pic->CU[depth][xCtb+cur_block_in_scu+(yCtb-1)*(encoder->in.width_in_LCU<<MAX_DEPTH)];
if (!b0->coded) b0 = NULL;
b1 = &encoder->in.cur_pic->CU[depth][xCtb+cur_block_in_scu-1+(yCtb-1)*(encoder->in.width_in_LCU<<MAX_DEPTH)];
if (!b1->coded) b1 = NULL;
if (xCtb != 0) {
b2 = &encoder->in.cur_pic->CU[depth][xCtb-1+(yCtb-1)*(encoder->in.width_in_LCU<<MAX_DEPTH)];
if(!b2->coded) b2 = NULL;
}
}
/* Left predictors */
if (a0 && a0->type == CU_INTER) {
mv_cand[candidates][0] = a0->inter.mv[0];
mv_cand[candidates][1] = a0->inter.mv[1];
candidates++;
} else if (a1 && a1->type == CU_INTER) {
mv_cand[candidates][0] = a1->inter.mv[0];
mv_cand[candidates][1] = a1->inter.mv[1];
candidates++;
}
/* Top predictors */
if (b0 && b0->type == CU_INTER) {
mv_cand[candidates][0] = b0->inter.mv[0];
mv_cand[candidates][1] = b0->inter.mv[1];
candidates++;
} else if (b1 && b1->type == CU_INTER) {
mv_cand[candidates][0] = b1->inter.mv[0];
mv_cand[candidates][1] = b1->inter.mv[1];
candidates++;
} else if(b2 && b2->type == CU_INTER) {
mv_cand[candidates][0] = b2->inter.mv[0];
mv_cand[candidates][1] = b2->inter.mv[1];
candidates++;
}
if(candidates < 2) {
//TODO: add temporal mv predictor
}
for (;candidates < 2; candidates++) {
mv_cand[candidates][0] = 0;
mv_cand[candidates][1] = 0;
candidates++;
}
}

View file

@ -14,5 +14,8 @@
#define __INTER_H
void inter_setBlockMode(picture* pic,uint32_t xCtb, uint32_t yCtb, uint8_t depth, CU_info* cur_cu);
void inter_recon(picture* ref,int32_t xpos, int32_t ypos,int32_t width, int16_t mv[2], picture* dst);
void inter_recon(picture *ref,int32_t xpos, int32_t ypos,int32_t width, int16_t mv[2], picture* dst);
void inter_get_mv_cand(encoder_control *encoder, int32_t xCtb, int32_t yCtb, int8_t depth, int16_t mv_cand[2][2]);
#endif

View file

@ -19,9 +19,9 @@
#include "config.h"
#include "bitstream.h"
#include "picture.h"
#include "encoder.h"
#include "intra.h"
#include "inter.h"
#include "encoder.h"
#include "filter.h"
#include "search.h"