mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-12-18 03:04:06 +00:00
Merge remote-tracking branch 'remotes/origin/fador'
This commit is contained in:
commit
48c2dc4cd9
|
@ -969,6 +969,10 @@ void encode_coding_tree(encoder_control* encoder,uint16_t xCtb,uint16_t yCtb, ui
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
uint32_t uiRefListIdx;
|
uint32_t uiRefListIdx;
|
||||||
|
|
||||||
|
int16_t mv_cand[2][2];
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// Void TEncSbac::codeInterDir( TComDataCU* pcCU, UInt uiAbsPartIdx )
|
// Void TEncSbac::codeInterDir( TComDataCU* pcCU, UInt uiAbsPartIdx )
|
||||||
if(encoder->in.cur_pic->slicetype == SLICE_B)
|
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++)
|
for(uiRefListIdx = 0; uiRefListIdx < 2; uiRefListIdx++)
|
||||||
{
|
{
|
||||||
//if(encoder->ref_idx_num[uiRefListIdx] > 0)
|
//if(encoder->ref_idx_num[uiRefListIdx] > 0)
|
||||||
|
@ -1029,13 +1034,25 @@ 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);
|
||||||
|
|
||||||
|
/* Select better candidate */
|
||||||
|
cur_CU->inter.mv_ref = 0; /* Default to candidate 0 */
|
||||||
|
/* Only check when candidates are different */
|
||||||
|
if (mv_cand[0][0] != mv_cand[1][0] || mv_cand[0][1] != mv_cand[1][1]) {
|
||||||
|
uint16_t cand_1_diff = abs(cur_CU->inter.mv[0]-mv_cand[0][0]) + abs(cur_CU->inter.mv[1]-mv_cand[0][1]);
|
||||||
|
uint16_t cand_2_diff = abs(cur_CU->inter.mv[0]-mv_cand[1][0]) + abs(cur_CU->inter.mv[1]-mv_cand[1][1]);
|
||||||
|
/* Select candidate 1 if it's closer */
|
||||||
|
if (cand_2_diff < cand_1_diff) {
|
||||||
|
cur_CU->inter.mv_ref = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!(/*pcCU->getSlice()->getMvdL1ZeroFlag() &&*/ encoder->ref_list == REF_PIC_LIST_1 && cur_CU->inter.mv_dir==3))
|
if (!(/*pcCU->getSlice()->getMvdL1ZeroFlag() &&*/ encoder->ref_list == REF_PIC_LIST_1 && cur_CU->inter.mv_dir==3))
|
||||||
{
|
{
|
||||||
/*const TComCUMvField* pcCUMvField = pcCU->getCUMvField( eRefList );*/
|
const int32_t mvd_hor = cur_CU->inter.mv[0]-mv_cand[cur_CU->inter.mv_ref][0];
|
||||||
//TODO: calculate MV field difference
|
const int32_t mvd_ver = cur_CU->inter.mv[1]-mv_cand[cur_CU->inter.mv_ref][1];
|
||||||
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 int8_t bHorAbsGr0 = mvd_hor != 0;
|
const int8_t bHorAbsGr0 = mvd_hor != 0;
|
||||||
const int8_t bVerAbsGr0 = mvd_ver != 0;
|
const int8_t bVerAbsGr0 = mvd_ver != 0;
|
||||||
const uint32_t mvd_hor_abs = abs(mvd_hor);
|
const uint32_t mvd_hor_abs = abs(mvd_hor);
|
||||||
|
@ -1077,13 +1094,12 @@ void encode_coding_tree(encoder_control* encoder,uint16_t xCtb,uint16_t yCtb, ui
|
||||||
|
|
||||||
/* Inter reconstruction */
|
/* 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);
|
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..) */
|
||||||
int32_t iSymbol = cur_CU->inter.mv_ref;//pcCU->getMVPIdx(eRefList, uiAbsPartIdx);
|
picture_setBlockCoded(encoder->in.cur_pic,xCtb, yCtb, depth, 1);
|
||||||
int32_t iNum = AMVP_MAX_NUM_CANDS;
|
|
||||||
cabac_writeUnaryMaxSymbol(&cabac,g_cMVPIdxSCModel, iSymbol,1,iNum-1);
|
|
||||||
}
|
}
|
||||||
|
/* Signal which candidate MV to use */
|
||||||
|
cabac_writeUnaryMaxSymbol(&cabac,g_cMVPIdxSCModel, cur_CU->inter.mv_ref,1,AMVP_MAX_NUM_CANDS-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
155
src/inter.c
155
src/inter.c
|
@ -80,31 +80,28 @@ void inter_recon(picture* ref,int32_t xpos, int32_t ypos,int32_t width, int16_t
|
||||||
mv[1] = mv[1]>>2;
|
mv[1] = mv[1]>>2;
|
||||||
|
|
||||||
/* With overflow present, more checking */
|
/* With overflow present, more checking */
|
||||||
if(overflow_neg_x || overflow_neg_y || overflow_pos_x || overflow_pos_y)
|
if (overflow_neg_x || overflow_neg_y || overflow_pos_x || overflow_pos_y) {
|
||||||
{
|
|
||||||
/* Copy Luma with boundary checking */
|
/* Copy Luma with boundary checking */
|
||||||
for(y = ypos; y < ypos+width; y++)
|
for (y = ypos; y < ypos+width; y++) {
|
||||||
{
|
for (x = xpos; x < xpos+width; x++) {
|
||||||
for(x = xpos; x < xpos+width; x++)
|
|
||||||
{
|
|
||||||
coord_x = x;
|
coord_x = x;
|
||||||
coord_y = y;
|
coord_y = y;
|
||||||
overflow_neg_x = (x < 0)?1:0;
|
overflow_neg_x = (x+mv[0] < 0)?1:0;
|
||||||
overflow_neg_y = (y < 0)?1:0;
|
overflow_neg_y = (y+mv[1] < 0)?1:0;
|
||||||
|
|
||||||
overflow_pos_x = (x >= ref->width )?1:0;
|
overflow_pos_x = (x+mv[0] >= ref->width )?1:0;
|
||||||
overflow_pos_y = (y >= ref->height)?1:0;
|
overflow_pos_y = (y+mv[1] >= ref->height)?1:0;
|
||||||
|
|
||||||
if(overflow_neg_x) {
|
if(overflow_neg_x) {
|
||||||
coord_x = 0;
|
coord_x = -mv[0];
|
||||||
} else if(overflow_pos_x) {
|
} else if(overflow_pos_x) {
|
||||||
coord_x = ref->width-1;
|
coord_x = ref->width-1-mv[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
if(overflow_neg_y) {
|
if(overflow_neg_y) {
|
||||||
coord_y = 0;
|
coord_y = -mv[1];
|
||||||
} else if(overflow_pos_y) {
|
} else if(overflow_pos_y) {
|
||||||
coord_y = ref->height-1;
|
coord_y = ref->height-1-mv[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
dst->yRecData[y*dst->width+x] = ref->yRecData[(coord_y+mv[1])*ref->width+(coord_x+mv[0])];
|
dst->yRecData[y*dst->width+x] = ref->yRecData[(coord_y+mv[1])*ref->width+(coord_x+mv[0])];
|
||||||
|
@ -112,55 +109,135 @@ void inter_recon(picture* ref,int32_t xpos, int32_t ypos,int32_t width, int16_t
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy Chroma with boundary checking */
|
/* Copy Chroma with boundary checking */
|
||||||
for(y = ypos>>1; y < (ypos+width)>>1; y++)
|
for (y = ypos>>1; y < (ypos+width)>>1; y++) {
|
||||||
{
|
for (x = xpos>>1; x < (xpos+width)>>1; x++) {
|
||||||
for(x = xpos>>1; x < (xpos+width)>>1; x++)
|
|
||||||
{
|
|
||||||
coord_x = x;
|
coord_x = x;
|
||||||
coord_y = y;
|
coord_y = y;
|
||||||
overflow_neg_x = (x < 0)?1:0;
|
overflow_neg_x = (x+(mv[0]>>1) < 0)?1:0;
|
||||||
overflow_neg_y = (y < 0)?1:0;
|
overflow_neg_y = (y+(mv[1]>>1) < 0)?1:0;
|
||||||
|
|
||||||
overflow_pos_x = (x >= ref->width>>1 )?1:0;
|
overflow_pos_x = (x+(mv[0]>>1) >= ref->width>>1 )?1:0;
|
||||||
overflow_pos_y = (y >= ref->height>>1)?1:0;
|
overflow_pos_y = (y+(mv[1]>>1) >= ref->height>>1)?1:0;
|
||||||
|
|
||||||
if(overflow_neg_x) {
|
if(overflow_neg_x) {
|
||||||
coord_x = 0;
|
coord_x = -(mv[0]>>1);
|
||||||
} else if(overflow_pos_x) {
|
} else if(overflow_pos_x) {
|
||||||
coord_x = (ref->width>>1)-1;
|
coord_x = ((ref->width-mv[0])>>1)-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(overflow_neg_y) {
|
if(overflow_neg_y) {
|
||||||
coord_y = 0;
|
coord_y = -(mv[1]>>1);
|
||||||
} else if(overflow_pos_y) {
|
} else if(overflow_pos_y) {
|
||||||
coord_y = (ref->height>>1)-1;
|
coord_y = ((ref->height-mv[1])>>1)-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
dst->uRecData[y*(dst->width>>1)+x] = ref->uRecData[(coord_y+(mv[1]>>1))*ref->width+(coord_x+(mv[0]>>1))];
|
dst->uRecData[y*(dst->width>>1)+x] = ref->uRecData[(coord_y+(mv[1]>>1))*(ref->width>>1)+(coord_x+(mv[0]>>1))];
|
||||||
dst->vRecData[y*(dst->width>>1)+x] = ref->vRecData[(coord_y+(mv[1]>>1))*ref->width+(coord_x+(mv[0]>>1))];
|
dst->vRecData[y*(dst->width>>1)+x] = ref->vRecData[(coord_y+(mv[1]>>1))*(ref->width>>1)+(coord_x+(mv[0]>>1))];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Copy Luma */
|
/* Copy Luma */
|
||||||
for(y = ypos; y < ypos+width; y++)
|
for (y = ypos; y < ypos+width; y++) {
|
||||||
{
|
for (x = xpos; x < xpos+width; x++) {
|
||||||
for(x = xpos; x < xpos+width; x++)
|
|
||||||
{
|
|
||||||
dst->yRecData[y*dst->width+x] = ref->yRecData[(y+mv[1])*ref->width+x+mv[0]];
|
dst->yRecData[y*dst->width+x] = ref->yRecData[(y+mv[1])*ref->width+x+mv[0]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy Chroma */
|
/* Copy Chroma */
|
||||||
for(y = ypos>>1; y < (ypos+width)>>1; y++)
|
for (y = ypos>>1; y < (ypos+width)>>1; y++) {
|
||||||
{
|
for (x = xpos>>1; x < (xpos+width)>>1; x++) {
|
||||||
for(x = xpos>>1; x < (xpos+width)>>1; x++)
|
|
||||||
{
|
|
||||||
dst->uRecData[y*(dst->width>>1)+x] = ref->uRecData[(y+(mv[1]>>1))*(ref->width>>1)+x+(mv[0]>>1)];
|
dst->uRecData[y*(dst->width>>1)+x] = ref->uRecData[(y+(mv[1]>>1))*(ref->width>>1)+x+(mv[0]>>1)];
|
||||||
dst->vRecData[y*(dst->width>>1)+x] = ref->vRecData[(y+(mv[1]>>1))*(ref->width>>1)+x+(mv[0]>>1)];
|
dst->vRecData[y*(dst->width>>1)+x] = ref->vRecData[(y+(mv[1]>>1))*(ref->width>>1)+x+(mv[0]>>1)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\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++;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -14,5 +14,8 @@
|
||||||
#define __INTER_H
|
#define __INTER_H
|
||||||
|
|
||||||
void inter_setBlockMode(picture* pic,uint32_t xCtb, uint32_t yCtb, uint8_t depth, CU_info* cur_cu);
|
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
|
#endif
|
||||||
|
|
|
@ -19,9 +19,9 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "bitstream.h"
|
#include "bitstream.h"
|
||||||
#include "picture.h"
|
#include "picture.h"
|
||||||
|
#include "encoder.h"
|
||||||
#include "intra.h"
|
#include "intra.h"
|
||||||
#include "inter.h"
|
#include "inter.h"
|
||||||
#include "encoder.h"
|
|
||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
#include "search.h"
|
#include "search.h"
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue