Fix encoding when both GOP and OWF are enabled.

Changes kvazaar_encode to not increase cur_state_num unless a frame is
started.
This commit is contained in:
Arttu Ylä-Outinen 2015-07-07 10:05:42 +03:00
parent 3efdee2c13
commit 907451590e
3 changed files with 37 additions and 13 deletions

View file

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

View file

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

View file

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