mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-11-27 19:24:06 +00:00
Added multi_ref_idx variable for intra coding (is 0 throughout the code for now). Modified prediction flag writing. Chroma pred flag remains unchanged (ToDo). Added bitstream debug printing on VERBOSE mode.
This commit is contained in:
parent
ed4e218702
commit
5b46fbd878
|
@ -266,8 +266,16 @@ void kvz_bitstream_put_se(bitstream_t *stream, int32_t data)
|
|||
void kvz_bitstream_add_rbsp_trailing_bits(bitstream_t * const stream)
|
||||
{
|
||||
kvz_bitstream_put(stream, 1, 1);
|
||||
#if VERBOSE
|
||||
printf("%-40s u(%d) : %d\n", "rbsp_stop_one_bit", 1, 1);
|
||||
#endif
|
||||
if ((stream->cur_bit & 7) != 0) {
|
||||
kvz_bitstream_put(stream, 0, 8 - (stream->cur_bit & 7));
|
||||
#if VERBOSE
|
||||
for (int i = 0; i < (8 - stream->cur_bit) & 7; i++) {
|
||||
printf("%-40s u(%d) : %d\n", "rbsp_alignment_zero_bit", 1, 0);
|
||||
}
|
||||
#endif
|
||||
kvz_bitstream_put(stream, 0, (8 - stream->cur_bit) & 7);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -287,6 +295,11 @@ void kvz_bitstream_align(bitstream_t * const stream)
|
|||
void kvz_bitstream_align_zero(bitstream_t * const stream)
|
||||
{
|
||||
if ((stream->cur_bit & 7) != 0) {
|
||||
kvz_bitstream_put(stream, 0, 8 - (stream->cur_bit & 7));
|
||||
#if VERBOSE
|
||||
for (int i = 0; i < (8 - stream->cur_bit) & 7; i++) {
|
||||
printf("%-40s u(%d) : %d\n", "rbsp_alignment_zero_bit", 1, 0);
|
||||
}
|
||||
#endif
|
||||
kvz_bitstream_put(stream, 0, (8 - stream->cur_bit) & 7);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ typedef struct
|
|||
cabac_ctx_t intra_subpart_model[2]; //!< \brief intra sub part context models
|
||||
cabac_ctx_t chroma_pred_model[3];
|
||||
cabac_ctx_t inter_dir[5];
|
||||
cabac_ctx_t qt_cbf_model_luma[4];
|
||||
cabac_ctx_t qt_cbf_model_luma[5];
|
||||
cabac_ctx_t qt_cbf_model_cr[2];
|
||||
cabac_ctx_t qt_cbf_model_cb[5];
|
||||
cabac_ctx_t cu_qp_delta_abs[3];
|
||||
|
@ -85,6 +85,7 @@ typedef struct
|
|||
cabac_ctx_t mvp_idx_model[2];
|
||||
cabac_ctx_t cu_qt_root_cbf_model;
|
||||
cabac_ctx_t sig_coeff_group_model[8];
|
||||
cabac_ctx_t luma_planar_model[2];
|
||||
} ctx;
|
||||
} cabac_data_t;
|
||||
|
||||
|
|
|
@ -78,6 +78,13 @@ static const uint8_t INIT_INTRA_PRED_MODE[4] = {
|
|||
154, 154, 170, 6
|
||||
};
|
||||
|
||||
static const uint8_t INIT_INTRA_LUMA_PLANAR_MODE[4][2] = {
|
||||
{ 125, 125, },
|
||||
{ 139, 139, },
|
||||
{ 110, 154, },
|
||||
{ 4, 5, },
|
||||
};
|
||||
|
||||
static const uint8_t INIT_CHROMA_PRED_MODE[4][3] = {
|
||||
{ 137, 139, 140, },
|
||||
{ 138, 139, 169, },
|
||||
|
@ -345,10 +352,11 @@ void kvz_init_contexts(encoder_state_t *state, int8_t QP, int8_t slice)
|
|||
kvz_ctx_init(&cabac->ctx.cu_qt_root_cbf_model, QP, INIT_QT_ROOT_CBF[slice][0], INIT_QT_ROOT_CBF[3][0]);
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
kvz_ctx_init(&cabac->ctx.qt_cbf_model_cr[i], QP, INIT_QT_CBF[slice][i + 9], INIT_QT_CBF[3][i + 9]);
|
||||
kvz_ctx_init(&cabac->ctx.qt_cbf_model_cr[i], QP, INIT_QT_CBF[slice][i + 10], INIT_QT_CBF[3][i + 10]);
|
||||
kvz_ctx_init(&cabac->ctx.cu_mvd_model[i], QP, INIT_MVD[slice][i], INIT_MVD[3][i]);
|
||||
kvz_ctx_init(&cabac->ctx.cu_ref_pic_model[i], QP, INIT_REF_PIC[slice][i], INIT_REF_PIC[3][i]);
|
||||
kvz_ctx_init(&cabac->ctx.mvp_idx_model[i], QP, INIT_MVP_IDX[slice][i], INIT_MVP_IDX[3][i]);
|
||||
kvz_ctx_init(&cabac->ctx.luma_planar_model[i], QP, INIT_INTRA_LUMA_PLANAR_MODE[slice][i], INIT_INTRA_LUMA_PLANAR_MODE[3][i]);
|
||||
|
||||
}
|
||||
|
||||
|
@ -357,7 +365,7 @@ void kvz_init_contexts(encoder_state_t *state, int8_t QP, int8_t slice)
|
|||
}
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
kvz_ctx_init(&cabac->ctx.qt_cbf_model_luma[i], QP, INIT_QT_CBF[slice][i], INIT_QT_CBF[3][i]);
|
||||
|
||||
kvz_ctx_init(&cabac->ctx.part_size_model[i], QP, INIT_PART_SIZE[slice][i], INIT_PART_SIZE[3][i]);
|
||||
|
||||
kvz_ctx_init(&cabac->ctx.cu_ctx_last_y_chroma[i], QP, INIT_LAST_X[slice][i + 25], INIT_LAST_X[3][i + 25]);
|
||||
|
@ -365,7 +373,8 @@ void kvz_init_contexts(encoder_state_t *state, int8_t QP, int8_t slice)
|
|||
}
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
kvz_ctx_init(&cabac->ctx.qt_cbf_model_cb[i], QP, INIT_QT_CBF[slice][i + 4], INIT_QT_CBF[3][i + 4]);
|
||||
kvz_ctx_init(&cabac->ctx.qt_cbf_model_luma[i], QP, INIT_QT_CBF[slice][i], INIT_QT_CBF[3][i]);
|
||||
kvz_ctx_init(&cabac->ctx.qt_cbf_model_cb[i], QP, INIT_QT_CBF[slice][i + 5], INIT_QT_CBF[3][i + 5]);
|
||||
|
||||
kvz_ctx_init(&cabac->ctx.inter_dir[i], QP, INIT_INTER_DIR[slice][i], INIT_INTER_DIR[3][i]);
|
||||
}
|
||||
|
|
1
src/cu.h
1
src/cu.h
|
@ -143,6 +143,7 @@ typedef struct
|
|||
#if KVZ_SEL_ENCRYPTION
|
||||
int8_t mode_encry;
|
||||
#endif
|
||||
uint8_t multi_ref_idx;
|
||||
} intra;
|
||||
struct {
|
||||
int16_t mv[2][2]; // \brief Motion vectors for L0 and L1
|
||||
|
|
|
@ -975,11 +975,28 @@ static void encode_intra_coding_unit(encoder_state_t * const state,
|
|||
#endif
|
||||
|
||||
// Intra Subpartition mode
|
||||
bool enough_samples = kvz_g_convert_to_bit[(LCU_WIDTH >> depth)] * 2 > kvz_g_convert_to_bit[4 /* MIN_TB_SIZEY*/];
|
||||
uint32_t width = (LCU_WIDTH >> depth);
|
||||
uint32_t height = (LCU_WIDTH >> depth);
|
||||
|
||||
bool enough_samples = kvz_g_convert_to_bit[width] + kvz_g_convert_to_bit[height] > (kvz_g_convert_to_bit[4 /* MIN_TB_SIZEY*/] << 1);
|
||||
uint8_t isp_mode = 0;
|
||||
// ToDo: add height comparison
|
||||
isp_mode += ((width > TR_MAX_WIDTH) || !enough_samples) ? 1 : 0;
|
||||
isp_mode += ((height > TR_MAX_WIDTH) || !enough_samples) ? 2 : 0;
|
||||
bool allow_isp = enough_samples;
|
||||
if (allow_isp) {
|
||||
cabac->cur_ctx = &(cabac->ctx.intra_subpart_model[0]);
|
||||
CABAC_BIN(cabac, 0, "intra_subPartitions");
|
||||
if (isp_mode != 0) {
|
||||
if (isp_mode) {
|
||||
cabac->cur_ctx = &(cabac->ctx.intra_subpart_model[0]);
|
||||
CABAC_BIN(cabac, 0, "intra_subPartitions");
|
||||
} else {
|
||||
cabac->cur_ctx = &(cabac->ctx.intra_subpart_model[0]);
|
||||
CABAC_BIN(cabac, 1, "intra_subPartitions");
|
||||
// ToDo: complete this if-clause
|
||||
if (isp_mode == 3) {
|
||||
cabac->cur_ctx = &(cabac->ctx.intra_subpart_model[1]);
|
||||
CABAC_BIN(cabac, allow_isp - 1, "intra_subPart_ver_hor");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PREDINFO CODING
|
||||
|
@ -990,6 +1007,7 @@ static void encode_intra_coding_unit(encoder_state_t * const state,
|
|||
const int num_pred_units = kvz_part_mode_num_parts[cur_cu->part_size];
|
||||
const int cu_width = LCU_WIDTH >> depth;
|
||||
|
||||
cabac->cur_ctx = &(cabac->ctx.intra_mode_model);
|
||||
for (int j = 0; j < num_pred_units; ++j) {
|
||||
const int pu_x = PU_GET_X(cur_cu->part_size, cu_width, x, j);
|
||||
const int pu_y = PU_GET_Y(cur_cu->part_size, cu_width, y, j);
|
||||
|
@ -1024,18 +1042,26 @@ static void encode_intra_coding_unit(encoder_state_t * const state,
|
|||
}
|
||||
}
|
||||
flag[j] = (mpm_preds[j] == -1) ? 0 : 1;
|
||||
|
||||
if (!(cur_pu->intra.multi_ref_idx || (isp_mode))) {
|
||||
CABAC_BIN(cabac, flag[j], "prev_intra_luma_pred_flag");
|
||||
}
|
||||
}
|
||||
|
||||
cabac->cur_ctx = &(cabac->ctx.intra_mode_model);
|
||||
for (int j = 0; j < num_pred_units; ++j) {
|
||||
CABAC_BIN(cabac, flag[j], "prev_intra_luma_pred_flag");
|
||||
}
|
||||
|
||||
|
||||
|
||||
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 ? 1 : 0), "mpm_idx");
|
||||
|
||||
const int pu_x = PU_GET_X(cur_cu->part_size, cu_width, x, j);
|
||||
const int pu_y = PU_GET_Y(cur_cu->part_size, cu_width, y, j);
|
||||
const cu_info_t *cur_pu = kvz_cu_array_at_const(frame->cu_array, pu_x, pu_y);
|
||||
cabac->cur_ctx = &(cabac->ctx.luma_planar_model[(isp_mode ? 0 : 1)]);
|
||||
if (cur_pu->intra.multi_ref_idx == 0) {
|
||||
CABAC_BIN(cabac, (mpm_preds[j] > 0 ? 1 : 0), "mpm_idx_luma_planar");
|
||||
}
|
||||
//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) {
|
||||
|
@ -1093,45 +1119,68 @@ static void encode_intra_coding_unit(encoder_state_t * const state,
|
|||
|
||||
// Code chroma prediction mode.
|
||||
if (state->encoder_control->chroma_format != KVZ_CSP_400) {
|
||||
unsigned pred_mode = 67;
|
||||
unsigned chroma_pred_modes[4] = {0, 50, 18, 1};
|
||||
unsigned pred_mode = 0;
|
||||
unsigned chroma_pred_modes[8] = {0, 50, 18, 1, 67, 68, 69, 70};
|
||||
const int pu_x = PU_GET_X(cur_cu->part_size, cu_width, x, 0);
|
||||
const int pu_y = PU_GET_Y(cur_cu->part_size, cu_width, y, 0);
|
||||
const cu_info_t *first_pu = kvz_cu_array_at_const(frame->cu_array, pu_x, pu_y);
|
||||
int8_t chroma_intra_dir = first_pu->intra.mode_chroma;
|
||||
int8_t luma_intra_dir = first_pu->intra.mode;
|
||||
|
||||
if (intra_pred_mode_chroma == intra_pred_mode_actual[0]) {
|
||||
pred_mode = 68;
|
||||
} else if (intra_pred_mode_chroma == 66) {
|
||||
// Angular 66 mode is possible only if intra pred mode is one of the
|
||||
// possible chroma pred modes, in which case it is signaled with that
|
||||
// duplicate mode.
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
if (intra_pred_mode_actual[0] == chroma_pred_modes[i]) pred_mode = i;
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
if (intra_pred_mode_chroma == chroma_pred_modes[i]) pred_mode = i;
|
||||
}
|
||||
}
|
||||
|
||||
// pred_mode == 67 mean intra_pred_mode_chroma is something that can't
|
||||
// be coded.
|
||||
assert(pred_mode != 67);
|
||||
|
||||
/**
|
||||
* Table 9-35 - Binarization for intra_chroma_pred_mode
|
||||
* intra_chroma_pred_mode bin_string
|
||||
* 4 0
|
||||
* 0 100
|
||||
* 1 101
|
||||
* 2 110
|
||||
* 3 111
|
||||
* Table 9-37 - Assignment of ctxInc to syntax elements with context coded bins
|
||||
* intra_chroma_pred_mode[][] = 0, bypass, bypass
|
||||
*/
|
||||
bool derived_mode = chroma_intra_dir == 70;
|
||||
cabac->cur_ctx = &(cabac->ctx.chroma_pred_model[0]);
|
||||
if (pred_mode == 68) {
|
||||
CABAC_BIN(cabac, 0, "intra_chroma_pred_mode");
|
||||
} else {
|
||||
CABAC_BIN(cabac, 1, "intra_chroma_pred_mode");
|
||||
CABAC_BINS_EP(cabac, pred_mode, 2, "intra_chroma_pred_mode");
|
||||
CABAC_BIN(cabac, derived_mode ? 0 : 1, "intra_chroma_pred_mode");
|
||||
|
||||
|
||||
if (!derived_mode) {
|
||||
/*for (int i = 0; i < 4; i++) {
|
||||
if (luma_intra_dir == chroma_pred_modes[i]) {
|
||||
chroma_pred_modes[i] = 66;
|
||||
break;
|
||||
}
|
||||
}*/
|
||||
for (; pred_mode < 8; pred_mode++) {
|
||||
if (chroma_intra_dir == chroma_pred_modes[pred_mode]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*else if (intra_pred_mode_chroma == 66) {
|
||||
// Angular 66 mode is possible only if intra pred mode is one of the
|
||||
// possible chroma pred modes, in which case it is signaled with that
|
||||
// duplicate mode.
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
if (intra_pred_mode_actual[0] == chroma_pred_modes[i]) pred_mode = i;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
if (intra_pred_mode_chroma == chroma_pred_modes[i]) pred_mode = i;
|
||||
}
|
||||
}
|
||||
|
||||
// pred_mode == 67 mean intra_pred_mode_chroma is something that can't
|
||||
// be coded.
|
||||
assert(pred_mode != 67);
|
||||
*/
|
||||
/**
|
||||
* Table 9-35 - Binarization for intra_chroma_pred_mode
|
||||
* intra_chroma_pred_mode bin_string
|
||||
* 4 0
|
||||
* 0 100
|
||||
* 1 101
|
||||
* 2 110
|
||||
* 3 111
|
||||
* Table 9-37 - Assignment of ctxInc to syntax elements with context coded bins
|
||||
* intra_chroma_pred_mode[][] = 0, bypass, bypass
|
||||
*/
|
||||
/*cabac->cur_ctx = &(cabac->ctx.chroma_pred_model[0]);
|
||||
if (pred_mode == 68) {
|
||||
CABAC_BIN(cabac, 0, "intra_chroma_pred_mode");
|
||||
}
|
||||
else {
|
||||
CABAC_BIN(cabac, 1, "intra_chroma_pred_mode");*/
|
||||
CABAC_BINS_EP(cabac, pred_mode, 2, "intra_chroma_pred_mode");
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1311,10 +1360,10 @@ void kvz_encode_coding_tree(encoder_state_t * const state,
|
|||
|
||||
bool allow_split = qt_split | bh_split | bv_split | th_split | tv_split;
|
||||
|
||||
|
||||
if (no_split && allow_split) {
|
||||
|
||||
split_model = 0;
|
||||
|
||||
|
||||
// Get left and top block split_flags and if they are present and true, increase model number
|
||||
// ToDo: should use height and width to increase model, PU_GET_W() ?
|
||||
if (left_cu && GET_SPLITDATA(left_cu, depth) == 1) {
|
||||
|
@ -1337,8 +1386,9 @@ void kvz_encode_coding_tree(encoder_state_t * const state,
|
|||
split_model += 3 * (split_num >> 1);
|
||||
|
||||
cabac->cur_ctx = &(cabac->ctx.split_flag_model[split_model]);
|
||||
CABAC_BIN(cabac, split_flag, "SplitFlag");
|
||||
CABAC_BIN(cabac, !(implicit_split_mode == KVZ_NO_SPLIT), "SplitFlag");
|
||||
}
|
||||
if (implicit_split_mode == KVZ_NO_SPLIT) return;
|
||||
|
||||
if (!split_flag) return;
|
||||
|
||||
|
|
|
@ -104,11 +104,16 @@
|
|||
typedef int16_t coeff_t;
|
||||
|
||||
//#define VERBOSE 1
|
||||
//#define KVZ_DEBUG_PRINT_CABAC 1
|
||||
//#define KVZ_DEBUG 1
|
||||
|
||||
/* CONFIG VARIABLES */
|
||||
|
||||
//spec: references to variables defined in Rec. ITU-T H.265 (04/2013)
|
||||
|
||||
// VVC flags
|
||||
#define RDPCM 1
|
||||
|
||||
//! Limits for prediction block sizes. 0 = 64x64, 4 = 4x4.
|
||||
#define PU_DEPTH_INTER_MIN 0
|
||||
#define PU_DEPTH_INTER_MAX 3
|
||||
|
|
12
src/nal.c
12
src/nal.c
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include "bitstream.h"
|
||||
#include "strategies/strategies-nal.h"
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
/**
|
||||
|
@ -36,6 +37,10 @@ void kvz_nal_write(bitstream_t * const bitstream, const uint8_t nal_type,
|
|||
const uint8_t start_code_prefix_one_3bytes = 0x01;
|
||||
const uint8_t zero = 0x00;
|
||||
|
||||
#ifdef KVZ_DEBUG
|
||||
printf("=========== NAL unit ===========\n");
|
||||
#endif
|
||||
|
||||
// zero_byte (0x00) shall be present in the byte stream NALU of VPS, SPS
|
||||
// and PPS, or the first NALU of an access unit
|
||||
if(long_start_code)
|
||||
|
@ -54,6 +59,13 @@ void kvz_nal_write(bitstream_t * const bitstream, const uint8_t nal_type,
|
|||
// 5bits of nuh_layer_id + nuh_temporal_id_plus1(3)
|
||||
byte = (temporal_id + 1) & 7;
|
||||
kvz_bitstream_writebyte(bitstream, byte);
|
||||
|
||||
#if VERBOSE
|
||||
printf("%-40s u(%d) : %d\n", "forbidden_zero_bit", 1, 0);
|
||||
printf("%-40s u(%d) : %d\n", "nal_unit_type", 6, nal_type);
|
||||
printf("%-40s u(%d) : %d\n", "nuh_layer_id", 6, temporal_id);
|
||||
printf("%-40s u(%d) : %d\n", "nuh_temporal_id", 3, temporal_id + 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
|
@ -417,6 +417,7 @@ static double search_cu(encoder_state_t * const state, int x, int y, int depth,
|
|||
cur_cu->type = CU_NOTSET;
|
||||
cur_cu->part_size = SIZE_2Nx2N;
|
||||
cur_cu->qp = state->qp;
|
||||
cur_cu->intra.multi_ref_idx = 0;
|
||||
|
||||
// If the CU is completely inside the frame at this depth, search for
|
||||
// prediction modes at this depth.
|
||||
|
|
Loading…
Reference in a new issue