mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-12-18 11:14:05 +00:00
Move encoding inter PUs to a separate function.
Moves code for encoding a single inter prediction unit from function kvz_encode_coding_tree to function encode_inter_prediction_unit.
This commit is contained in:
parent
5ee9f164e8
commit
ac952cbb44
|
@ -977,129 +977,11 @@ void kvz_encoder_next_frame(encoder_state_t *state)
|
||||||
state->prepared = 1;
|
state->prepared = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void encode_inter_prediction_unit(encoder_state_t * const state,
|
||||||
void kvz_encode_coding_tree(encoder_state_t * const state,
|
cabac_data_t * const cabac,
|
||||||
uint16_t x_ctb, uint16_t y_ctb, uint8_t depth)
|
const cu_info_t * const cur_cu,
|
||||||
|
int x_ctb, int y_ctb, int depth)
|
||||||
{
|
{
|
||||||
cabac_data_t * const cabac = &state->cabac;
|
|
||||||
const videoframe_t * const frame = state->tile->frame;
|
|
||||||
const cu_info_t *cur_cu = kvz_videoframe_get_cu_const(frame, x_ctb, y_ctb);
|
|
||||||
uint8_t split_flag = GET_SPLITDATA(cur_cu, depth);
|
|
||||||
uint8_t split_model = 0;
|
|
||||||
|
|
||||||
//Absolute ctb
|
|
||||||
uint16_t abs_x_ctb = x_ctb + (state->tile->lcu_offset_x * LCU_WIDTH) / (LCU_WIDTH >> MAX_DEPTH);
|
|
||||||
uint16_t abs_y_ctb = y_ctb + (state->tile->lcu_offset_y * LCU_WIDTH) / (LCU_WIDTH >> MAX_DEPTH);
|
|
||||||
|
|
||||||
// Check for slice border FIXME
|
|
||||||
uint8_t border_x = ((state->encoder_control->in.width) < (abs_x_ctb * (LCU_WIDTH >> MAX_DEPTH) + (LCU_WIDTH >> depth))) ? 1 : 0;
|
|
||||||
uint8_t border_y = ((state->encoder_control->in.height) < (abs_y_ctb * (LCU_WIDTH >> MAX_DEPTH) + (LCU_WIDTH >> depth))) ? 1 : 0;
|
|
||||||
uint8_t border_split_x = ((state->encoder_control->in.width) < ((abs_x_ctb + 1) * (LCU_WIDTH >> MAX_DEPTH) + (LCU_WIDTH >> (depth + 1)))) ? 0 : 1;
|
|
||||||
uint8_t border_split_y = ((state->encoder_control->in.height) < ((abs_y_ctb + 1) * (LCU_WIDTH >> MAX_DEPTH) + (LCU_WIDTH >> (depth + 1)))) ? 0 : 1;
|
|
||||||
uint8_t border = border_x | border_y; /*!< are we in any border CU */
|
|
||||||
|
|
||||||
// When not in MAX_DEPTH, insert split flag and split the blocks if needed
|
|
||||||
if (depth != MAX_DEPTH) {
|
|
||||||
// Implisit split flag when on border
|
|
||||||
if (!border) {
|
|
||||||
// Get left and top block split_flags and if they are present and true, increase model number
|
|
||||||
if (x_ctb > 0 && GET_SPLITDATA(kvz_videoframe_get_cu_const(frame, x_ctb - 1, y_ctb), depth) == 1) {
|
|
||||||
split_model++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (y_ctb > 0 && GET_SPLITDATA(kvz_videoframe_get_cu_const(frame, x_ctb, y_ctb - 1), depth) == 1) {
|
|
||||||
split_model++;
|
|
||||||
}
|
|
||||||
|
|
||||||
cabac->cur_ctx = &(cabac->ctx.split_flag_model[split_model]);
|
|
||||||
CABAC_BIN(cabac, split_flag, "SplitFlag");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (split_flag || border) {
|
|
||||||
// Split blocks and remember to change x and y block positions
|
|
||||||
uint8_t change = 1<<(MAX_DEPTH-1-depth);
|
|
||||||
kvz_encode_coding_tree(state, x_ctb, y_ctb, depth + 1); // x,y
|
|
||||||
|
|
||||||
// TODO: fix when other half of the block would not be completely over the border
|
|
||||||
if (!border_x || border_split_x) {
|
|
||||||
kvz_encode_coding_tree(state, x_ctb + change, y_ctb, depth + 1);
|
|
||||||
}
|
|
||||||
if (!border_y || border_split_y) {
|
|
||||||
kvz_encode_coding_tree(state, x_ctb, y_ctb + change, depth + 1);
|
|
||||||
}
|
|
||||||
if (!border || (border_split_x && border_split_y)) {
|
|
||||||
kvz_encode_coding_tree(state, x_ctb + change, y_ctb + change, depth + 1);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Encode skip flag
|
|
||||||
if (state->global->slicetype != KVZ_SLICE_I) {
|
|
||||||
int8_t ctx_skip = 0; // uiCtxSkip = aboveskipped + leftskipped;
|
|
||||||
int ui;
|
|
||||||
int16_t num_cand = MRG_MAX_NUM_CANDS;
|
|
||||||
// Get left and top skipped flags and if they are present and true, increase context number
|
|
||||||
if (x_ctb > 0 && (kvz_videoframe_get_cu_const(frame, x_ctb - 1, y_ctb))->skipped) {
|
|
||||||
ctx_skip++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (y_ctb > 0 && (kvz_videoframe_get_cu_const(frame, x_ctb, y_ctb - 1))->skipped) {
|
|
||||||
ctx_skip++;
|
|
||||||
}
|
|
||||||
|
|
||||||
cabac->cur_ctx = &(cabac->ctx.cu_skip_flag_model[ctx_skip]);
|
|
||||||
CABAC_BIN(cabac, cur_cu->skipped, "SkipFlag");
|
|
||||||
|
|
||||||
// IF SKIP
|
|
||||||
if (cur_cu->skipped) {
|
|
||||||
if (num_cand > 1) {
|
|
||||||
for (ui = 0; ui < num_cand - 1; ui++) {
|
|
||||||
int32_t symbol = (ui != cur_cu->merge_idx);
|
|
||||||
if (ui == 0) {
|
|
||||||
cabac->cur_ctx = &(cabac->ctx.cu_merge_idx_ext_model);
|
|
||||||
CABAC_BIN(cabac, symbol, "MergeIndex");
|
|
||||||
} else {
|
|
||||||
CABAC_BIN_EP(cabac,symbol,"MergeIndex");
|
|
||||||
}
|
|
||||||
if (symbol == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ENDIF SKIP
|
|
||||||
|
|
||||||
// Prediction mode
|
|
||||||
if (state->global->slicetype != KVZ_SLICE_I) {
|
|
||||||
cabac->cur_ctx = &(cabac->ctx.cu_pred_mode_model);
|
|
||||||
CABAC_BIN(cabac, (cur_cu->type == CU_INTRA), "PredMode");
|
|
||||||
}
|
|
||||||
|
|
||||||
// part_mode
|
|
||||||
if (cur_cu->type == CU_INTRA) {
|
|
||||||
if (depth == MAX_DEPTH) {
|
|
||||||
cabac->cur_ctx = &(cabac->ctx.part_size_model[0]);
|
|
||||||
if (cur_cu->part_size == SIZE_2Nx2N) {
|
|
||||||
CABAC_BIN(cabac, 1, "part_mode 2Nx2N");
|
|
||||||
} else {
|
|
||||||
CABAC_BIN(cabac, 0, "part_mode NxN");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// TODO: Handle inter sizes other than 2Nx2N
|
|
||||||
cabac->cur_ctx = &(cabac->ctx.part_size_model[0]);
|
|
||||||
CABAC_BIN(cabac, 1, "part_mode 2Nx2N");
|
|
||||||
}
|
|
||||||
|
|
||||||
//end partsize
|
|
||||||
if (cur_cu->type == CU_INTER) {
|
|
||||||
// FOR each part
|
|
||||||
// Mergeflag
|
// Mergeflag
|
||||||
int16_t num_cand = 0;
|
int16_t num_cand = 0;
|
||||||
cabac->cur_ctx = &(cabac->ctx.cu_merge_flag_ext_model);
|
cabac->cur_ctx = &(cabac->ctx.cu_merge_flag_ext_model);
|
||||||
|
@ -1225,6 +1107,132 @@ void kvz_encode_coding_tree(encoder_state_t * const state,
|
||||||
}
|
}
|
||||||
} // for ref_list
|
} // for ref_list
|
||||||
} // if !merge
|
} // if !merge
|
||||||
|
}
|
||||||
|
|
||||||
|
void kvz_encode_coding_tree(encoder_state_t * const state,
|
||||||
|
uint16_t x_ctb, uint16_t y_ctb, uint8_t depth)
|
||||||
|
{
|
||||||
|
cabac_data_t * const cabac = &state->cabac;
|
||||||
|
const videoframe_t * const frame = state->tile->frame;
|
||||||
|
const cu_info_t *cur_cu = kvz_videoframe_get_cu_const(frame, x_ctb, y_ctb);
|
||||||
|
uint8_t split_flag = GET_SPLITDATA(cur_cu, depth);
|
||||||
|
uint8_t split_model = 0;
|
||||||
|
|
||||||
|
//Absolute ctb
|
||||||
|
uint16_t abs_x_ctb = x_ctb + (state->tile->lcu_offset_x * LCU_WIDTH) / (LCU_WIDTH >> MAX_DEPTH);
|
||||||
|
uint16_t abs_y_ctb = y_ctb + (state->tile->lcu_offset_y * LCU_WIDTH) / (LCU_WIDTH >> MAX_DEPTH);
|
||||||
|
|
||||||
|
// Check for slice border FIXME
|
||||||
|
uint8_t border_x = ((state->encoder_control->in.width) < (abs_x_ctb * (LCU_WIDTH >> MAX_DEPTH) + (LCU_WIDTH >> depth))) ? 1 : 0;
|
||||||
|
uint8_t border_y = ((state->encoder_control->in.height) < (abs_y_ctb * (LCU_WIDTH >> MAX_DEPTH) + (LCU_WIDTH >> depth))) ? 1 : 0;
|
||||||
|
uint8_t border_split_x = ((state->encoder_control->in.width) < ((abs_x_ctb + 1) * (LCU_WIDTH >> MAX_DEPTH) + (LCU_WIDTH >> (depth + 1)))) ? 0 : 1;
|
||||||
|
uint8_t border_split_y = ((state->encoder_control->in.height) < ((abs_y_ctb + 1) * (LCU_WIDTH >> MAX_DEPTH) + (LCU_WIDTH >> (depth + 1)))) ? 0 : 1;
|
||||||
|
uint8_t border = border_x | border_y; /*!< are we in any border CU */
|
||||||
|
|
||||||
|
// When not in MAX_DEPTH, insert split flag and split the blocks if needed
|
||||||
|
if (depth != MAX_DEPTH) {
|
||||||
|
// Implisit split flag when on border
|
||||||
|
if (!border) {
|
||||||
|
// Get left and top block split_flags and if they are present and true, increase model number
|
||||||
|
if (x_ctb > 0 && GET_SPLITDATA(kvz_videoframe_get_cu_const(frame, x_ctb - 1, y_ctb), depth) == 1) {
|
||||||
|
split_model++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y_ctb > 0 && GET_SPLITDATA(kvz_videoframe_get_cu_const(frame, x_ctb, y_ctb - 1), depth) == 1) {
|
||||||
|
split_model++;
|
||||||
|
}
|
||||||
|
|
||||||
|
cabac->cur_ctx = &(cabac->ctx.split_flag_model[split_model]);
|
||||||
|
CABAC_BIN(cabac, split_flag, "SplitFlag");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (split_flag || border) {
|
||||||
|
// Split blocks and remember to change x and y block positions
|
||||||
|
uint8_t change = 1<<(MAX_DEPTH-1-depth);
|
||||||
|
kvz_encode_coding_tree(state, x_ctb, y_ctb, depth + 1); // x,y
|
||||||
|
|
||||||
|
// TODO: fix when other half of the block would not be completely over the border
|
||||||
|
if (!border_x || border_split_x) {
|
||||||
|
kvz_encode_coding_tree(state, x_ctb + change, y_ctb, depth + 1);
|
||||||
|
}
|
||||||
|
if (!border_y || border_split_y) {
|
||||||
|
kvz_encode_coding_tree(state, x_ctb, y_ctb + change, depth + 1);
|
||||||
|
}
|
||||||
|
if (!border || (border_split_x && border_split_y)) {
|
||||||
|
kvz_encode_coding_tree(state, x_ctb + change, y_ctb + change, depth + 1);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Encode skip flag
|
||||||
|
if (state->global->slicetype != KVZ_SLICE_I) {
|
||||||
|
int8_t ctx_skip = 0; // uiCtxSkip = aboveskipped + leftskipped;
|
||||||
|
int ui;
|
||||||
|
int16_t num_cand = MRG_MAX_NUM_CANDS;
|
||||||
|
// Get left and top skipped flags and if they are present and true, increase context number
|
||||||
|
if (x_ctb > 0 && (kvz_videoframe_get_cu_const(frame, x_ctb - 1, y_ctb))->skipped) {
|
||||||
|
ctx_skip++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y_ctb > 0 && (kvz_videoframe_get_cu_const(frame, x_ctb, y_ctb - 1))->skipped) {
|
||||||
|
ctx_skip++;
|
||||||
|
}
|
||||||
|
|
||||||
|
cabac->cur_ctx = &(cabac->ctx.cu_skip_flag_model[ctx_skip]);
|
||||||
|
CABAC_BIN(cabac, cur_cu->skipped, "SkipFlag");
|
||||||
|
|
||||||
|
// IF SKIP
|
||||||
|
if (cur_cu->skipped) {
|
||||||
|
if (num_cand > 1) {
|
||||||
|
for (ui = 0; ui < num_cand - 1; ui++) {
|
||||||
|
int32_t symbol = (ui != cur_cu->merge_idx);
|
||||||
|
if (ui == 0) {
|
||||||
|
cabac->cur_ctx = &(cabac->ctx.cu_merge_idx_ext_model);
|
||||||
|
CABAC_BIN(cabac, symbol, "MergeIndex");
|
||||||
|
} else {
|
||||||
|
CABAC_BIN_EP(cabac,symbol,"MergeIndex");
|
||||||
|
}
|
||||||
|
if (symbol == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ENDIF SKIP
|
||||||
|
|
||||||
|
// Prediction mode
|
||||||
|
if (state->global->slicetype != KVZ_SLICE_I) {
|
||||||
|
cabac->cur_ctx = &(cabac->ctx.cu_pred_mode_model);
|
||||||
|
CABAC_BIN(cabac, (cur_cu->type == CU_INTRA), "PredMode");
|
||||||
|
}
|
||||||
|
|
||||||
|
// part_mode
|
||||||
|
if (cur_cu->type == CU_INTRA) {
|
||||||
|
if (depth == MAX_DEPTH) {
|
||||||
|
cabac->cur_ctx = &(cabac->ctx.part_size_model[0]);
|
||||||
|
if (cur_cu->part_size == SIZE_2Nx2N) {
|
||||||
|
CABAC_BIN(cabac, 1, "part_mode 2Nx2N");
|
||||||
|
} else {
|
||||||
|
CABAC_BIN(cabac, 0, "part_mode NxN");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// TODO: Handle inter sizes other than 2Nx2N
|
||||||
|
cabac->cur_ctx = &(cabac->ctx.part_size_model[0]);
|
||||||
|
CABAC_BIN(cabac, 1, "part_mode 2Nx2N");
|
||||||
|
}
|
||||||
|
|
||||||
|
//end partsize
|
||||||
|
if (cur_cu->type == CU_INTER) {
|
||||||
|
// FOR each part
|
||||||
|
encode_inter_prediction_unit(state, cabac, cur_cu, x_ctb, y_ctb, depth);
|
||||||
|
// END for each part
|
||||||
|
|
||||||
{
|
{
|
||||||
int cbf = (cbf_is_set(cur_cu->cbf.y, depth) ||
|
int cbf = (cbf_is_set(cur_cu->cbf.y, depth) ||
|
||||||
|
@ -1243,8 +1251,6 @@ void kvz_encode_coding_tree(encoder_state_t * const state,
|
||||||
kvz_encode_transform_coeff(state, x_ctb * 2, y_ctb * 2, depth, 0, 0, 0);
|
kvz_encode_transform_coeff(state, x_ctb * 2, y_ctb * 2, depth, 0, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// END for each part
|
|
||||||
} else if (cur_cu->type == CU_INTRA) {
|
} else if (cur_cu->type == CU_INTRA) {
|
||||||
uint8_t intra_pred_mode[4] = {
|
uint8_t intra_pred_mode[4] = {
|
||||||
cur_cu->intra[0].mode, cur_cu->intra[1].mode,
|
cur_cu->intra[0].mode, cur_cu->intra[1].mode,
|
||||||
|
|
Loading…
Reference in a new issue