mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-11-30 20:54:07 +00:00
Move OWF logic and CLI stuff out of encoder_compute_stats.
- CLI stuff is moved to either cli-module or to main function. - OWF stuff is made more explicit by counting the frames instead of communicating through encoder_state_t.stats_done.
This commit is contained in:
parent
ea50d03e52
commit
5c28745457
41
src/cli.c
41
src/cli.c
|
@ -27,6 +27,8 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "encoderstate.h"
|
||||||
|
|
||||||
|
|
||||||
void print_version(void)
|
void print_version(void)
|
||||||
{
|
{
|
||||||
|
@ -146,3 +148,42 @@ void print_help(void)
|
||||||
" -w, --width : Width of input in pixels\n"
|
" -w, --width : Width of input in pixels\n"
|
||||||
" -h, --height : Height of input in pixels\n");
|
" -h, --height : Height of input in pixels\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void print_frame_info(encoder_state_t *state, double frame_psnr[3])
|
||||||
|
{
|
||||||
|
fprintf(stderr, "POC %4d QP %2d (%c-frame) %10d bits PSNR: %2.4f %2.4f %2.4f",
|
||||||
|
state->global->poc,
|
||||||
|
state->global->QP,
|
||||||
|
"BPI"[state->global->slicetype % 3], state->stats_bitstream_length << 3,
|
||||||
|
frame_psnr[0], frame_psnr[1], frame_psnr[2]);
|
||||||
|
|
||||||
|
// Print reference picture lists
|
||||||
|
if (state->global->slicetype != SLICE_I) {
|
||||||
|
int j, ref_list[2] = { 0, 0 }, ref_list_poc[2][16];
|
||||||
|
// List all pocs of lists
|
||||||
|
for (j = 0; j < state->global->ref->used_size; j++) {
|
||||||
|
if (state->global->ref->images[j]->poc < state->global->poc) {
|
||||||
|
ref_list_poc[0][ref_list[0]] = state->global->ref->images[j]->poc;
|
||||||
|
ref_list[0]++;
|
||||||
|
} else {
|
||||||
|
ref_list_poc[1][ref_list[1]] = state->global->ref->images[j]->poc;
|
||||||
|
ref_list[1]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
encoder_ref_insertion_sort(ref_list_poc[0], ref_list[0]);
|
||||||
|
encoder_ref_insertion_sort(ref_list_poc[1], ref_list[1]);
|
||||||
|
|
||||||
|
fprintf(stderr, " [L0 ");
|
||||||
|
for (j = ref_list[0] - 1; j >= 0; j--) {
|
||||||
|
fprintf(stderr, "%d ", ref_list_poc[0][j]);
|
||||||
|
}
|
||||||
|
fprintf(stderr, "] [L1 ");
|
||||||
|
for (j = 0; j < ref_list[1]; j++) {
|
||||||
|
fprintf(stderr, "%d ", ref_list_poc[1][j]);
|
||||||
|
}
|
||||||
|
fprintf(stderr, "]");
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
}
|
||||||
|
|
|
@ -30,5 +30,6 @@
|
||||||
|
|
||||||
void print_version(void);
|
void print_version(void);
|
||||||
void print_help(void);
|
void print_help(void);
|
||||||
|
void print_frame_info(encoder_state_t *state, double frame_psnr[3]);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -48,6 +48,7 @@
|
||||||
#include "strategyselector.h"
|
#include "strategyselector.h"
|
||||||
#include "cli.h"
|
#include "cli.h"
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Program main function.
|
* \brief Program main function.
|
||||||
* \param argc Argument count from commandline
|
* \param argc Argument count from commandline
|
||||||
|
@ -60,8 +61,6 @@ int main(int argc, char *argv[])
|
||||||
FILE *input = NULL; //!< input file (YUV)
|
FILE *input = NULL; //!< input file (YUV)
|
||||||
FILE *output = NULL; //!< output file (HEVC NAL stream)
|
FILE *output = NULL; //!< output file (HEVC NAL stream)
|
||||||
encoder_control_t encoder;
|
encoder_control_t encoder;
|
||||||
double psnr[3] = { 0.0, 0.0, 0.0 };
|
|
||||||
uint32_t stat_frames = 0;
|
|
||||||
uint64_t curpos = 0;
|
uint64_t curpos = 0;
|
||||||
FILE *recout = NULL; //!< reconstructed YUV output, --debug
|
FILE *recout = NULL; //!< reconstructed YUV output, --debug
|
||||||
clock_t start_time = clock();
|
clock_t start_time = clock();
|
||||||
|
@ -246,25 +245,22 @@ int main(int argc, char *argv[])
|
||||||
//Initial frame
|
//Initial frame
|
||||||
encoder_states[current_encoder_state].global->frame = -1;
|
encoder_states[current_encoder_state].global->frame = -1;
|
||||||
|
|
||||||
// Only the code that handles conformance window coding needs to know
|
|
||||||
// the real dimensions. As a quick fix for broken non-multiple of 8 videos,
|
|
||||||
// change the input values here to be the real values. For a real fix
|
|
||||||
// encoder.in probably needs to be merged into cfg.
|
|
||||||
// The real fix would be: never go dig in cfg
|
|
||||||
//cfg->width = encoder.in.width;
|
|
||||||
//cfg->height = encoder.in.height;
|
|
||||||
|
|
||||||
GET_TIME(&encoding_start_real_time);
|
GET_TIME(&encoding_start_real_time);
|
||||||
encoding_start_cpu_time = clock();
|
encoding_start_cpu_time = clock();
|
||||||
|
|
||||||
uint64_t bitstream_length = 0;
|
uint64_t bitstream_length = 0;
|
||||||
|
uint32_t frames_started = 0;
|
||||||
|
uint32_t frames_done = 0;
|
||||||
|
double psnr_sum[3] = { 0.0, 0.0, 0.0 };
|
||||||
|
|
||||||
// Start coding cycle while data on input and not on the last frame
|
// Start coding cycle while data on input and not on the last frame
|
||||||
while(!cfg->frames || encoder_states[current_encoder_state].global->frame < cfg->frames - 1) {
|
while (cfg->frames == 0 || frames_started < cfg->frames) {
|
||||||
|
encoder_state_t *state = &encoder_states[current_encoder_state];
|
||||||
|
|
||||||
// Skip '--seek' frames before input.
|
// Skip '--seek' frames before input.
|
||||||
// This block can be moved outside this while loop when there is a
|
// This block can be moved outside this while loop when there is a
|
||||||
// mechanism to skip the while loop on error.
|
// mechanism to skip the while loop on error.
|
||||||
if (encoder_states[current_encoder_state].global->frame == 0 && cfg->seek > 0) {
|
if (frames_started == 0 && cfg->seek > 0) {
|
||||||
int frame_bytes = cfg->width * cfg->height * 3 / 2;
|
int frame_bytes = cfg->width * cfg->height * 3 / 2;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
|
||||||
|
@ -286,19 +282,23 @@ int main(int argc, char *argv[])
|
||||||
encoding_start_cpu_time = clock();
|
encoding_start_cpu_time = clock();
|
||||||
}
|
}
|
||||||
|
|
||||||
//Compute stats
|
// If we have started as many frames as we are going to encode in parallel, wait for the first one we started encoding to finish before
|
||||||
encoder_compute_stats(&encoder_states[current_encoder_state], recout, &stat_frames, psnr, &bitstream_length);
|
// encoding more.
|
||||||
|
if (frames_started > cfg->owf) {
|
||||||
|
double frame_psnr[3] = { 0.0, 0.0, 0.0 };
|
||||||
|
encoder_compute_stats(&encoder_states[current_encoder_state], recout, frame_psnr, &bitstream_length);
|
||||||
|
frames_done += 1;
|
||||||
|
psnr_sum[0] += frame_psnr[0];
|
||||||
|
psnr_sum[1] += frame_psnr[1];
|
||||||
|
psnr_sum[2] += frame_psnr[2];
|
||||||
|
|
||||||
|
print_frame_info(state, frame_psnr);
|
||||||
|
}
|
||||||
|
frames_started += 1;
|
||||||
|
|
||||||
//Clear encoder
|
//Clear encoder
|
||||||
encoder_next_frame(&encoder_states[current_encoder_state]);
|
encoder_next_frame(&encoder_states[current_encoder_state]);
|
||||||
|
|
||||||
//Abort if enough frames
|
|
||||||
if (cfg->frames && encoder_states[current_encoder_state].global->frame >= cfg->frames) {
|
|
||||||
//Ignore this frame, which is not valid...
|
|
||||||
encoder_states[current_encoder_state].stats_done = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
CHECKPOINT_MARK("read source frame: %d", encoder_states[current_encoder_state].global->frame + cfg->seek);
|
CHECKPOINT_MARK("read source frame: %d", encoder_states[current_encoder_state].global->frame + cfg->seek);
|
||||||
|
|
||||||
// Read one frame from the input
|
// Read one frame from the input
|
||||||
|
@ -322,8 +322,18 @@ int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int first_enc = current_encoder_state;
|
int first_enc = current_encoder_state;
|
||||||
do {
|
do {
|
||||||
|
double frame_psnr[3] = { 0.0, 0.0, 0.0 };
|
||||||
current_encoder_state = (current_encoder_state + 1) % (encoder.owf + 1);
|
current_encoder_state = (current_encoder_state + 1) % (encoder.owf + 1);
|
||||||
encoder_compute_stats(&encoder_states[current_encoder_state], recout, &stat_frames, psnr, &bitstream_length);
|
encoder_state_t *state = &encoder_states[current_encoder_state];
|
||||||
|
|
||||||
|
if (!state->stats_done) {
|
||||||
|
encoder_compute_stats(state, recout, frame_psnr, &bitstream_length);
|
||||||
|
print_frame_info(state, frame_psnr);
|
||||||
|
frames_done += 1;
|
||||||
|
psnr_sum[0] += frame_psnr[0];
|
||||||
|
psnr_sum[1] += frame_psnr[1];
|
||||||
|
psnr_sum[2] += frame_psnr[2];
|
||||||
|
}
|
||||||
} while (current_encoder_state != first_enc);
|
} while (current_encoder_state != first_enc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -338,8 +348,8 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
// Print statistics of the coding
|
// Print statistics of the coding
|
||||||
fprintf(stderr, " Processed %d frames, %10llu bits AVG PSNR: %2.4f %2.4f %2.4f\n",
|
fprintf(stderr, " Processed %d frames, %10llu bits AVG PSNR: %2.4f %2.4f %2.4f\n",
|
||||||
stat_frames, (long long unsigned int)bitstream_length * 8,
|
frames_done, (long long unsigned int)bitstream_length * 8,
|
||||||
psnr[0] / stat_frames, psnr[1] / stat_frames, psnr[2] / stat_frames);
|
psnr_sum[0] / frames_done, psnr_sum[1] / frames_done, psnr_sum[2] / frames_done);
|
||||||
fprintf(stderr, " Total CPU time: %.3f s.\n", ((float)(clock() - start_time)) / CLOCKS_PER_SEC);
|
fprintf(stderr, " Total CPU time: %.3f s.\n", ((float)(clock() - start_time)) / CLOCKS_PER_SEC);
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -348,7 +358,7 @@ int main(int argc, char *argv[])
|
||||||
fprintf(stderr, " Encoding time: %.3f s.\n", encoding_time);
|
fprintf(stderr, " Encoding time: %.3f s.\n", encoding_time);
|
||||||
fprintf(stderr, " Encoding wall time: %.3f s.\n", wall_time);
|
fprintf(stderr, " Encoding wall time: %.3f s.\n", wall_time);
|
||||||
fprintf(stderr, " Encoding CPU usage: %.2f%%\n", encoding_time/wall_time*100.f);
|
fprintf(stderr, " Encoding CPU usage: %.2f%%\n", encoding_time/wall_time*100.f);
|
||||||
fprintf(stderr, " FPS: %.2f\n", ((double)stat_frames)/wall_time);
|
fprintf(stderr, " FPS: %.2f\n", ((double)frames_done)/wall_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(input);
|
fclose(input);
|
||||||
|
|
|
@ -623,7 +623,7 @@ static void encoder_state_encode(encoder_state_t * const main_state) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void encoder_ref_insertion_sort(int reflist[16], int length) {
|
void encoder_ref_insertion_sort(int reflist[16], int length) {
|
||||||
|
|
||||||
for (uint8_t i = 1; i < length; ++i) {
|
for (uint8_t i = 1; i < length; ++i) {
|
||||||
const int16_t cur_poc = reflist[i];
|
const int16_t cur_poc = reflist[i];
|
||||||
|
@ -1016,14 +1016,12 @@ int read_one_frame(FILE* file, const encoder_state_t * const state)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void encoder_compute_stats(encoder_state_t *state, FILE * const recout, uint32_t *stat_frames, double psnr[3], uint64_t *bitstream_length) {
|
void encoder_compute_stats(encoder_state_t *state, FILE * const recout, double frame_psnr[3], uint64_t *bitstream_length) {
|
||||||
const encoder_control_t * const encoder = state->encoder_control;
|
const encoder_control_t * const encoder = state->encoder_control;
|
||||||
|
|
||||||
if (state->stats_done) return;
|
if (state->stats_done) return;
|
||||||
state->stats_done = 1;
|
state->stats_done = 1;
|
||||||
|
|
||||||
++(*stat_frames);
|
|
||||||
|
|
||||||
//Blocking call
|
//Blocking call
|
||||||
threadqueue_waitfor(encoder->threadqueue, state->tqj_bitstream_written);
|
threadqueue_waitfor(encoder->threadqueue, state->tqj_bitstream_written);
|
||||||
|
|
||||||
|
@ -1050,48 +1048,7 @@ void encoder_compute_stats(encoder_state_t *state, FILE * const recout, uint32_t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// PSNR calculations
|
videoframe_compute_psnr(state->tile->frame, frame_psnr);
|
||||||
{
|
|
||||||
double temp_psnr[3];
|
|
||||||
|
|
||||||
videoframe_compute_psnr(state->tile->frame, temp_psnr);
|
|
||||||
|
|
||||||
fprintf(stderr, "POC %4d QP %2d (%c-frame) %10d bits PSNR: %2.4f %2.4f %2.4f", state->global->poc,
|
|
||||||
state->global->QP,
|
|
||||||
"BPI"[state->global->slicetype%3], state->stats_bitstream_length<<3,
|
|
||||||
temp_psnr[0], temp_psnr[1], temp_psnr[2]);
|
|
||||||
// Print reference picture lists
|
|
||||||
if (state->global->slicetype != SLICE_I) {
|
|
||||||
int j, ref_list[2] = { 0, 0 }, ref_list_poc[2][16];
|
|
||||||
// List all pocs of lists
|
|
||||||
for (j = 0; j < state->global->ref->used_size; j++) {
|
|
||||||
if (state->global->ref->images[j]->poc < state->global->poc) {
|
|
||||||
ref_list_poc[0][ref_list[0]] = state->global->ref->images[j]->poc;
|
|
||||||
ref_list[0]++;
|
|
||||||
} else {
|
|
||||||
ref_list_poc[1][ref_list[1]] = state->global->ref->images[j]->poc;
|
|
||||||
ref_list[1]++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
encoder_ref_insertion_sort(ref_list_poc[0], ref_list[0]);
|
|
||||||
encoder_ref_insertion_sort(ref_list_poc[1], ref_list[1]);
|
|
||||||
|
|
||||||
fprintf(stderr, " [L0 ");
|
|
||||||
for (j = ref_list[0]-1; j >= 0; j--) {
|
|
||||||
fprintf(stderr, "%d ", ref_list_poc[0][j]);
|
|
||||||
}
|
|
||||||
fprintf(stderr, "] [L1 ");
|
|
||||||
for (j = 0; j < ref_list[1]; j++) {
|
|
||||||
fprintf(stderr, "%d ", ref_list_poc[1][j]);
|
|
||||||
}
|
|
||||||
fprintf(stderr, "]");
|
|
||||||
}
|
|
||||||
fprintf(stderr, "\n");
|
|
||||||
// Increment total PSNR
|
|
||||||
psnr[0] += temp_psnr[0];
|
|
||||||
psnr[1] += temp_psnr[1];
|
|
||||||
psnr[2] += temp_psnr[2];
|
|
||||||
}
|
|
||||||
|
|
||||||
*bitstream_length += state->stats_bitstream_length;
|
*bitstream_length += state->stats_bitstream_length;
|
||||||
}
|
}
|
||||||
|
|
|
@ -197,7 +197,7 @@ typedef struct encoder_state_t {
|
||||||
void encode_one_frame(encoder_state_t *state);
|
void encode_one_frame(encoder_state_t *state);
|
||||||
int read_one_frame(FILE* file, const encoder_state_t *state);
|
int read_one_frame(FILE* file, const encoder_state_t *state);
|
||||||
|
|
||||||
void encoder_compute_stats(encoder_state_t *state, FILE * const recout, uint32_t *stat_frames, double psnr[3], uint64_t *bitstream_length);
|
void encoder_compute_stats(encoder_state_t *state, FILE * const recout, double psnr[3], uint64_t *bitstream_length);
|
||||||
void encoder_next_frame(encoder_state_t *state);
|
void encoder_next_frame(encoder_state_t *state);
|
||||||
|
|
||||||
|
|
||||||
|
@ -219,6 +219,8 @@ int encoder_state_match_children_of_previous_frame(encoder_state_t * const state
|
||||||
|
|
||||||
coeff_scan_order_t get_scan_order(int8_t cu_type, int intra_mode, int depth);
|
coeff_scan_order_t get_scan_order(int8_t cu_type, int intra_mode, int depth);
|
||||||
|
|
||||||
|
void encoder_ref_insertion_sort(int reflist[16], int length);
|
||||||
|
|
||||||
static const uint8_t g_group_idx[32] = {
|
static const uint8_t g_group_idx[32] = {
|
||||||
0, 1, 2, 3, 4, 4, 5, 5, 6, 6,
|
0, 1, 2, 3, 4, 4, 5, 5, 6, 6,
|
||||||
6, 6, 7, 7, 7, 7, 8, 8, 8, 8,
|
6, 6, 7, 7, 7, 7, 8, 8, 8, 8,
|
||||||
|
|
Loading…
Reference in a new issue