From 2a85f0f5a45fd5c7929ca787d8cce4386194ecff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arttu=20Yl=C3=A4-Outinen?= Date: Mon, 26 Jun 2017 11:44:17 +0300 Subject: [PATCH] Move hard-coded MV limits to encoder_control_t Adds field max_inter_ref_lcu to encoder_control_t. It is used to set up inter-LCU dependencies in encoder_state_encode_leaf and restrict motion vectors in fracmv_within_tile. --- src/encoder.c | 3 +++ src/encoder.h | 6 ++++++ src/encoderstate.c | 28 ++++++++++++---------------- src/search_inter.c | 8 ++++---- 4 files changed, 25 insertions(+), 20 deletions(-) diff --git a/src/encoder.c b/src/encoder.c index 936b11f2..df2fe376 100644 --- a/src/encoder.c +++ b/src/encoder.c @@ -574,6 +574,9 @@ encoder_control_t* kvz_encoder_control_init(const kvz_config *const cfg) encoder->cfg.trskip_enable = false; } + encoder->max_inter_ref_lcu.right = 1; + encoder->max_inter_ref_lcu.down = 1; + // If fractional framerate is set, use that instead of the floating point framerate. if (encoder->cfg.framerate_num != 0) { encoder->vui.timing_info_present_flag = 1; diff --git a/src/encoder.h b/src/encoder.h index ddea2fc4..00d698d8 100644 --- a/src/encoder.h +++ b/src/encoder.h @@ -127,6 +127,12 @@ typedef struct encoder_control_t uint8_t dependent_slice_segments_enabled_flag; } pps; + //! Maximum motion vector distance as number of LCUs. + struct { + int right; + int down; + } max_inter_ref_lcu; + } encoder_control_t; encoder_control_t* kvz_encoder_control_init(const kvz_config *cfg); diff --git a/src/encoderstate.c b/src/encoderstate.c index da37cd20..25a3aa56 100644 --- a/src/encoderstate.c +++ b/src/encoderstate.c @@ -729,7 +729,8 @@ static void encoder_state_encode_leaf(encoder_state_t * const state) assert(state->is_leaf); assert(state->lcu_order_count > 0); - const kvz_config *cfg = &state->encoder_control->cfg; + const encoder_control_t *ctrl = state->encoder_control; + const kvz_config *cfg = &ctrl->cfg; state->ref_qp = state->frame->QP; @@ -754,7 +755,7 @@ static void encoder_state_encode_leaf(encoder_state_t * const state) #ifdef KVZ_DEBUG { const lcu_order_element_t * const lcu = &state->lcu_order[i]; - PERFORMANCE_MEASURE_END(KVZ_PERF_LCU, state->encoder_control->threadqueue, "type=encode_lcu,frame=%d,tile=%d,slice=%d,px_x=%d-%d,px_y=%d-%d", state->frame->num, state->tile->id, state->slice->id, lcu->position_px.x + state->tile->lcu_offset_x * LCU_WIDTH, lcu->position_px.x + state->tile->lcu_offset_x * LCU_WIDTH + lcu->size.x - 1, lcu->position_px.y + state->tile->lcu_offset_y * LCU_WIDTH, lcu->position_px.y + state->tile->lcu_offset_y * LCU_WIDTH + lcu->size.y - 1); + PERFORMANCE_MEASURE_END(KVZ_PERF_LCU, ctrl->threadqueue, "type=encode_lcu,frame=%d,tile=%d,slice=%d,px_x=%d-%d,px_y=%d-%d", state->frame->num, state->tile->id, state->slice->id, lcu->position_px.x + state->tile->lcu_offset_x * LCU_WIDTH, lcu->position_px.x + state->tile->lcu_offset_x * LCU_WIDTH + lcu->size.x - 1, lcu->position_px.y + state->tile->lcu_offset_y * LCU_WIDTH, lcu->position_px.y + state->tile->lcu_offset_y * LCU_WIDTH + lcu->size.y - 1); } #endif //KVZ_DEBUG } @@ -769,7 +770,7 @@ static void encoder_state_encode_leaf(encoder_state_t * const state) { // For LP-gop, depend on the state of the first reference. int ref_neg = cfg->gop[(state->frame->poc - 1) % cfg->gop_len].ref_neg[0]; - if (ref_neg > state->encoder_control->cfg.owf) { + if (ref_neg > cfg->owf) { // If frame is not within OWF range, it's already done. ref_state = NULL; } else { @@ -794,7 +795,7 @@ static void encoder_state_encode_leaf(encoder_state_t * const state) char* job_description = NULL; #endif kvz_threadqueue_free_job(&state->tile->wf_jobs[lcu->id]); - state->tile->wf_jobs[lcu->id] = kvz_threadqueue_submit(state->encoder_control->threadqueue, encoder_state_worker_encode_lcu, (void*)lcu, 1, job_description); + state->tile->wf_jobs[lcu->id] = kvz_threadqueue_submit(ctrl->threadqueue, encoder_state_worker_encode_lcu, (void*)lcu, 1, job_description); threadqueue_job_t **job = &state->tile->wf_jobs[lcu->id]; // If job object was returned, add dependancies and allow it to run. @@ -809,19 +810,14 @@ static void encoder_state_encode_leaf(encoder_state_t * const state) { // We need to wait until the CTUs whose pixels we refer to are // done before we can start this CTU. - if (lcu->below) { - if (lcu->below->right) { - kvz_threadqueue_job_dep_add(job[0], ref_state->tile->wf_jobs[lcu->below->right->id]); - } else { - kvz_threadqueue_job_dep_add(job[0], ref_state->tile->wf_jobs[lcu->below->id]); - } - } else { - if (lcu->right) { - kvz_threadqueue_job_dep_add(job[0], ref_state->tile->wf_jobs[lcu->right->id]); - } else { - kvz_threadqueue_job_dep_add(job[0], ref_state->tile->wf_jobs[lcu->id]); - } + const lcu_order_element_t *dep_lcu = lcu; + for (int i = 0; dep_lcu->below && i < ctrl->max_inter_ref_lcu.down; i++) { + dep_lcu = dep_lcu->below; } + for (int i = 0; dep_lcu->right && i < ctrl->max_inter_ref_lcu.right; i++) { + dep_lcu = dep_lcu->right; + } + kvz_threadqueue_job_dep_add(job[0], ref_state->tile->wf_jobs[dep_lcu->id]); } // Add local WPP dependancy to the LCU on the left. diff --git a/src/search_inter.c b/src/search_inter.c index 4ff55c2c..f86a54c4 100644 --- a/src/search_inter.c +++ b/src/search_inter.c @@ -70,13 +70,13 @@ static INLINE bool fracmv_within_tile(const encoder_state_t *state, const vector .y = (((orig->y + height + margin) << 2) + y) / (LCU_WIDTH << 2) - orig_lcu.y, }; - // TODO: Remove hard coded constants. - if (mv_lcu.y > 1) { + if (mv_lcu.y > ctrl->max_inter_ref_lcu.down) { return false; } - // TODO: Remove hard coded constants. - if (mv_lcu.x + mv_lcu.y > 2) { + if (mv_lcu.x + mv_lcu.y > + ctrl->max_inter_ref_lcu.down + ctrl->max_inter_ref_lcu.right) + { return false; } }