Add --stats-file-prefix option

When the option is defined with an option four files prefixlambda.txt,
prefixqp.txt, prefixdist.txt, and prefixbits.txt that have the corresponding
data for each ctu. This is a debug feature.
This commit is contained in:
Joose Sainio 2020-09-09 12:35:47 +03:00
parent c10b841e7c
commit 3fb8b7ebc6
6 changed files with 54 additions and 5 deletions

View file

@ -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

View file

@ -163,6 +163,7 @@ int kvz_config_init(kvz_config *cfg)
cfg->intra_bit_allocation = false;
cfg->clip_neighbour = true;
cfg->stats_file_prefix = NULL;
return 1;
}
@ -1359,6 +1360,9 @@ int kvz_config_parse(kvz_config *cfg, const char *name, const char *value)
else if OPT("clip-neighbour") {
cfg->clip_neighbour = atobool(value);
}
else if OPT("stats-file-prefix") {
cfg->stats_file_prefix = strdup(value);
}
else {
return 0;
}

View file

@ -149,6 +149,7 @@ static const struct option long_options[] = {
{ "no-intra-bits", no_argument, NULL, 0 },
{ "clip-neighbour", no_argument, NULL, 0 },
{ "no-clip-neighbour", no_argument, NULL, 0 },
{ "stats-file-prefix", required_argument, NULL, 0 },
{0, 0, 0, 0}
};
@ -396,6 +397,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"
/* Word wrap to this width to stay under 80 characters (including ") *************/
"Video structure:\n"

View file

@ -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);
}

View file

@ -437,6 +437,8 @@ typedef struct kvz_config
uint8_t intra_bit_allocation;
uint8_t clip_neighbour;
char *stats_file_prefix;
} kvz_config;
/**

View file

@ -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;
}
@ -875,6 +891,13 @@ 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) {
fprintf(dist_file, "%d %d %d\n", state->frame->poc, encoder->in.width_in_lcu, encoder->in.height_in_lcu);
fprintf(bits_file, "%d %d %d\n", state->frame->poc, encoder->in.width_in_lcu, encoder->in.height_in_lcu);
fprintf(qp_file, "%d %d %d\n", state->frame->poc, encoder->in.width_in_lcu, encoder->in.height_in_lcu);
fprintf(lambda_file, "%d %d %d\n", state->frame->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 +912,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->qp);
fprintf(lambda_file, "%f ", 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 +1051,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 +1070,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 +1102,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);
@ -1092,4 +1128,6 @@ void kvz_set_lcu_lambda_and_qp(encoder_state_t * const state,
state->lambda = qp_to_lambda(state, state->qp);
state->lambda_sqrt = sqrt(state->lambda);
}
lcu->lambda = state->lambda;
lcu->qp = state->qp;
}