From c0c9bc619a081e4e5bdbef256cbe7dab0b26d363 Mon Sep 17 00:00:00 2001 From: Ari Koivula Date: Wed, 29 Apr 2015 17:22:53 +0300 Subject: [PATCH 1/3] Fix valgrind warning. - Attribute state->global->slicetype was used before being initialized. - The reference frame lists should be updated based on current frame, not on previous frame (or uninitialized data). --- src/encoderstate.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/encoderstate.c b/src/encoderstate.c index 27747e19..f85224f2 100644 --- a/src/encoderstate.c +++ b/src/encoderstate.c @@ -784,14 +784,9 @@ static void encoder_state_new_frame(encoder_state_t * const state) { } if (state->global->is_radl_frame) { - // Clear the reference list - encoder_state_clear_refs(state); - state->global->slicetype = SLICE_I; state->global->pictype = NAL_IDR_W_RADL; } else { - encoder_state_remove_refs(state); - encoder_state_ref_sort(state); state->global->slicetype = encoder->cfg->intra_period==1 ? SLICE_I : (state->encoder_control->cfg->gop_len?SLICE_B:SLICE_P); state->global->pictype = NAL_TRAIL_R; if (state->encoder_control->cfg->gop_len) { @@ -800,6 +795,14 @@ static void encoder_state_new_frame(encoder_state_t * const state) { } } } + + if (state->global->is_radl_frame) { + encoder_state_clear_refs(state); + } else { + encoder_state_remove_refs(state); + encoder_state_ref_sort(state); + } + if (state->encoder_control->cfg->gop_len) { if (state->global->slicetype == SLICE_I) { state->global->QP = state->encoder_control->cfg->qp; From b43f1cb9ebea0c3a38ee3e2f585bbbe306f67c1f Mon Sep 17 00:00:00 2001 From: Ari Koivula Date: Thu, 30 Apr 2015 13:02:02 +0300 Subject: [PATCH 2/3] Fix keeping of reference frames over IDR boundary. - --- src/encoderstate.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/encoderstate.c b/src/encoderstate.c index f85224f2..c2880a30 100644 --- a/src/encoderstate.c +++ b/src/encoderstate.c @@ -720,7 +720,7 @@ static void encoder_state_remove_refs(encoder_state_t *state) { refnumber = encoder->cfg->gop[state->global->gop_offset].ref_neg_count + encoder->cfg->gop[state->global->gop_offset].ref_pos_count; check_refs = 1; } else if (state->global->slicetype == SLICE_I) { - refnumber = 1; + refnumber = 0; } // Remove the ref pic (if present) while (check_refs || state->global->ref->used_size > (uint32_t)refnumber) { @@ -798,11 +798,11 @@ static void encoder_state_new_frame(encoder_state_t * const state) { if (state->global->is_radl_frame) { encoder_state_clear_refs(state); - } else { - encoder_state_remove_refs(state); - encoder_state_ref_sort(state); } + encoder_state_remove_refs(state); + encoder_state_ref_sort(state); + if (state->encoder_control->cfg->gop_len) { if (state->global->slicetype == SLICE_I) { state->global->QP = state->encoder_control->cfg->qp; From 9015aab9968a7d4f321576579a7bd9d9b1fde7ba Mon Sep 17 00:00:00 2001 From: Ari Koivula Date: Thu, 30 Apr 2015 13:30:02 +0300 Subject: [PATCH 3/3] Clean up IDR handling code. - IDR was called RADL, probably because the NAL type is IDR_W_RADL. - Move things around to make it clearer what is happening. --- src/encoder_state-bitstream.c | 2 +- src/encoderstate.c | 37 ++++++++++++++++++----------------- src/encoderstate.h | 2 +- 3 files changed, 21 insertions(+), 20 deletions(-) diff --git a/src/encoder_state-bitstream.c b/src/encoder_state-bitstream.c index e0b6555e..0dd6b8d3 100644 --- a/src/encoder_state-bitstream.c +++ b/src/encoder_state-bitstream.c @@ -785,7 +785,7 @@ static void encoder_state_write_bitstream_main(encoder_state_t * const state) { } { - uint8_t nal_type = (state->global->is_radl_frame ? NAL_IDR_W_RADL : NAL_TRAIL_R); + uint8_t nal_type = (state->global->is_idr_frame ? NAL_IDR_W_RADL : NAL_TRAIL_R); nal_write(stream, nal_type, 0, first_nal_in_au); } diff --git a/src/encoderstate.c b/src/encoderstate.c index c2880a30..9070b142 100644 --- a/src/encoderstate.c +++ b/src/encoderstate.c @@ -400,7 +400,7 @@ static void encoder_state_encode_leaf(encoder_state_t * const state) { // once. The added dependancy is for the first LCU of each wavefront // row to depend on the reconstruction status of the row below in the // previous frame. - if (state->previous_encoder_state != state && state->previous_encoder_state->tqj_recon_done && !state->global->is_radl_frame) { + if (state->previous_encoder_state != state && state->previous_encoder_state->tqj_recon_done && !state->global->is_idr_frame) { if (!lcu->left) { if (lcu->below) { threadqueue_job_dep_add(state->tile->wf_jobs[lcu->id], lcu->below->encoder_state->previous_encoder_state->tqj_recon_done); @@ -583,7 +583,7 @@ static void encoder_state_encode(encoder_state_t * const main_state) { char* job_description = NULL; #endif main_state->children[i].tqj_recon_done = threadqueue_submit(main_state->encoder_control->threadqueue, encoder_state_worker_encode_children, &(main_state->children[i]), 1, job_description); - if (main_state->children[i].previous_encoder_state != &main_state->children[i] && main_state->children[i].previous_encoder_state->tqj_recon_done && !main_state->children[i].global->is_radl_frame) { + if (main_state->children[i].previous_encoder_state != &main_state->children[i] && main_state->children[i].previous_encoder_state->tqj_recon_done && !main_state->children[i].global->is_idr_frame) { //Add dependencies to the previous frame //FIXME is this correct? threadqueue_job_dep_add(main_state->children[i].tqj_recon_done, main_state->children[i].previous_encoder_state->tqj_recon_done); @@ -752,7 +752,7 @@ static void encoder_state_remove_refs(encoder_state_t *state) { } -static void encoder_state_clear_refs(encoder_state_t *state) { +static void encoder_state_reset_poc(encoder_state_t *state) { int i; state->global->poc = 0; @@ -760,7 +760,7 @@ static void encoder_state_clear_refs(encoder_state_t *state) { for (i=0; state->children[i].encoder_control; ++i) { encoder_state_t *sub_state = &(state->children[i]); - encoder_state_clear_refs(sub_state); + encoder_state_reset_poc(sub_state); } } @@ -769,21 +769,26 @@ static void encoder_state_new_frame(encoder_state_t * const state) { //FIXME Move this somewhere else! if (state->type == ENCODER_STATE_TYPE_MAIN) { const encoder_control_t * const encoder = state->encoder_control; - - const int is_first_frame = (state->global->frame == 0); - const int is_i_radl = (encoder->cfg->intra_period == 1 && state->global->frame % 2 == 0); - const int is_p_radl = (encoder->cfg->intra_period > 1 && (state->global->frame % encoder->cfg->intra_period) == 0); - state->global->is_radl_frame = is_first_frame || is_i_radl || is_p_radl; - if (state->global->frame && encoder->cfg->gop_len) { + if (state->global->frame == 0) { + state->global->is_idr_frame = true; + } else if (encoder->cfg->gop_len) { + // Closed GOP / CRA is not yet supported. + state->global->is_idr_frame = false; + // Calculate POC according to the global frame counter and GOP structure - state->global->poc = (state->global->frame - 1) - (state->global->frame - 1) % encoder->cfg->gop_len + - encoder->cfg->gop[state->global->gop_offset].poc_offset; + int32_t poc = state->global->frame - 1; + int32_t poc_offset = encoder->cfg->gop[state->global->gop_offset].poc_offset; + state->global->poc = poc - poc % encoder->cfg->gop_len + poc_offset; videoframe_set_poc(state->tile->frame, state->global->poc); - state->global->is_radl_frame = 0; + } else { + bool is_i_idr = (encoder->cfg->intra_period == 1 && state->global->frame % 2 == 0); + bool is_p_idr = (encoder->cfg->intra_period > 1 && (state->global->frame % encoder->cfg->intra_period) == 0); + state->global->is_idr_frame = is_i_idr || is_p_idr; } - if (state->global->is_radl_frame) { + if (state->global->is_idr_frame) { + encoder_state_reset_poc(state); state->global->slicetype = SLICE_I; state->global->pictype = NAL_IDR_W_RADL; } else { @@ -796,10 +801,6 @@ static void encoder_state_new_frame(encoder_state_t * const state) { } } - if (state->global->is_radl_frame) { - encoder_state_clear_refs(state); - } - encoder_state_remove_refs(state); encoder_state_ref_sort(state); diff --git a/src/encoderstate.h b/src/encoderstate.h index 035f2177..86904e3f 100644 --- a/src/encoderstate.h +++ b/src/encoderstate.h @@ -79,7 +79,7 @@ typedef struct { int8_t idx; } refmap[16]; - int is_radl_frame; + bool is_idr_frame; uint8_t pictype; uint8_t slicetype;