mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-11-23 18:14:06 +00:00
Merge branch 'stats-files'
# Conflicts: # src/cfg.c # src/cli.c # src/kvazaar.h
This commit is contained in:
commit
8143ab971c
|
@ -107,7 +107,10 @@ Options:
|
|||
- intra_pred_modes: Intra prediction modes.
|
||||
--key <string> : Encryption key [16,213,27,56,255,127,242,112,
|
||||
97,126,197,204,25,59,38,30]
|
||||
|
||||
--stats-file-prefix : A prefix used for stats files that include
|
||||
bits, lambda, distortion, and qp for each ctu.
|
||||
These are meant for debugging and are not
|
||||
written unless the prefix is defined.
|
||||
Video structure:
|
||||
-q, --qp <integer> : Quantization parameter [22]
|
||||
-p, --period <integer> : Period of intra pictures [64]
|
||||
|
|
|
@ -23,7 +23,7 @@ AC_CONFIG_SRCDIR([src/encmain.c])
|
|||
#
|
||||
# Here is a somewhat sane guide to lib versioning: http://apr.apache.org/versioning.html
|
||||
ver_major=6
|
||||
ver_minor=2
|
||||
ver_minor=3
|
||||
ver_release=0
|
||||
|
||||
# Prevents configure from adding a lot of defines to the CFLAGS
|
||||
|
|
|
@ -100,7 +100,12 @@ a list of features separated with a '+'. [off]
|
|||
\fB\-\-key <string>
|
||||
Encryption key [16,213,27,56,255,127,242,112,
|
||||
97,126,197,204,25,59,38,30]
|
||||
|
||||
.TP
|
||||
\fB\-\-stats\-file\-prefix
|
||||
A prefix used for stats files that include
|
||||
bits, lambda, distortion, and qp for each ctu.
|
||||
These are meant for debugging and are not
|
||||
written unless the prefix is defined.
|
||||
.SS "Video structure:"
|
||||
.TP
|
||||
\fB\-q\fR, \fB\-\-qp <integer>
|
||||
|
|
|
@ -165,6 +165,7 @@ int kvz_config_init(kvz_config *cfg)
|
|||
|
||||
cfg->file_format = KVZ_FORMAT_AUTO;
|
||||
|
||||
cfg->stats_file_prefix = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1374,6 +1375,9 @@ int kvz_config_parse(kvz_config *cfg, const char *name, const char *value)
|
|||
}
|
||||
cfg->file_format = file_format;
|
||||
}
|
||||
else if OPT("stats-file-prefix") {
|
||||
cfg->stats_file_prefix = strdup(value);
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -150,6 +150,7 @@ static const struct option long_options[] = {
|
|||
{ "clip-neighbour", no_argument, NULL, 0 },
|
||||
{ "no-clip-neighbour", no_argument, NULL, 0 },
|
||||
{ "input-file-format", required_argument, NULL, 0 },
|
||||
{ "stats-file-prefix", required_argument, NULL, 0 },
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
|
@ -433,6 +434,10 @@ void print_help(void)
|
|||
" - intra_pred_modes: Intra prediction modes.\n"
|
||||
" --key <string> : Encryption key [16,213,27,56,255,127,242,112,\n"
|
||||
" 97,126,197,204,25,59,38,30]\n"
|
||||
" --stats-file-prefix : A prefix used for stats files that include\n"
|
||||
" bits, lambda, distortion, and qp for each ctu.\n"
|
||||
" These are meant for debugging and are not\n"
|
||||
" written unless the prefix is defined.\n"
|
||||
"\n"
|
||||
/* Word wrap to this width to stay under 80 characters (including ") *************/
|
||||
"Video structure:\n"
|
||||
|
|
|
@ -1064,7 +1064,7 @@ static void encoder_state_write_bitstream_main(encoder_state_t * const state)
|
|||
state->frame->total_bits_coded = state->previous_encoder_state->frame->total_bits_coded;
|
||||
}
|
||||
state->frame->total_bits_coded += newpos - curpos;
|
||||
if(state->encoder_control->cfg.rc_algorithm == KVZ_OBA) {
|
||||
if(state->encoder_control->cfg.rc_algorithm == KVZ_OBA || state->encoder_control->cfg.stats_file_prefix) {
|
||||
kvz_update_after_picture(state);
|
||||
}
|
||||
|
||||
|
|
|
@ -64,6 +64,8 @@ typedef struct lcu_stats_t {
|
|||
//! \brief Lambda value which was used for this LCU
|
||||
double lambda;
|
||||
|
||||
double adjust_lambda;
|
||||
|
||||
//! \brief Rate control alpha parameter
|
||||
double rc_alpha;
|
||||
|
||||
|
@ -73,6 +75,7 @@ typedef struct lcu_stats_t {
|
|||
int i_cost;
|
||||
|
||||
int8_t qp;
|
||||
int8_t adjust_qp;
|
||||
uint8_t skipped;
|
||||
} lcu_stats_t;
|
||||
|
||||
|
|
|
@ -448,6 +448,8 @@ typedef struct kvz_config
|
|||
uint8_t clip_neighbour;
|
||||
|
||||
enum kvz_file_format file_format;
|
||||
|
||||
char *stats_file_prefix;
|
||||
} kvz_config;
|
||||
|
||||
/**
|
||||
|
|
|
@ -35,6 +35,11 @@ static const double MAX_LAMBDA = 10000;
|
|||
|
||||
static kvz_rc_data *data;
|
||||
|
||||
static FILE *dist_file;
|
||||
static FILE *bits_file;
|
||||
static FILE *qp_file;
|
||||
static FILE *lambda_file;
|
||||
|
||||
/**
|
||||
* \brief Clip lambda value to a valid range.
|
||||
*/
|
||||
|
@ -87,6 +92,17 @@ kvz_rc_data * kvz_get_rc_data(const encoder_control_t * const encoder) {
|
|||
|
||||
data->intra_alpha = 6.7542000000000000;
|
||||
data->intra_beta = 1.7860000000000000;
|
||||
if(encoder->cfg.stats_file_prefix) {
|
||||
char buff[128];
|
||||
sprintf(buff, "%sbits.txt", encoder->cfg.stats_file_prefix);
|
||||
bits_file = fopen(buff, "w");
|
||||
sprintf(buff, "%sdist.txt", encoder->cfg.stats_file_prefix);
|
||||
dist_file = fopen(buff, "w");
|
||||
sprintf(buff, "%sqp.txt", encoder->cfg.stats_file_prefix);
|
||||
qp_file = fopen(buff, "w");
|
||||
sprintf(buff, "%slambda.txt", encoder->cfg.stats_file_prefix);
|
||||
lambda_file = fopen(buff, "w");
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
|
@ -791,6 +807,8 @@ static double qp_to_lambda(encoder_state_t* const state, int qp)
|
|||
state->lambda = qp_to_lambda(state, state->qp);
|
||||
state->lambda_sqrt = sqrt(state->lambda);
|
||||
|
||||
ctu->adjust_lambda = state->lambda;
|
||||
ctu->adjust_qp = state->qp;
|
||||
//ctu->qp = state->qp;
|
||||
//ctu->lambda = state->lambda;
|
||||
}
|
||||
|
@ -854,6 +872,22 @@ static void update_ck(encoder_state_t * const state, int ctu_index, int layer)
|
|||
}
|
||||
|
||||
|
||||
static int calc_poc(encoder_state_t * const state) {
|
||||
const encoder_control_t * const encoder = state->encoder_control;
|
||||
if((encoder->cfg.open_gop && !encoder->cfg.gop_lowdelay) || !encoder->cfg.intra_period) {
|
||||
return state->frame->poc;
|
||||
}
|
||||
if(!encoder->cfg.gop_len || encoder->cfg.open_gop || encoder->cfg.intra_period == 1 || encoder->cfg.gop_lowdelay) {
|
||||
return state->frame->poc + state->frame->num / encoder->cfg.intra_period * encoder->cfg.intra_period;
|
||||
}
|
||||
if (!encoder->cfg.gop_lowdelay && !encoder->cfg.open_gop) {
|
||||
return state->frame->poc + state->frame->num / (encoder->cfg.intra_period + 1) * (encoder->cfg.intra_period + 1);
|
||||
}
|
||||
assert(0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
void kvz_update_after_picture(encoder_state_t * const state) {
|
||||
double total_distortion = 0;
|
||||
double lambda = 0;
|
||||
|
@ -875,6 +909,14 @@ void kvz_update_after_picture(encoder_state_t * const state) {
|
|||
pthread_mutex_unlock(&state->frame->new_ratecontrol->intra_lock);
|
||||
}
|
||||
|
||||
if (encoder->cfg.stats_file_prefix) {
|
||||
int poc = calc_poc(state);
|
||||
fprintf(dist_file, "%d %d %d\n", poc, encoder->in.width_in_lcu, encoder->in.height_in_lcu);
|
||||
fprintf(bits_file, "%d %d %d\n", poc, encoder->in.width_in_lcu, encoder->in.height_in_lcu);
|
||||
fprintf(qp_file, "%d %d %d\n", poc, encoder->in.width_in_lcu, encoder->in.height_in_lcu);
|
||||
fprintf(lambda_file, "%d %d %d\n", poc, encoder->in.width_in_lcu, encoder->in.height_in_lcu);
|
||||
}
|
||||
|
||||
for(int y_ctu = 0; y_ctu < state->encoder_control->in.height_in_lcu; y_ctu++) {
|
||||
for (int x_ctu = 0; x_ctu < state->encoder_control->in.width_in_lcu; x_ctu++) {
|
||||
int ctu_distortion = 0;
|
||||
|
@ -889,9 +931,23 @@ void kvz_update_after_picture(encoder_state_t * const state) {
|
|||
ctu->distortion = (double)ctu_distortion / ctu->pixels;
|
||||
total_distortion += (double)ctu_distortion / ctu->pixels;
|
||||
lambda += ctu->lambda / (state->encoder_control->in.width_in_lcu * state->encoder_control->in.height_in_lcu);
|
||||
}
|
||||
if(encoder->cfg.stats_file_prefix) {
|
||||
fprintf(dist_file, "%f ", ctu->distortion);
|
||||
fprintf(bits_file, "%d ", ctu->bits);
|
||||
fprintf(qp_file, "%d ", ctu->adjust_qp ? ctu->adjust_qp : ctu->qp);
|
||||
fprintf(lambda_file, "%f ", ctu->adjust_lambda ? ctu->adjust_lambda : ctu->lambda);
|
||||
}
|
||||
}
|
||||
if (encoder->cfg.stats_file_prefix) {
|
||||
fprintf(dist_file, "\n");
|
||||
fprintf(bits_file, "\n");
|
||||
fprintf(qp_file, "\n");
|
||||
fprintf(lambda_file, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
if(encoder->cfg.stats_file_prefix && encoder->cfg.rc_algorithm != KVZ_OBA) return;
|
||||
|
||||
total_distortion /= (state->encoder_control->in.height_in_lcu * state->encoder_control->in.width_in_lcu);
|
||||
if (state->frame->is_irap) {
|
||||
pthread_mutex_lock(&state->frame->new_ratecontrol->intra_lock);
|
||||
|
@ -1014,6 +1070,7 @@ void kvz_set_lcu_lambda_and_qp(encoder_state_t * const state,
|
|||
vector2d_t pos)
|
||||
{
|
||||
const encoder_control_t * const ctrl = state->encoder_control;
|
||||
lcu_stats_t *lcu = kvz_get_lcu_stats(state, pos.x, pos.y);
|
||||
|
||||
if (ctrl->cfg.roi.dqps != NULL) {
|
||||
vector2d_t lcu = {
|
||||
|
@ -1032,7 +1089,6 @@ void kvz_set_lcu_lambda_and_qp(encoder_state_t * const state,
|
|||
|
||||
}
|
||||
else if (ctrl->cfg.target_bitrate > 0) {
|
||||
lcu_stats_t *lcu = kvz_get_lcu_stats(state, pos.x, pos.y);
|
||||
const uint32_t pixels = MIN(LCU_WIDTH, state->tile->frame->width - LCU_WIDTH * pos.x) *
|
||||
MIN(LCU_WIDTH, state->tile->frame->height - LCU_WIDTH * pos.y);
|
||||
|
||||
|
@ -1065,7 +1121,6 @@ void kvz_set_lcu_lambda_and_qp(encoder_state_t * const state,
|
|||
lambda);
|
||||
lambda = clip_lambda(lambda);
|
||||
|
||||
lcu->lambda = lambda;
|
||||
state->lambda = lambda;
|
||||
state->lambda_sqrt = sqrt(lambda);
|
||||
state->qp = lambda_to_qp(lambda);
|
||||
|
@ -1076,13 +1131,16 @@ void kvz_set_lcu_lambda_and_qp(encoder_state_t * const state,
|
|||
state->lambda_sqrt = sqrt(state->frame->lambda);
|
||||
}
|
||||
|
||||
lcu->lambda = state->lambda;
|
||||
lcu->qp = state->qp;
|
||||
|
||||
// Apply variance adaptive quantization
|
||||
if (ctrl->cfg.vaq) {
|
||||
vector2d_t lcu = {
|
||||
vector2d_t lcu_pos = {
|
||||
pos.x + state->tile->lcu_offset_x,
|
||||
pos.y + state->tile->lcu_offset_y
|
||||
};
|
||||
int id = lcu.x + lcu.y * state->tile->frame->width_in_lcu;
|
||||
int id = lcu_pos.x + lcu_pos.y * state->tile->frame->width_in_lcu;
|
||||
int aq_offset = round(state->frame->aq_offsets[id]);
|
||||
state->qp += aq_offset;
|
||||
// Maximum delta QP is clipped between [-26, 25] according to ITU T-REC-H.265 specification chapter 7.4.9.10 Transform unit semantics
|
||||
|
@ -1091,5 +1149,8 @@ void kvz_set_lcu_lambda_and_qp(encoder_state_t * const state,
|
|||
state->qp = CLIP_TO_QP(state->qp);
|
||||
state->lambda = qp_to_lambda(state, state->qp);
|
||||
state->lambda_sqrt = sqrt(state->lambda);
|
||||
|
||||
lcu->adjust_lambda = state->lambda;
|
||||
lcu->adjust_qp = state->qp;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue