From a9463758614652ac64d59df94c268bb8d3ec86c7 Mon Sep 17 00:00:00 2001 From: lordnn Date: Wed, 15 Jul 2026 00:35:41 +0300 Subject: [PATCH 1/2] From quadratic to linear complexity. Signed-off-by: lordnn --- src/oapv.c | 36 +++++++++++++++--------------------- src/oapv_def.h | 2 ++ src/oapv_rc.c | 17 +++++++---------- 3 files changed, 24 insertions(+), 31 deletions(-) diff --git a/src/oapv.c b/src/oapv.c index 61bde19..bc8f4d3 100644 --- a/src/oapv.c +++ b/src/oapv.c @@ -771,29 +771,25 @@ static int enc_thread_tile(void *arg) oapve_core_t *core = (oapve_core_t *)arg; oapve_ctx_t *ctx = core->ctx; oapve_tile_t *tile = ctx->tile; - int ret = OAPV_OK, i; + int ret = OAPV_OK; while(1) { // find not encoded tile oapv_tpool_enter_cs(ctx->sync_obj); - for(i = 0; i < ctx->num_tiles; i++) { - if(tile[i].stat == ENC_TILE_STAT_NOT_ENCODED) { - tile[i].stat = ENC_TILE_STAT_ON_ENCODING; - core->tile_idx = i; - break; - } + core->tile_idx = ctx->tile_idx; + if (ctx->tile_idx < ctx->num_tiles) { + tile[core->tile_idx].stat = ENC_TILE_STAT_ON_ENCODING; + ++ctx->tile_idx; } oapv_tpool_leave_cs(ctx->sync_obj); - if(i == ctx->num_tiles) { + if(core->tile_idx == ctx->num_tiles) { break; } ret = enc_tile(ctx, core, &tile[core->tile_idx]); oapv_assert_g(OAPV_SUCCEEDED(ret), ERR); - oapv_tpool_enter_cs(ctx->sync_obj); tile[core->tile_idx].stat = ENC_TILE_STAT_ENCODED; - oapv_tpool_leave_cs(ctx->sync_obj); } ERR: return ret; @@ -1043,6 +1039,7 @@ static int enc_frame(oapve_ctx_t *ctx, oapv_bs_t *bs) int parallel_task = (ctx->threads > ctx->num_tiles) ? ctx->num_tiles : ctx->threads; /* encode tiles ************************************/ + ctx->tile_idx = 0; for(tidx = 0; tidx < (parallel_task - 1); tidx++) { tpool->run(ctx->thread_id[tidx], enc_thread_tile, (void *)ctx->core[tidx]); @@ -1700,7 +1697,7 @@ static int dec_tile(oapvd_core_t *core, oapvd_tile_t *tile) static int dec_thread_tile(void *arg) { oapv_bs_t bs; - int i, ret, run, tidx = 0, thread_ret = OAPV_OK; + int ret, run, tidx = 0, thread_ret = OAPV_OK; oapvd_core_t *core = (oapvd_core_t *)arg; oapvd_ctx_t *ctx = core->ctx; @@ -1709,15 +1706,13 @@ static int dec_thread_tile(void *arg) while(1) { // find not decoded tile oapv_tpool_enter_cs(ctx->sync_obj); - for(i = 0; i < ctx->num_tiles; i++) { - if(DEC_TILE_STAT_IS_DO(tile[i].stat)) { - tile[i].stat = DEC_TILE_STAT_ON(tile[i].stat); - tidx = i; - break; - } + tidx = ctx->tile_idx; + if (ctx->tile_idx < ctx->num_tiles) { + tile[tidx].stat = DEC_TILE_STAT_ON(tile[tidx].stat); + ++ctx->tile_idx; } oapv_tpool_leave_cs(ctx->sync_obj); - if(i == ctx->num_tiles) { + if(tidx == ctx->num_tiles) { break; // end of worker thread } @@ -1748,11 +1743,10 @@ static int dec_thread_tile(void *arg) } oapv_tpool_leave_cs(ctx->sync_obj); - if(DEC_TILE_STAT_IS_DECODE(tile[i].stat)) { + if(DEC_TILE_STAT_IS_DECODE(tile[tidx].stat)) { ret = dec_tile(core, &tile[tidx]); } - oapv_tpool_enter_cs(ctx->sync_obj); if (OAPV_SUCCEEDED(ret)) { tile[tidx].stat = DEC_TILE_STAT_DONE(tile[tidx].stat); } @@ -1760,7 +1754,6 @@ static int dec_thread_tile(void *arg) tile[tidx].stat = DEC_TILE_STAT_ERR(tile[tidx].stat); thread_ret = ret; } - oapv_tpool_leave_cs(ctx->sync_obj); } return thread_ret; @@ -2002,6 +1995,7 @@ int oapvd_decode(oapvd_t did, oapv_bitb_t *bitb, oapv_frms_t *ofrms, oapvm_t mid parallel_task = (ctx->threads > ctx->num_tiles) ? ctx->num_tiles : ctx->threads; /* decode tiles ************************************/ + ctx->tile_idx = 0; for(tidx = 0; tidx < (parallel_task - 1); tidx++) { tpool->run(ctx->thread_id[tidx], dec_thread_tile, (void *)ctx->core[tidx]); diff --git a/src/oapv_def.h b/src/oapv_def.h index b834526..274f308 100644 --- a/src/oapv_def.h +++ b/src/oapv_def.h @@ -286,6 +286,7 @@ struct oapve_ctx { int au_bs_fmt; // access unit bitstream format int num_tiles_frms[OAPV_MAX_NUM_FRAMES]; int num_tiles; + int tile_idx; int num_tile_cols; int num_tile_rows; int qp[N_C]; @@ -400,6 +401,7 @@ struct oapvd_ctx { oapv_sync_obj_t sync_obj; u8 *tile_end; int num_tiles; + int tile_idx; int num_tile_cols; int num_tile_rows; int w; diff --git a/src/oapv_rc.c b/src/oapv_rc.c index 25d6e3a..82239c2 100644 --- a/src/oapv_rc.c +++ b/src/oapv_rc.c @@ -77,29 +77,25 @@ int get_tile_cost_thread(void* arg) oapve_core_t* core = (oapve_core_t*)arg; oapve_ctx_t* ctx = core->ctx; oapve_tile_t* tile = ctx->tile; - int tidx = 0, ret = OAPV_OK, i; + int tidx = 0, ret = OAPV_OK; while (1) { // find not processed tile oapv_tpool_enter_cs(ctx->sync_obj); - for (i = 0; i < ctx->num_tiles; i++) { - if (tile[i].stat == ENC_TILE_STAT_NOT_ENCODED) { - tile[i].stat = ENC_TILE_STAT_ON_ENCODING; - tidx = i; - break; - } + tidx = ctx->tile_idx; + if (ctx->tile_idx < ctx->num_tiles) { + tile[tidx].stat = ENC_TILE_STAT_ON_ENCODING; + ++ctx->tile_idx; } oapv_tpool_leave_cs(ctx->sync_obj); - if (i == ctx->num_tiles) { + if (tidx == ctx->num_tiles) { break; } ret = oapve_rc_get_tile_cost(ctx, core, &tile[tidx]); oapv_assert_g(OAPV_SUCCEEDED(ret), ERR); - oapv_tpool_enter_cs(ctx->sync_obj); tile[tidx].stat = ENC_TILE_STAT_ENCODED; - oapv_tpool_leave_cs(ctx->sync_obj); } ERR: return ret; @@ -115,6 +111,7 @@ int oapve_rc_get_tile_cost_thread(oapve_ctx_t* ctx, u64* sum) int parallel_task = (ctx->threads > ctx->num_tiles) ? ctx->num_tiles : ctx->threads; // run new threads + ctx->tile_idx = 0; int tidx = 0; for (tidx = 0; tidx < (parallel_task - 1); tidx++) { tpool->run(ctx->thread_id[tidx], get_tile_cost_thread, (void*)ctx->core[tidx]); From 3a929b42a846c828dc1a9ff8cdb4b7c85663349d Mon Sep 17 00:00:00 2001 From: lordnn Date: Wed, 15 Jul 2026 00:38:02 +0300 Subject: [PATCH 2/2] Removed `volatile`. Signed-off-by: lordnn --- src/oapv_def.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/oapv_def.h b/src/oapv_def.h index 274f308..a7d2b51 100644 --- a/src/oapv_def.h +++ b/src/oapv_def.h @@ -260,7 +260,7 @@ struct oapve_tile { u8 *bs_buf; s32 bs_size; u32 bs_buf_max; - volatile s32 stat; + s32 stat; }; /****************************************************************************** @@ -363,7 +363,7 @@ struct oapvd_tile { u8 *bs_beg; /* start position of tile in input bistream */ u8 *bs_end; /* end position of tile() in input bistream */ - volatile s32 stat; /* decoding status */ + s32 stat; /* decoding status */ }; typedef struct oapvd_core oapvd_core_t;