From b8e3513a231678eaeeca5ca41e7d9db0e487a4bf Mon Sep 17 00:00:00 2001 From: Ari Koivula Date: Wed, 8 Feb 2017 21:27:20 +0200 Subject: [PATCH] Fix crash with sub-LCU frame sizes and WPP The end of slice was being calculated incorrectly, which led to no tile being created inside the slice, which led to an assert triggering. This fixes the wrong end of slice calculation, but also disallows wavefront rows from being created, if there would be only one. The wavefront initialization code assumes there are always more than one row, so the inter-frame dependency doesn't get added properly. Fixes #153. --- src/encoder_state-ctors_dtors.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/encoder_state-ctors_dtors.c b/src/encoder_state-ctors_dtors.c index 49d438b9..462e3c76 100644 --- a/src/encoder_state-ctors_dtors.c +++ b/src/encoder_state-ctors_dtors.c @@ -113,6 +113,9 @@ static int encoder_state_config_tile_init(encoder_state_t * const state, if (encoder->wpp) { int num_jobs = state->tile->frame->width_in_lcu * state->tile->frame->height_in_lcu; state->tile->wf_jobs = MALLOC(threadqueue_job_t*, num_jobs); + for (int i = 0; i < num_jobs; ++i) { + state->tile->wf_jobs[i] = NULL; + } if (!state->tile->wf_jobs) { printf("Error allocating wf_jobs array!\n"); return 0; @@ -365,7 +368,10 @@ int kvz_encoder_state_init(encoder_state_t * const child_state, encoder_state_t int children_allow_tile = 0; int range_start; - int start_in_ts, end_in_ts; + // First index of this encoder state in tile scan order. + int start_in_ts; + // Index of the first LCU after this state in tile scan order. + int end_in_ts; switch(child_state->type) { case ENCODER_STATE_TYPE_MAIN: @@ -377,14 +383,15 @@ int kvz_encoder_state_init(encoder_state_t * const child_state, encoder_state_t case ENCODER_STATE_TYPE_SLICE: assert(child_state->parent); if (child_state->parent->type != ENCODER_STATE_TYPE_TILE) children_allow_tile = 1; - children_allow_wavefront_row = encoder->wpp; start_in_ts = child_state->slice->start_in_ts; - end_in_ts = child_state->slice->end_in_ts; + end_in_ts = child_state->slice->end_in_ts + 1; + int num_wpp_rows = (end_in_ts - start_in_ts) / child_state->tile->frame->width_in_lcu; + children_allow_wavefront_row = encoder->wpp && num_wpp_rows > 1; break; case ENCODER_STATE_TYPE_TILE: assert(child_state->parent); if (child_state->parent->type != ENCODER_STATE_TYPE_SLICE) children_allow_slice = 1; - children_allow_wavefront_row = encoder->wpp; + children_allow_wavefront_row = encoder->wpp && child_state->tile->frame->height_in_lcu > 1; start_in_ts = child_state->tile->lcu_offset_in_ts; end_in_ts = child_state->tile->lcu_offset_in_ts + child_state->tile->frame->width_in_lcu * child_state->tile->frame->height_in_lcu; break;