mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-12-18 03:04:06 +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;
|
||||
}
|
||||
|
||||
|
||||
void kvz_encode_coding_tree(encoder_state_t * const state,
|
||||
uint16_t x_ctb, uint16_t y_ctb, uint8_t depth)
|
||||
static void encode_inter_prediction_unit(encoder_state_t * const state,
|
||||
cabac_data_t * const cabac,
|
||||
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
|
||||
int16_t num_cand = 0;
|
||||
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
|
||||
} // 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) ||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
// END for each part
|
||||
} else if (cur_cu->type == CU_INTRA) {
|
||||
uint8_t intra_pred_mode[4] = {
|
||||
cur_cu->intra[0].mode, cur_cu->intra[1].mode,
|
||||
|
|
Loading…
Reference in a new issue