From 907451590ec305adc81f2ab003be378a69dfcc73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arttu=20Yl=C3=A4-Outinen?= Date: Tue, 7 Jul 2015 10:05:42 +0300 Subject: [PATCH] Fix encoding when both GOP and OWF are enabled. Changes kvazaar_encode to not increase cur_state_num unless a frame is started. --- src/encmain.c | 10 +++++++--- src/kvazaar.c | 27 +++++++++++++++++---------- src/kvazaar_internal.h | 13 +++++++++++++ 3 files changed, 37 insertions(+), 13 deletions(-) diff --git a/src/encmain.c b/src/encmain.c index 93d916b3..e1c3e684 100644 --- a/src/encmain.c +++ b/src/encmain.c @@ -168,8 +168,6 @@ int main(int argc, char *argv[]) double psnr_sum[3] = { 0.0, 0.0, 0.0 }; for (;;) { - encoder_state_t *state = &enc->states[enc->cur_state_num]; - kvz_picture *img_in = NULL; if (!feof(input) && (opts->frames == 0 || frames_read < opts->frames)) { // Try to read an input frame. @@ -225,7 +223,13 @@ int main(int argc, char *argv[]) bitstream_length += len_out; // Compute and print stats. - state = &enc->states[enc->cur_state_num]; + + // Number of the state that was finished is one less than + // enc->out_state_num. + encoder_state_t *state = &enc->states[ + (enc->out_state_num + enc->num_encoder_states - 1) % + enc->num_encoder_states + ]; double frame_psnr[3] = { 0.0, 0.0, 0.0 }; encoder_compute_stats(state, recout, frame_psnr); diff --git a/src/kvazaar.c b/src/kvazaar.c index e1f1fd05..e8da06f6 100644 --- a/src/kvazaar.c +++ b/src/kvazaar.c @@ -72,6 +72,7 @@ static kvz_encoder * kvazaar_open(const kvz_config *cfg) encoder->num_encoder_states = encoder->control->owf + 1; encoder->cur_state_num = 0; + encoder->out_state_num = 0; encoder->frames_started = 0; encoder->frames_done = 0; encoder->states = calloc(encoder->num_encoder_states, sizeof(encoder_state_t)); @@ -141,21 +142,27 @@ static int kvazaar_encode(kvz_encoder *enc, return 1; } - // Move to the next encoder state. - enc->cur_state_num = (enc->cur_state_num + 1) % (enc->num_encoder_states); - state = &enc->states[enc->cur_state_num]; - if (!state->frame_done) { - threadqueue_waitfor(enc->control->threadqueue, state->tqj_bitstream_written); + // We started encoding a frame; move to the next encoder state. + enc->cur_state_num = (enc->cur_state_num + 1) % (enc->num_encoder_states); + } + + encoder_state_t *output_state = &enc->states[enc->out_state_num]; + if (!output_state->frame_done && + (pic_in == NULL || enc->cur_state_num == enc->out_state_num)) { + + threadqueue_waitfor(enc->control->threadqueue, output_state->tqj_bitstream_written); // Get stream length before taking chunks since that clears the stream. - if (len_out) *len_out = bitstream_tell(&state->stream) / 8; - if (data_out) *data_out = bitstream_take_chunks(&state->stream); - if (pic_out) *pic_out = image_copy_ref(state->tile->frame->rec); + if (len_out) *len_out = bitstream_tell(&output_state->stream) / 8; + if (data_out) *data_out = bitstream_take_chunks(&output_state->stream); + if (pic_out) *pic_out = image_copy_ref(output_state->tile->frame->rec); - state->frame_done = 1; - state->prepared = 0; + output_state->frame_done = 1; + output_state->prepared = 0; enc->frames_done += 1; + + enc->out_state_num = (enc->out_state_num + 1) % (enc->num_encoder_states); } return 1; diff --git a/src/kvazaar_internal.h b/src/kvazaar_internal.h index 98181b97..fe73825f 100644 --- a/src/kvazaar_internal.h +++ b/src/kvazaar_internal.h @@ -30,7 +30,20 @@ struct kvz_encoder { struct encoder_control_t* control; struct encoder_state_t* states; unsigned num_encoder_states; + + /** + * \brief Number of the current encoder state. + * + * The current state is the one that will be used for encoding the frame + * that is started next. + */ unsigned cur_state_num; + + /** + * \brief Number of the next encoder state to be finished. + */ + unsigned out_state_num; + unsigned frames_started; unsigned frames_done;