Merge branch 'ref-fix'

This commit is contained in:
Ari Koivula 2015-04-30 22:25:24 +03:00
commit a121665d80
3 changed files with 26 additions and 22 deletions

View file

@ -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); nal_write(stream, nal_type, 0, first_nal_in_au);
} }

View file

@ -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 // 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 // row to depend on the reconstruction status of the row below in the
// previous frame. // 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->left) {
if (lcu->below) { if (lcu->below) {
threadqueue_job_dep_add(state->tile->wf_jobs[lcu->id], lcu->below->encoder_state->previous_encoder_state->tqj_recon_done); 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; char* job_description = NULL;
#endif #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); 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 //Add dependencies to the previous frame
//FIXME is this correct? //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); threadqueue_job_dep_add(main_state->children[i].tqj_recon_done, main_state->children[i].previous_encoder_state->tqj_recon_done);
@ -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; refnumber = encoder->cfg->gop[state->global->gop_offset].ref_neg_count + encoder->cfg->gop[state->global->gop_offset].ref_pos_count;
check_refs = 1; check_refs = 1;
} else if (state->global->slicetype == SLICE_I) { } else if (state->global->slicetype == SLICE_I) {
refnumber = 1; refnumber = 0;
} }
// Remove the ref pic (if present) // Remove the ref pic (if present)
while (check_refs || state->global->ref->used_size > (uint32_t)refnumber) { while (check_refs || state->global->ref->used_size > (uint32_t)refnumber) {
@ -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; int i;
state->global->poc = 0; 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) { for (i=0; state->children[i].encoder_control; ++i) {
encoder_state_t *sub_state = &(state->children[i]); encoder_state_t *sub_state = &(state->children[i]);
encoder_state_clear_refs(sub_state); encoder_state_reset_poc(sub_state);
} }
} }
@ -769,29 +769,29 @@ static void encoder_state_new_frame(encoder_state_t * const state) {
//FIXME Move this somewhere else! //FIXME Move this somewhere else!
if (state->type == ENCODER_STATE_TYPE_MAIN) { if (state->type == ENCODER_STATE_TYPE_MAIN) {
const encoder_control_t * const encoder = state->encoder_control; 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 // 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 + int32_t poc = state->global->frame - 1;
encoder->cfg->gop[state->global->gop_offset].poc_offset; 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); 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) {
// Clear the reference list encoder_state_reset_poc(state);
encoder_state_clear_refs(state);
state->global->slicetype = SLICE_I; state->global->slicetype = SLICE_I;
state->global->pictype = NAL_IDR_W_RADL; state->global->pictype = NAL_IDR_W_RADL;
} else { } 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->slicetype = encoder->cfg->intra_period==1 ? SLICE_I : (state->encoder_control->cfg->gop_len?SLICE_B:SLICE_P);
state->global->pictype = NAL_TRAIL_R; state->global->pictype = NAL_TRAIL_R;
if (state->encoder_control->cfg->gop_len) { if (state->encoder_control->cfg->gop_len) {
@ -800,6 +800,10 @@ static void encoder_state_new_frame(encoder_state_t * const state) {
} }
} }
} }
encoder_state_remove_refs(state);
encoder_state_ref_sort(state);
if (state->encoder_control->cfg->gop_len) { if (state->encoder_control->cfg->gop_len) {
if (state->global->slicetype == SLICE_I) { if (state->global->slicetype == SLICE_I) {
state->global->QP = state->encoder_control->cfg->qp; state->global->QP = state->encoder_control->cfg->qp;

View file

@ -79,7 +79,7 @@ typedef struct {
int8_t idx; int8_t idx;
} refmap[16]; } refmap[16];
int is_radl_frame; bool is_idr_frame;
uint8_t pictype; uint8_t pictype;
uint8_t slicetype; uint8_t slicetype;