mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-11-28 03:34:06 +00:00
Fix statistics with OWF
This commit is contained in:
parent
0522a3d8e5
commit
bf6024734a
|
@ -58,8 +58,8 @@ int main(int argc, char *argv[])
|
||||||
FILE *output = NULL; //!< output file (HEVC NAL stream)
|
FILE *output = NULL; //!< output file (HEVC NAL stream)
|
||||||
encoder_control encoder;
|
encoder_control encoder;
|
||||||
double psnr[3] = { 0.0, 0.0, 0.0 };
|
double psnr[3] = { 0.0, 0.0, 0.0 };
|
||||||
uint64_t curpos = 0;
|
uint32_t stat_frames = 0;
|
||||||
uint64_t lastpos = 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();
|
||||||
|
|
||||||
|
@ -313,9 +313,6 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
// 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) {
|
while(!cfg->frames || encoder_states[current_encoder_state].global->frame < cfg->frames) {
|
||||||
int32_t diff;
|
|
||||||
double temp_psnr[3];
|
|
||||||
|
|
||||||
// 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.
|
||||||
|
@ -339,6 +336,9 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Compute stats
|
||||||
|
encoder_compute_stats(&encoder_states[current_encoder_state], recout, &stat_frames, psnr);
|
||||||
|
|
||||||
//Clear encoder
|
//Clear encoder
|
||||||
encoder_next_frame(&encoder_states[current_encoder_state]);
|
encoder_next_frame(&encoder_states[current_encoder_state]);
|
||||||
|
|
||||||
|
@ -354,48 +354,10 @@ int main(int argc, char *argv[])
|
||||||
// The actual coding happens here, after this function we have a coded frame
|
// The actual coding happens here, after this function we have a coded frame
|
||||||
encode_one_frame(&encoder_states[current_encoder_state]);
|
encode_one_frame(&encoder_states[current_encoder_state]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (cfg->debug != NULL) {
|
|
||||||
const videoframe * const frame = encoder_states[current_encoder_state].tile->frame;
|
|
||||||
// Write reconstructed frame out.
|
|
||||||
// Use conformance-window dimensions instead of internal ones.
|
|
||||||
const int width = frame->width;
|
|
||||||
const int out_width = encoder.in.real_width;
|
|
||||||
const int out_height = encoder.in.real_height;
|
|
||||||
int y;
|
|
||||||
const pixel *y_rec = frame->rec->y;
|
|
||||||
const pixel *u_rec = frame->rec->u;
|
|
||||||
const pixel *v_rec = frame->rec->v;
|
|
||||||
|
|
||||||
for (y = 0; y < out_height; ++y) {
|
|
||||||
fwrite(&y_rec[y * width], sizeof(*y_rec), out_width, recout);
|
|
||||||
}
|
|
||||||
for (y = 0; y < out_height / 2; ++y) {
|
|
||||||
fwrite(&u_rec[y * width / 2], sizeof(*u_rec), out_width / 2, recout);
|
|
||||||
}
|
|
||||||
for (y = 0; y < out_height / 2; ++y) {
|
|
||||||
fwrite(&v_rec[y * width / 2], sizeof(*v_rec), out_width / 2, recout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate the bytes pushed to output for this frame
|
|
||||||
fgetpos(output,(fpos_t*)&curpos);
|
|
||||||
diff = (int32_t)(curpos-lastpos);
|
|
||||||
lastpos = curpos;
|
|
||||||
|
|
||||||
//FIXME Stats are completely broken!!!
|
//FIXME Stats are completely broken!!!
|
||||||
// PSNR calculations
|
|
||||||
videoframe_compute_psnr(encoder_states[current_encoder_state].tile->frame, temp_psnr);
|
|
||||||
|
|
||||||
fprintf(stderr, "POC %4d (%c-frame) %10d bits PSNR: %2.4f %2.4f %2.4f\n", encoder_states[current_encoder_state].global->frame,
|
|
||||||
"BPI"[encoder_states[current_encoder_state].global->slicetype%3], diff<<3,
|
|
||||||
temp_psnr[0], temp_psnr[1], temp_psnr[2]);
|
|
||||||
|
|
||||||
// Increment total PSNR
|
|
||||||
psnr[0] += temp_psnr[0];
|
|
||||||
psnr[1] += temp_psnr[1];
|
|
||||||
psnr[2] += temp_psnr[2];
|
|
||||||
|
|
||||||
//Stop otherwise we will end up doing too much work
|
//Stop otherwise we will end up doing too much work
|
||||||
if (encoder_states[current_encoder_state].global->frame >= cfg->frames - 1) {
|
if (encoder_states[current_encoder_state].global->frame >= cfg->frames - 1) {
|
||||||
|
@ -404,14 +366,25 @@ int main(int argc, char *argv[])
|
||||||
//Switch to the next encoder
|
//Switch to the next encoder
|
||||||
current_encoder_state = (current_encoder_state + 1) % (encoder.owf + 1);
|
current_encoder_state = (current_encoder_state + 1) % (encoder.owf + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Compute stats for the remaining encoders
|
||||||
|
{
|
||||||
|
int first_enc = current_encoder_state;
|
||||||
|
do {
|
||||||
|
current_encoder_state = (current_encoder_state + 1) % (encoder.owf + 1);
|
||||||
|
encoder_compute_stats(&encoder_states[current_encoder_state], recout, &stat_frames, psnr);
|
||||||
|
} while (current_encoder_state != first_enc);
|
||||||
|
}
|
||||||
|
|
||||||
threadqueue_flush(encoder.threadqueue);
|
threadqueue_flush(encoder.threadqueue);
|
||||||
|
|
||||||
|
|
||||||
// Coding finished
|
// Coding finished
|
||||||
fgetpos(output,(fpos_t*)&curpos);
|
fgetpos(output,(fpos_t*)&curpos);
|
||||||
|
|
||||||
// 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", encoder_states[current_encoder_state].global->frame, (long long unsigned int) curpos<<3,
|
fprintf(stderr, " Processed %d frames, %10llu bits AVG PSNR: %2.4f %2.4f %2.4f\n", stat_frames, (long long unsigned int) curpos<<3,
|
||||||
psnr[0] / encoder_states[current_encoder_state].global->frame, psnr[1] / encoder_states[current_encoder_state].global->frame, psnr[2] / encoder_states[current_encoder_state].global->frame);
|
psnr[0] / stat_frames, psnr[1] / stat_frames, psnr[2] / stat_frames);
|
||||||
fprintf(stderr, " Total time: %.3f s.\n", ((float)(clock() - start_time)) / CLOCKS_PER_SEC);
|
fprintf(stderr, " Total time: %.3f s.\n", ((float)(clock() - start_time)) / CLOCKS_PER_SEC);
|
||||||
|
|
||||||
fclose(input);
|
fclose(input);
|
||||||
|
|
|
@ -286,6 +286,7 @@ int encoder_state_init(encoder_state * const child_state, encoder_state * const
|
||||||
child_state->children[0].encoder_control = NULL;
|
child_state->children[0].encoder_control = NULL;
|
||||||
child_state->tqj_bitstream_written = NULL;
|
child_state->tqj_bitstream_written = NULL;
|
||||||
child_state->tqj_recon_done = NULL;
|
child_state->tqj_recon_done = NULL;
|
||||||
|
child_state->stats_done = 1; //It avoids printing meaningless stats at the beginning
|
||||||
|
|
||||||
if (!parent_state) {
|
if (!parent_state) {
|
||||||
const encoder_control * const encoder = child_state->encoder_control;
|
const encoder_control * const encoder = child_state->encoder_control;
|
||||||
|
|
|
@ -782,6 +782,58 @@ int read_one_frame(FILE* file, const encoder_state * const encoder_state)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void encoder_compute_stats(encoder_state *encoder_state, FILE * const recout, uint32_t *stat_frames, double psnr[3]) {
|
||||||
|
const encoder_control * const encoder = encoder_state->encoder_control;
|
||||||
|
|
||||||
|
if (encoder_state->stats_done) return;
|
||||||
|
encoder_state->stats_done = 1;
|
||||||
|
|
||||||
|
++(*stat_frames);
|
||||||
|
|
||||||
|
//Blocking call
|
||||||
|
threadqueue_waitfor(encoder->threadqueue, encoder_state->tqj_bitstream_written);
|
||||||
|
|
||||||
|
if (recout) {
|
||||||
|
const videoframe * const frame = encoder_state->tile->frame;
|
||||||
|
// Write reconstructed frame out.
|
||||||
|
// Use conformance-window dimensions instead of internal ones.
|
||||||
|
const int width = frame->width;
|
||||||
|
const int out_width = encoder->in.real_width;
|
||||||
|
const int out_height = encoder->in.real_height;
|
||||||
|
int y;
|
||||||
|
const pixel *y_rec = frame->rec->y;
|
||||||
|
const pixel *u_rec = frame->rec->u;
|
||||||
|
const pixel *v_rec = frame->rec->v;
|
||||||
|
|
||||||
|
for (y = 0; y < out_height; ++y) {
|
||||||
|
fwrite(&y_rec[y * width], sizeof(*y_rec), out_width, recout);
|
||||||
|
}
|
||||||
|
for (y = 0; y < out_height / 2; ++y) {
|
||||||
|
fwrite(&u_rec[y * width / 2], sizeof(*u_rec), out_width / 2, recout);
|
||||||
|
}
|
||||||
|
for (y = 0; y < out_height / 2; ++y) {
|
||||||
|
fwrite(&v_rec[y * width / 2], sizeof(*v_rec), out_width / 2, recout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PSNR calculations
|
||||||
|
{
|
||||||
|
int32_t diff=0; //FIXME: get the correct length of bitstream
|
||||||
|
double temp_psnr[3];
|
||||||
|
|
||||||
|
videoframe_compute_psnr(encoder_state->tile->frame, temp_psnr);
|
||||||
|
|
||||||
|
fprintf(stderr, "POC %4d (%c-frame) %10d bits PSNR: %2.4f %2.4f %2.4f\n", encoder_state->global->frame,
|
||||||
|
"BPI"[encoder_state->global->slicetype%3], diff<<3,
|
||||||
|
temp_psnr[0], temp_psnr[1], temp_psnr[2]);
|
||||||
|
|
||||||
|
// Increment total PSNR
|
||||||
|
psnr[0] += temp_psnr[0];
|
||||||
|
psnr[1] += temp_psnr[1];
|
||||||
|
psnr[2] += temp_psnr[2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void encoder_next_frame(encoder_state *encoder_state) {
|
void encoder_next_frame(encoder_state *encoder_state) {
|
||||||
const encoder_control * const encoder = encoder_state->encoder_control;
|
const encoder_control * const encoder = encoder_state->encoder_control;
|
||||||
|
@ -789,7 +841,7 @@ void encoder_next_frame(encoder_state *encoder_state) {
|
||||||
//Blocking call
|
//Blocking call
|
||||||
threadqueue_waitfor(encoder->threadqueue, encoder_state->tqj_bitstream_written);
|
threadqueue_waitfor(encoder->threadqueue, encoder_state->tqj_bitstream_written);
|
||||||
|
|
||||||
//FIXME FIXME FIXME Compute statistics here
|
encoder_state->stats_done = 0;
|
||||||
|
|
||||||
if (encoder_state->global->frame == -1) {
|
if (encoder_state->global->frame == -1) {
|
||||||
//We're at the first frame, so don't care about all this stuff;
|
//We're at the first frame, so don't care about all this stuff;
|
||||||
|
|
|
@ -162,6 +162,8 @@ typedef struct encoder_state {
|
||||||
bitstream stream;
|
bitstream stream;
|
||||||
cabac_data cabac;
|
cabac_data cabac;
|
||||||
|
|
||||||
|
int stats_done;
|
||||||
|
|
||||||
//Jobs to wait for
|
//Jobs to wait for
|
||||||
threadqueue_job * tqj_recon_done; //Reconstruction is done
|
threadqueue_job * tqj_recon_done; //Reconstruction is done
|
||||||
threadqueue_job * tqj_bitstream_written; //Bitstream is written
|
threadqueue_job * tqj_bitstream_written; //Bitstream is written
|
||||||
|
@ -172,6 +174,7 @@ typedef struct encoder_state {
|
||||||
void encode_one_frame(encoder_state *encoder_state);
|
void encode_one_frame(encoder_state *encoder_state);
|
||||||
int read_one_frame(FILE* file, const encoder_state *encoder);
|
int read_one_frame(FILE* file, const encoder_state *encoder);
|
||||||
|
|
||||||
|
void encoder_compute_stats(encoder_state *encoder_state, FILE * const recout, uint32_t *stat_frames, double psnr[3]);
|
||||||
void encoder_next_frame(encoder_state *encoder_state);
|
void encoder_next_frame(encoder_state *encoder_state);
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue