mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-11-23 18:14:06 +00:00
Changed intra coding to use 6 MPM, implemented merge sort and MPM selection
This commit is contained in:
parent
1081336868
commit
d15f58517f
|
@ -966,7 +966,7 @@ static void encode_intra_coding_unit(encoder_state_t * const state,
|
|||
uint8_t *intra_pred_mode = intra_pred_mode_actual;
|
||||
|
||||
uint8_t intra_pred_mode_chroma = cur_cu->intra.mode_chroma;
|
||||
int8_t intra_preds[4][3] = {{-1, -1, -1},{-1, -1, -1},{-1, -1, -1},{-1, -1, -1}};
|
||||
int8_t intra_preds[4][INTRA_MPM_COUNT] = {{-1, -1, -1, -1, -1, -1},{-1, -1, -1, -1, -1, -1},{-1, -1, -1, -1, -1, -1},{-1, -1, -1, -1, -1, -1}};
|
||||
int8_t mpm_preds[4] = {-1, -1, -1, -1};
|
||||
uint32_t flag[4];
|
||||
|
||||
|
@ -987,6 +987,7 @@ static void encode_intra_coding_unit(encoder_state_t * const state,
|
|||
// If intra prediction mode is found from the predictors,
|
||||
// it can be signaled with two EP's. Otherwise we can send
|
||||
// 5 EP bins with the full predmode
|
||||
// ToDo: fix comments for VVC
|
||||
const int num_pred_units = kvz_part_mode_num_parts[cur_cu->part_size];
|
||||
const int cu_width = LCU_WIDTH >> depth;
|
||||
|
||||
|
@ -1017,7 +1018,7 @@ static void encode_intra_coding_unit(encoder_state_t * const state,
|
|||
|
||||
intra_pred_mode_actual[j] = cur_pu->intra.mode;
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
for (int i = 0; i < INTRA_MPM_COUNT; i++) {
|
||||
if (intra_preds[j][i] == intra_pred_mode[j]) {
|
||||
mpm_preds[j] = (int8_t)i;
|
||||
break;
|
||||
|
@ -1035,28 +1036,59 @@ static void encode_intra_coding_unit(encoder_state_t * const state,
|
|||
for (int j = 0; j < num_pred_units; ++j) {
|
||||
// Signal index of the prediction mode in the prediction list.
|
||||
if (flag[j]) {
|
||||
CABAC_BIN_EP(cabac, (mpm_preds[j] == 0 ? 0 : 1), "mpm_idx");
|
||||
if (mpm_preds[j] != 0) {
|
||||
CABAC_BIN_EP(cabac, (mpm_preds[j] == 1 ? 0 : 1), "mpm_idx");
|
||||
CABAC_BIN_EP(cabac, (mpm_preds[j] > 0 ? 1 : 0), "mpm_idx");
|
||||
if (mpm_preds[j] > 0) {
|
||||
CABAC_BIN_EP(cabac, (mpm_preds[j] > 1 ? 1 : 0), "mpm_idx");
|
||||
} else if (mpm_preds[j] > 1) {
|
||||
CABAC_BIN_EP(cabac, (mpm_preds[j] > 2 ? 1 : 0), "mpm_idx");
|
||||
} else if (mpm_preds[j] > 2) {
|
||||
CABAC_BIN_EP(cabac, (mpm_preds[j] > 3 ? 1 : 0), "mpm_idx");
|
||||
} else if (mpm_preds[j] > 3) {
|
||||
CABAC_BIN_EP(cabac, (mpm_preds[j] > 4 ? 1 : 0), "mpm_idx");
|
||||
}
|
||||
} else {
|
||||
|
||||
// Signal the actual prediction mode.
|
||||
int32_t tmp_pred = intra_pred_mode[j];
|
||||
|
||||
uint8_t intra_preds_temp[INTRA_MPM_COUNT+2];
|
||||
memcpy(intra_preds_temp, intra_preds[j], sizeof(int8_t)*3);
|
||||
memcpy(intra_preds_temp+4, &intra_preds[j][3], sizeof(int8_t)*3);
|
||||
intra_preds_temp[3] = 255;
|
||||
intra_preds_temp[7] = 255;
|
||||
|
||||
// Improvised merge sort
|
||||
// Sort prediction list from lowest to highest.
|
||||
if (intra_preds[j][0] > intra_preds[j][1]) SWAP(intra_preds[j][0], intra_preds[j][1], int8_t);
|
||||
if (intra_preds[j][0] > intra_preds[j][2]) SWAP(intra_preds[j][0], intra_preds[j][2], int8_t);
|
||||
if (intra_preds[j][1] > intra_preds[j][2]) SWAP(intra_preds[j][1], intra_preds[j][2], int8_t);
|
||||
if (intra_preds_temp[0] > intra_preds_temp[1]) SWAP(intra_preds_temp[0], intra_preds_temp[1], int8_t);
|
||||
if (intra_preds_temp[0] > intra_preds_temp[2]) SWAP(intra_preds_temp[0], intra_preds_temp[2], int8_t);
|
||||
if (intra_preds_temp[1] > intra_preds_temp[2]) SWAP(intra_preds_temp[1], intra_preds_temp[2], int8_t);
|
||||
|
||||
if (intra_preds_temp[4] > intra_preds_temp[5]) SWAP(intra_preds_temp[4], intra_preds_temp[5], int8_t);
|
||||
if (intra_preds_temp[4] > intra_preds_temp[6]) SWAP(intra_preds_temp[4], intra_preds_temp[6], int8_t);
|
||||
if (intra_preds_temp[5] > intra_preds_temp[6]) SWAP(intra_preds_temp[5], intra_preds_temp[6], int8_t);
|
||||
|
||||
// Merge two subarrays
|
||||
int32_t array1 = 0;
|
||||
int32_t array2 = 4;
|
||||
for (int item = 0; item < INTRA_MPM_COUNT; item++) {
|
||||
if (intra_preds_temp[array1] < intra_preds_temp[array2]) {
|
||||
intra_preds[j][item] = intra_preds_temp[array1];
|
||||
array1++;
|
||||
} else {
|
||||
intra_preds[j][item] = intra_preds_temp[array2];
|
||||
array2++;
|
||||
}
|
||||
}
|
||||
|
||||
// Reduce the index of the signaled prediction mode according to the
|
||||
// prediction list, as it has been already signaled that it's not one
|
||||
// of the prediction modes.
|
||||
for (int i = 2; i >= 0; i--) {
|
||||
tmp_pred = (tmp_pred > intra_preds[j][i] ? tmp_pred - 1 : tmp_pred);
|
||||
for (int i = INTRA_MPM_COUNT-1; i >= 0; i--) {
|
||||
if (tmp_pred > intra_preds[j][i]) {
|
||||
tmp_pred--;
|
||||
}
|
||||
}
|
||||
|
||||
CABAC_BINS_EP(cabac, tmp_pred, 6, "rem_intra_luma_pred_mode");
|
||||
|
||||
kvz_cabac_encode_trunc_bin(cabac, tmp_pred, 67 - INTRA_MPM_COUNT);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -159,6 +159,12 @@ typedef int16_t coeff_t;
|
|||
#define LCU_LUMA_SIZE (LCU_WIDTH * LCU_WIDTH)
|
||||
#define LCU_CHROMA_SIZE (LCU_WIDTH * LCU_WIDTH >> 2)
|
||||
|
||||
/**
|
||||
* \brief Number of Most Probable Modes in Intra coding
|
||||
*
|
||||
*/
|
||||
#define INTRA_MPM_COUNT 6
|
||||
|
||||
/**
|
||||
* \brief Number of pixels to delay deblocking.
|
||||
*
|
||||
|
@ -185,7 +191,7 @@ typedef int16_t coeff_t;
|
|||
|
||||
#define AMVP_MAX_NUM_CANDS 2
|
||||
#define AMVP_MAX_NUM_CANDS_MEM 3
|
||||
#define MRG_MAX_NUM_CANDS 5
|
||||
#define MRG_MAX_NUM_CANDS 7
|
||||
|
||||
/* Some tools */
|
||||
#define ABS(a) ((a) >= 0 ? (a) : (-a))
|
||||
|
|
52
src/intra.c
52
src/intra.c
|
@ -77,13 +77,19 @@ int8_t kvz_intra_get_dir_luma_predictor(
|
|||
const cu_info_t *const left_pu,
|
||||
const cu_info_t *const above_pu)
|
||||
{
|
||||
// The default mode if block is not coded yet is INTRA_DC.
|
||||
int8_t left_intra_dir = 1;
|
||||
enum {
|
||||
PLANAR_IDX = 0,
|
||||
DC_IDX = 1,
|
||||
HOR_IDX = 18,
|
||||
VER_IDX = 50,
|
||||
};
|
||||
// The default mode if block is not coded yet is INTRA_PLANAR.
|
||||
int8_t left_intra_dir = 0;
|
||||
if (left_pu && left_pu->type == CU_INTRA) {
|
||||
left_intra_dir = left_pu->intra.mode;
|
||||
}
|
||||
|
||||
int8_t above_intra_dir = 1;
|
||||
int8_t above_intra_dir = 0;
|
||||
if (above_pu && above_pu->type == CU_INTRA && y % LCU_WIDTH != 0) {
|
||||
above_intra_dir = above_pu->intra.mode;
|
||||
}
|
||||
|
@ -91,26 +97,44 @@ int8_t kvz_intra_get_dir_luma_predictor(
|
|||
const int offset = 61;
|
||||
const int mod = 64;
|
||||
|
||||
preds[0] = left_intra_dir;
|
||||
preds[1] = (preds[0] == PLANAR_IDX) ? DC_IDX : PLANAR_IDX;
|
||||
preds[2] = VER_IDX;
|
||||
preds[3] = HOR_IDX;
|
||||
preds[4] = VER_IDX - 4;
|
||||
preds[5] = VER_IDX + 4;
|
||||
|
||||
// If the predictions are the same, add new predictions
|
||||
if (left_intra_dir == above_intra_dir) {
|
||||
if (left_intra_dir > 1) { // angular modes
|
||||
if (left_intra_dir > DC_IDX) { // angular modes
|
||||
preds[0] = left_intra_dir;
|
||||
preds[1] = ((left_intra_dir + offset) % mod) + 2;
|
||||
preds[2] = ((left_intra_dir - 1 ) % mod) + 2;
|
||||
} else { //non-angular
|
||||
preds[0] = 0;//PLANAR_IDX;
|
||||
preds[1] = 1;//DC_IDX;
|
||||
preds[2] = 50;//VER_IDX;
|
||||
preds[1] = PLANAR_IDX;
|
||||
preds[2] = DC_IDX;
|
||||
preds[3] = ((left_intra_dir + offset) % mod) + 2;
|
||||
preds[4] = ((left_intra_dir - 1) % mod) + 2;
|
||||
preds[5] = ((left_intra_dir + offset - 1) % mod) + 2;
|
||||
}
|
||||
} else { // If we have two distinct predictions
|
||||
preds[0] = left_intra_dir;
|
||||
preds[1] = above_intra_dir;
|
||||
bool max_cand_mode_idx = preds[0] > preds[1] ? 0 : 1;
|
||||
|
||||
if (left_intra_dir > DC_IDX && above_intra_dir > DC_IDX) {
|
||||
preds[2] = PLANAR_IDX;
|
||||
preds[3] = DC_IDX;
|
||||
|
||||
// add planar mode if it's not yet present
|
||||
if (left_intra_dir && above_intra_dir ) {
|
||||
preds[2] = 0; // PLANAR_IDX;
|
||||
if ((preds[max_cand_mode_idx] - preds[!max_cand_mode_idx] < 63) && (preds[max_cand_mode_idx] - preds[!max_cand_mode_idx] > 1)) {
|
||||
preds[4] = ((preds[max_cand_mode_idx] + offset) % mod) + 2;
|
||||
preds[5] = ((preds[max_cand_mode_idx] - 1) % mod) + 2;
|
||||
} else {
|
||||
preds[4] = ((preds[max_cand_mode_idx] + offset - 1) % mod) + 2;
|
||||
preds[5] = ((preds[max_cand_mode_idx]) % mod) + 2;
|
||||
}
|
||||
} else { // Add DC mode if it's not present, otherwise VER_IDX.
|
||||
preds[2] = (left_intra_dir+above_intra_dir)<2? 50 : 1;
|
||||
preds[2] = (preds[!max_cand_mode_idx] == PLANAR_IDX) ? DC_IDX : PLANAR_IDX;
|
||||
preds[3] = ((preds[max_cand_mode_idx] + offset) % mod) + 2;
|
||||
preds[4] = ((preds[max_cand_mode_idx] - 1) % mod) + 2;
|
||||
preds[5] = ((preds[max_cand_mode_idx] + offset - 1) % mod) + 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue