Refactoring encoder.c in preparation for adding merge-mode

This commit is contained in:
Marko Viitanen 2013-10-11 11:40:37 +03:00
parent b1b45944a9
commit 96a0f03298

View file

@ -959,14 +959,14 @@ void encode_coding_tree(encoder_control *encoder, uint16_t x_ctb,
// parseRefFrmIdx // parseRefFrmIdx
int32_t ref_frame = cur_cu->inter.mv_ref; int32_t ref_frame = cur_cu->inter.mv_ref;
cabac.ctx = &g_cu_ref_pic_model[0]; cabac.ctx = &g_cu_ref_pic_model[0];
CABAC_BIN(&cabac, (ref_frame == 0) ? 0 : 1, "ref_frame_flag"); CABAC_BIN(&cabac, (ref_frame == 0) ? 0 : 1, "ref_frame_flag");
if (ref_frame > 0) { if (ref_frame > 0) {
uint32_t i; uint32_t i;
uint32_t ref_num = encoder->ref_idx_num[ref_list_idx] - 2; uint32_t ref_num = encoder->ref_idx_num[ref_list_idx] - 2;
cabac.ctx = &g_cu_ref_pic_model[1]; cabac.ctx = &g_cu_ref_pic_model[1];
ref_frame--; ref_frame--;
for (i = 0; i < ref_num; ++i) { for (i = 0; i < ref_num; ++i) {
@ -976,14 +976,11 @@ void encode_coding_tree(encoder_control *encoder, uint16_t x_ctb,
CABAC_BIN(&cabac, symbol, "ref_frame_flag2"); CABAC_BIN(&cabac, symbol, "ref_frame_flag2");
} else { } else {
CABAC_BIN_EP(&cabac, symbol, "ref_frame_flag2"); CABAC_BIN_EP(&cabac, symbol, "ref_frame_flag2");
}
if (symbol == 0) {
break;
}
}
} }
if (symbol == 0) break;
} }
}
}
// Get MV candidates // Get MV candidates
inter_get_mv_cand(encoder, x_ctb, y_ctb, depth, mv_cand); inter_get_mv_cand(encoder, x_ctb, y_ctb, depth, mv_cand);
@ -992,145 +989,147 @@ void encode_coding_tree(encoder_control *encoder, uint16_t x_ctb,
cur_cu->inter.mv_ref = 0; // Default to candidate 0 cur_cu->inter.mv_ref = 0; // Default to candidate 0
// Only check when candidates are different // Only check when candidates are different
if (mv_cand[0][0] != mv_cand[1][0] || mv_cand[0][1] != mv_cand[1][1]) { 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( 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]); 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( 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]); cur_cu->inter.mv[1] - mv_cand[1][1]);
// Select candidate 1 if it's closer // Select candidate 1 if it's closer
if (cand_2_diff < cand_1_diff) { if (cand_2_diff < cand_1_diff) {
cur_cu->inter.mv_ref = 1; 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 int32_t mvd_hor = cur_cu->inter.mv[0] - mv_cand[cur_cu->inter.mv_ref][0]; 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 int32_t mvd_ver = cur_cu->inter.mv[1] - mv_cand[cur_cu->inter.mv_ref][1];
const int8_t hor_abs_gr0 = mvd_hor != 0; const int8_t hor_abs_gr0 = mvd_hor != 0;
const int8_t ver_abs_gr0 = mvd_ver != 0; const int8_t ver_abs_gr0 = mvd_ver != 0;
const uint32_t mvd_hor_abs = abs(mvd_hor); const uint32_t mvd_hor_abs = abs(mvd_hor);
const uint32_t mvd_ver_abs = abs(mvd_ver); const uint32_t mvd_ver_abs = abs(mvd_ver);
cabac.ctx = &g_cu_mvd_model[0]; cabac.ctx = &g_cu_mvd_model[0];
CABAC_BIN(&cabac, (mvd_hor!=0)?1:0, "abs_mvd_greater0_flag_hor"); CABAC_BIN(&cabac, (mvd_hor!=0)?1:0, "abs_mvd_greater0_flag_hor");
CABAC_BIN(&cabac, (mvd_ver!=0)?1:0, "abs_mvd_greater0_flag_ver"); CABAC_BIN(&cabac, (mvd_ver!=0)?1:0, "abs_mvd_greater0_flag_ver");
cabac.ctx = &g_cu_mvd_model[1]; cabac.ctx = &g_cu_mvd_model[1];
if (hor_abs_gr0) { if (hor_abs_gr0) {
CABAC_BIN(&cabac, (mvd_hor_abs>1)?1:0, "abs_mvd_greater1_flag_hor"); CABAC_BIN(&cabac, (mvd_hor_abs>1)?1:0, "abs_mvd_greater1_flag_hor");
} }
if (ver_abs_gr0) { if (ver_abs_gr0) {
CABAC_BIN(&cabac, (mvd_ver_abs>1)?1:0, "abs_mvd_greater1_flag_ver"); CABAC_BIN(&cabac, (mvd_ver_abs>1)?1:0, "abs_mvd_greater1_flag_ver");
} }
if (hor_abs_gr0) { if (hor_abs_gr0) {
if (mvd_hor_abs > 1) { if (mvd_hor_abs > 1) {
cabac_write_ep_ex_golomb(&cabac,mvd_hor_abs-2, 1); cabac_write_ep_ex_golomb(&cabac,mvd_hor_abs-2, 1);
} }
CABAC_BIN_EP(&cabac, (mvd_hor>0)?0:1, "mvd_sign_flag_hor"); CABAC_BIN_EP(&cabac, (mvd_hor>0)?0:1, "mvd_sign_flag_hor");
} }
if (ver_abs_gr0) { if (ver_abs_gr0) {
if (mvd_ver_abs > 1) { if (mvd_ver_abs > 1) {
cabac_write_ep_ex_golomb(&cabac,mvd_ver_abs-2, 1); cabac_write_ep_ex_golomb(&cabac,mvd_ver_abs-2, 1);
}
CABAC_BIN_EP(&cabac, (mvd_ver>0)?0:1, "mvd_sign_flag_ver");
}
// Inter reconstruction
inter_recon(encoder->ref->pics[0], x_ctb * CU_MIN_SIZE_PIXELS,
y_ctb * 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_set_block_coded(encoder->in.cur_pic, x_ctb, y_ctb, depth, 1);
} }
CABAC_BIN_EP(&cabac, (mvd_ver>0)?0:1, "mvd_sign_flag_ver");
}
}
// Signal which candidate MV to use // Signal which candidate MV to use
cabac_write_unary_max_symbol(&cabac, g_mvp_idx_model, cur_cu->inter.mv_ref, 1, cabac_write_unary_max_symbol(&cabac, g_mvp_idx_model, cur_cu->inter.mv_ref, 1,
AMVP_MAX_NUM_CANDS - 1); AMVP_MAX_NUM_CANDS - 1);
}
}
} }
}
} // for ref_list
} // if !merge
if (1) { // Inter reconstruction
inter_recon(encoder->ref->pics[0], x_ctb * CU_MIN_SIZE_PIXELS,
y_ctb * 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_set_block_coded(encoder->in.cur_pic, x_ctb, y_ctb, depth, 1);
{
pixel *base_y = &encoder->in.cur_pic->y_data[x_ctb*(LCU_WIDTH>>(MAX_DEPTH)) + (y_ctb*(LCU_WIDTH>>(MAX_DEPTH))) *encoder->in.width]; pixel *base_y = &encoder->in.cur_pic->y_data[x_ctb*(LCU_WIDTH>>(MAX_DEPTH)) + (y_ctb*(LCU_WIDTH>>(MAX_DEPTH))) *encoder->in.width];
pixel *base_u = &encoder->in.cur_pic->u_data[x_ctb*(LCU_WIDTH>>(MAX_DEPTH+1)) + (y_ctb*(LCU_WIDTH>>(MAX_DEPTH+1)))*(encoder->in.width>>1)]; pixel *base_u = &encoder->in.cur_pic->u_data[x_ctb*(LCU_WIDTH>>(MAX_DEPTH+1)) + (y_ctb*(LCU_WIDTH>>(MAX_DEPTH+1)))*(encoder->in.width>>1)];
pixel *base_v = &encoder->in.cur_pic->v_data[x_ctb*(LCU_WIDTH>>(MAX_DEPTH+1)) + (y_ctb*(LCU_WIDTH>>(MAX_DEPTH+1)))*(encoder->in.width>>1)]; pixel *base_v = &encoder->in.cur_pic->v_data[x_ctb*(LCU_WIDTH>>(MAX_DEPTH+1)) + (y_ctb*(LCU_WIDTH>>(MAX_DEPTH+1)))*(encoder->in.width>>1)];
uint32_t width = LCU_WIDTH>>depth; uint32_t width = LCU_WIDTH>>depth;
/* INTRAPREDICTION VARIABLES */ /* INTRAPREDICTION VARIABLES */
int16_t pred[LCU_WIDTH*LCU_WIDTH+1]; int16_t pred[LCU_WIDTH*LCU_WIDTH+1];
int16_t predU[LCU_WIDTH*LCU_WIDTH>>2]; int16_t predU[LCU_WIDTH*LCU_WIDTH>>2];
int16_t predV[LCU_WIDTH*LCU_WIDTH>>2]; int16_t predV[LCU_WIDTH*LCU_WIDTH>>2];
pixel *recbase_y = &encoder->in.cur_pic->y_recdata[x_ctb*(LCU_WIDTH>>(MAX_DEPTH)) + (y_ctb*(LCU_WIDTH>>(MAX_DEPTH))) *encoder->in.width]; pixel *recbase_y = &encoder->in.cur_pic->y_recdata[x_ctb*(LCU_WIDTH>>(MAX_DEPTH)) + (y_ctb*(LCU_WIDTH>>(MAX_DEPTH))) *encoder->in.width];
pixel *recbase_u = &encoder->in.cur_pic->u_recdata[x_ctb*(LCU_WIDTH>>(MAX_DEPTH+1)) + (y_ctb*(LCU_WIDTH>>(MAX_DEPTH+1)))*(encoder->in.width>>1)]; pixel *recbase_u = &encoder->in.cur_pic->u_recdata[x_ctb*(LCU_WIDTH>>(MAX_DEPTH+1)) + (y_ctb*(LCU_WIDTH>>(MAX_DEPTH+1)))*(encoder->in.width>>1)];
pixel *recbase_v = &encoder->in.cur_pic->v_recdata[x_ctb*(LCU_WIDTH>>(MAX_DEPTH+1)) + (y_ctb*(LCU_WIDTH>>(MAX_DEPTH+1)))*(encoder->in.width>>1)]; pixel *recbase_v = &encoder->in.cur_pic->v_recdata[x_ctb*(LCU_WIDTH>>(MAX_DEPTH+1)) + (y_ctb*(LCU_WIDTH>>(MAX_DEPTH+1)))*(encoder->in.width>>1)];
/* TODO: dynamic memory allocation */ /* TODO: dynamic memory allocation */
int16_t coeff_y[LCU_WIDTH*LCU_WIDTH*2]; int16_t coeff_y[LCU_WIDTH*LCU_WIDTH*2];
int16_t coeff_u[LCU_WIDTH*LCU_WIDTH>>1]; int16_t coeff_u[LCU_WIDTH*LCU_WIDTH>>1];
int16_t coeff_v[LCU_WIDTH*LCU_WIDTH>>1]; int16_t coeff_v[LCU_WIDTH*LCU_WIDTH>>1];
int8_t residual = 0; int8_t residual = 0;
/* Initialize helper structure for transform */ /* Initialize helper structure for transform */
transform_info ti; transform_info ti;
memset(&ti, 0, sizeof(transform_info)); memset(&ti, 0, sizeof(transform_info));
ti.x_ctb = x_ctb; ti.y_ctb = y_ctb; ti.x_ctb = x_ctb; ti.y_ctb = y_ctb;
/* Base pointers */ /* Base pointers */
ti.base = base_y; ti.base_u = base_u; ti.base_v = base_v; ti.base = base_y; ti.base_u = base_u; ti.base_v = base_v;
ti.base_stride = encoder->in.width; ti.base_stride = encoder->in.width;
// Prediction pointers // Prediction pointers
ti.pred = pred; ti.pred_u = predU; ti.pred_v = predV; ti.pred = pred; ti.pred_u = predU; ti.pred_v = predV;
ti.pred_stride = (LCU_WIDTH>>depth); ti.pred_stride = (LCU_WIDTH>>depth);
// Reconstruction pointers // Reconstruction pointers
ti.recbase = recbase_y; ti.recbase_u = recbase_u; ti.recbase_v = recbase_v; ti.recbase = recbase_y; ti.recbase_u = recbase_u; ti.recbase_v = recbase_v;
ti.recbase_stride = encoder->in.width; ti.recbase_stride = encoder->in.width;
// Coeff pointers // Coeff pointers
ti.coeff[0] = coeff_y; ti.coeff[1] = coeff_u; ti.coeff[2] = coeff_v; ti.coeff[0] = coeff_y; ti.coeff[1] = coeff_u; ti.coeff[2] = coeff_v;
ti.block_type = CU_INTER; ti.block_type = CU_INTER;
// Handle transforms, quant and reconstruction // Handle transforms, quant and reconstruction
ti.idx = 0; ti.idx = 0;
encode_transform_tree(encoder,&ti, depth); encode_transform_tree(encoder,&ti, depth);
// Coded block pattern // Coded block pattern
ti.cb_top[0] = (ti.cb[0] & 0x1 || ti.cb[1] & 0x1 || ti.cb[2] & 0x1 || ti.cb[3] & 0x1)?1:0; ti.cb_top[0] = (ti.cb[0] & 0x1 || ti.cb[1] & 0x1 || ti.cb[2] & 0x1 || ti.cb[3] & 0x1)?1:0;
ti.cb_top[1] = (ti.cb[0] & 0x2 || ti.cb[1] & 0x2 || ti.cb[2] & 0x2 || ti.cb[3] & 0x2)?1:0; ti.cb_top[1] = (ti.cb[0] & 0x2 || ti.cb[1] & 0x2 || ti.cb[2] & 0x2 || ti.cb[3] & 0x2)?1:0;
ti.cb_top[2] = (ti.cb[0] & 0x4 || ti.cb[1] & 0x4 || ti.cb[2] & 0x4 || ti.cb[3] & 0x4)?1:0; ti.cb_top[2] = (ti.cb[0] & 0x4 || ti.cb[1] & 0x4 || ti.cb[2] & 0x4 || ti.cb[3] & 0x4)?1:0;
residual = ti.cb_top[0] | ti.cb_top[1] | ti.cb_top[2]; residual = ti.cb_top[0] | ti.cb_top[1] | ti.cb_top[2];
if(depth == 0) { if(depth == 0) {
picture_set_block_residual(encoder->in.cur_pic,x_ctb ,y_ctb ,depth+1,ti.cb[0] & 0x1); picture_set_block_residual(encoder->in.cur_pic,x_ctb ,y_ctb ,depth+1,ti.cb[0] & 0x1);
picture_set_block_residual(encoder->in.cur_pic,x_ctb + 4,y_ctb ,depth+1,ti.cb[1] & 0x1); picture_set_block_residual(encoder->in.cur_pic,x_ctb + 4,y_ctb ,depth+1,ti.cb[1] & 0x1);
picture_set_block_residual(encoder->in.cur_pic,x_ctb ,y_ctb + 4,depth+1,ti.cb[2] & 0x1); picture_set_block_residual(encoder->in.cur_pic,x_ctb ,y_ctb + 4,depth+1,ti.cb[2] & 0x1);
picture_set_block_residual(encoder->in.cur_pic,x_ctb + 4,y_ctb + 4,depth+1,ti.cb[3] & 0x1); picture_set_block_residual(encoder->in.cur_pic,x_ctb + 4,y_ctb + 4,depth+1,ti.cb[3] & 0x1);
} else { } else {
picture_set_block_residual(encoder->in.cur_pic,x_ctb,y_ctb,depth,ti.cb_top[0]); picture_set_block_residual(encoder->in.cur_pic,x_ctb,y_ctb,depth,ti.cb_top[0]);
} }
cabac.ctx = &g_cu_qt_root_cbf_model; cabac.ctx = &g_cu_qt_root_cbf_model;
CABAC_BIN(&cabac, residual, "rqt_root_cbf"); CABAC_BIN(&cabac, residual, "rqt_root_cbf");
// Code (possible) coeffs to bitstream // Code (possible) coeffs to bitstream
ti.idx = 0; ti.idx = 0;
if(residual) { if(residual) {
encode_transform_coeff(encoder, &ti,depth, 0); encode_transform_coeff(encoder, &ti,depth, 0);
} }
} }
}
// END for each part // END for each part
} else if (cur_cu->type == CU_INTRA) { } else if (cur_cu->type == CU_INTRA) {