mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-11-27 19:24:06 +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 "encoderstate.h"
|
||||
|
||||
|
||||
void print_version(void)
|
||||
{
|
||||
|
@ -146,3 +148,42 @@ void print_help(void)
|
|||
" -w, --width : Width 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_help(void);
|
||||
void print_frame_info(encoder_state_t *state, double frame_psnr[3]);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include "strategyselector.h"
|
||||
#include "cli.h"
|
||||
|
||||
|
||||
/**
|
||||
* \brief Program main function.
|
||||
* \param argc Argument count from commandline
|
||||
|
@ -60,8 +61,6 @@ int main(int argc, char *argv[])
|
|||
FILE *input = NULL; //!< input file (YUV)
|
||||
FILE *output = NULL; //!< output file (HEVC NAL stream)
|
||||
encoder_control_t encoder;
|
||||
double psnr[3] = { 0.0, 0.0, 0.0 };
|
||||
uint32_t stat_frames = 0;
|
||||
uint64_t curpos = 0;
|
||||
FILE *recout = NULL; //!< reconstructed YUV output, --debug
|
||||
clock_t start_time = clock();
|
||||
|
@ -246,25 +245,22 @@ int main(int argc, char *argv[])
|
|||
//Initial frame
|
||||
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);
|
||||
encoding_start_cpu_time = clock();
|
||||
|
||||
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
|
||||
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.
|
||||
// This block can be moved outside this while loop when there is a
|
||||
// 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 error = 0;
|
||||
|
||||
|
@ -285,20 +281,24 @@ int main(int argc, char *argv[])
|
|||
GET_TIME(&encoding_start_real_time);
|
||||
encoding_start_cpu_time = clock();
|
||||
}
|
||||
|
||||
//Compute stats
|
||||
encoder_compute_stats(&encoder_states[current_encoder_state], recout, &stat_frames, psnr, &bitstream_length);
|
||||
|
||||
// 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
|
||||
// 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
|
||||
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);
|
||||
|
||||
// Read one frame from the input
|
||||
|
@ -322,8 +322,18 @@ int main(int argc, char *argv[])
|
|||
{
|
||||
int first_enc = current_encoder_state;
|
||||
do {
|
||||
double frame_psnr[3] = { 0.0, 0.0, 0.0 };
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -338,8 +348,8 @@ int main(int argc, char *argv[])
|
|||
|
||||
// Print statistics of the coding
|
||||
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,
|
||||
psnr[0] / stat_frames, psnr[1] / stat_frames, psnr[2] / stat_frames);
|
||||
frames_done, (long long unsigned int)bitstream_length * 8,
|
||||
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);
|
||||
|
||||
{
|
||||
|
@ -348,7 +358,7 @@ int main(int argc, char *argv[])
|
|||
fprintf(stderr, " Encoding time: %.3f s.\n", encoding_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, " FPS: %.2f\n", ((double)stat_frames)/wall_time);
|
||||
fprintf(stderr, " FPS: %.2f\n", ((double)frames_done)/wall_time);
|
||||
}
|
||||
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (state->stats_done) return;
|
||||
state->stats_done = 1;
|
||||
|
||||
++(*stat_frames);
|
||||
|
||||
//Blocking call
|
||||
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
|
||||
{
|
||||
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];
|
||||
}
|
||||
videoframe_compute_psnr(state->tile->frame, frame_psnr);
|
||||
|
||||
*bitstream_length += state->stats_bitstream_length;
|
||||
}
|
||||
|
|
|
@ -197,7 +197,7 @@ typedef struct encoder_state_t {
|
|||
void encode_one_frame(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);
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
||||
void encoder_ref_insertion_sort(int reflist[16], int length);
|
||||
|
||||
static const uint8_t g_group_idx[32] = {
|
||||
0, 1, 2, 3, 4, 4, 5, 5, 6, 6,
|
||||
6, 6, 7, 7, 7, 7, 8, 8, 8, 8,
|
||||
|
|
Loading…
Reference in a new issue