mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-28 20:53:54 +02:00
avcodec/elbg: Move arguments to the context early if possible
This affects all the arguments that don't change during a call to avpriv_elbg_do(); doing so makes it easily recognizable which arguments change upon recursive calls. Reviewed-by: Paul B Mahol <onemda@gmail.com> Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This commit is contained in:
parent
896c11687e
commit
5e01527330
@ -332,30 +332,22 @@ static void do_shiftings(ELBGContext *elbg)
|
||||
}
|
||||
}
|
||||
|
||||
static int do_elbg(int *points, int dim, int numpoints, int *codebook,
|
||||
int num_cb, int max_steps, int *closest_cb,
|
||||
AVLFG *rand_state)
|
||||
static int do_elbg(ELBGContext *elbg, int *points, int numpoints,
|
||||
int max_steps)
|
||||
{
|
||||
int dist;
|
||||
ELBGContext elbg_d;
|
||||
ELBGContext *elbg = &elbg_d;
|
||||
int i, j, steps = 0, ret = 0;
|
||||
int *size_part = av_malloc_array(num_cb, sizeof(int));
|
||||
int *size_part = av_malloc_array(elbg->num_cb, sizeof(int));
|
||||
cell *list_buffer = av_malloc_array(numpoints, sizeof(cell));
|
||||
cell *free_cells;
|
||||
int best_dist, best_idx = 0;
|
||||
int best_idx = 0;
|
||||
int64_t last_error;
|
||||
|
||||
elbg->error = INT64_MAX;
|
||||
elbg->dim = dim;
|
||||
elbg->num_cb = num_cb;
|
||||
elbg->codebook = codebook;
|
||||
elbg->cells = av_malloc_array(num_cb, sizeof(cell *));
|
||||
elbg->utility = av_malloc_array(num_cb, sizeof(*elbg->utility));
|
||||
elbg->nearest_cb = closest_cb;
|
||||
elbg->cells = av_malloc_array(elbg->num_cb, sizeof(cell *));
|
||||
elbg->utility = av_malloc_array(elbg->num_cb, sizeof(*elbg->utility));
|
||||
elbg->points = points;
|
||||
elbg->utility_inc = av_malloc_array(num_cb, sizeof(*elbg->utility_inc));
|
||||
elbg->scratchbuf = av_malloc_array(5*dim, sizeof(int));
|
||||
elbg->utility_inc = av_malloc_array(elbg->num_cb, sizeof(*elbg->utility_inc));
|
||||
elbg->scratchbuf = av_malloc_array(5 * elbg->dim, sizeof(int));
|
||||
|
||||
if (!size_part || !list_buffer || !elbg->cells ||
|
||||
!elbg->utility || !elbg->utility_inc || !elbg->scratchbuf) {
|
||||
@ -363,23 +355,26 @@ static int do_elbg(int *points, int dim, int numpoints, int *codebook,
|
||||
goto out;
|
||||
}
|
||||
|
||||
elbg->rand_state = rand_state;
|
||||
|
||||
do {
|
||||
free_cells = list_buffer;
|
||||
last_error = elbg->error;
|
||||
steps++;
|
||||
memset(elbg->utility, 0, num_cb * sizeof(*elbg->utility));
|
||||
memset(elbg->cells, 0, num_cb * sizeof(*elbg->cells));
|
||||
memset(elbg->utility, 0, elbg->num_cb * sizeof(*elbg->utility));
|
||||
memset(elbg->cells, 0, elbg->num_cb * sizeof(*elbg->cells));
|
||||
|
||||
elbg->error = 0;
|
||||
|
||||
/* This loop evaluate the actual Voronoi partition. It is the most
|
||||
costly part of the algorithm. */
|
||||
for (i=0; i < numpoints; i++) {
|
||||
best_dist = distance_limited(elbg->points + i*elbg->dim, elbg->codebook + best_idx*elbg->dim, dim, INT_MAX);
|
||||
int best_dist = distance_limited(elbg->points + i * elbg->dim,
|
||||
elbg->codebook + best_idx * elbg->dim,
|
||||
elbg->dim, INT_MAX);
|
||||
for (int k = 0; k < elbg->num_cb; k++) {
|
||||
dist = distance_limited(elbg->points + i*elbg->dim, elbg->codebook + k*elbg->dim, dim, best_dist);
|
||||
int dist = distance_limited(elbg->points + i * elbg->dim,
|
||||
elbg->codebook + k * elbg->dim,
|
||||
elbg->dim, best_dist);
|
||||
if (dist < best_dist) {
|
||||
best_dist = dist;
|
||||
best_idx = k;
|
||||
@ -396,9 +391,9 @@ static int do_elbg(int *points, int dim, int numpoints, int *codebook,
|
||||
|
||||
do_shiftings(elbg);
|
||||
|
||||
memset(size_part, 0, num_cb * sizeof(*size_part));
|
||||
memset(size_part, 0, elbg->num_cb * sizeof(*size_part));
|
||||
|
||||
memset(elbg->codebook, 0, elbg->num_cb * dim * sizeof(*elbg->codebook));
|
||||
memset(elbg->codebook, 0, elbg->num_cb * elbg->dim * sizeof(*elbg->codebook));
|
||||
|
||||
for (i=0; i < numpoints; i++) {
|
||||
size_part[elbg->nearest_cb[i]]++;
|
||||
@ -433,13 +428,13 @@ out:
|
||||
* points.
|
||||
* @return < 0 in case of error, 0 otherwise
|
||||
*/
|
||||
static int init_elbg(int *points, int dim, int numpoints, int *codebook,
|
||||
int num_cb, int max_steps, int *closest_cb,
|
||||
AVLFG *rand_state)
|
||||
static int init_elbg(ELBGContext *elbg, int *points, int numpoints,
|
||||
int max_steps)
|
||||
{
|
||||
int dim = elbg->dim;
|
||||
int ret = 0;
|
||||
|
||||
if (numpoints > 24LL * num_cb) {
|
||||
if (numpoints > 24LL * elbg->num_cb) {
|
||||
/* ELBG is very costly for a big number of points. So if we have a lot
|
||||
of them, get a good initial codebook to save on iterations */
|
||||
int *temp_points = av_malloc_array(dim, (numpoints/8)*sizeof(*temp_points));
|
||||
@ -450,19 +445,17 @@ static int init_elbg(int *points, int dim, int numpoints, int *codebook,
|
||||
memcpy(temp_points + i*dim, points + k*dim, dim * sizeof(*temp_points));
|
||||
}
|
||||
|
||||
ret = init_elbg(temp_points, dim, numpoints / 8, codebook,
|
||||
num_cb, 2 * max_steps, closest_cb, rand_state);
|
||||
ret = init_elbg(elbg, temp_points, numpoints / 8, 2 * max_steps);
|
||||
if (ret < 0) {
|
||||
av_freep(&temp_points);
|
||||
return ret;
|
||||
}
|
||||
ret = do_elbg (temp_points, dim, numpoints / 8, codebook,
|
||||
num_cb, 2 * max_steps, closest_cb, rand_state);
|
||||
ret = do_elbg(elbg, temp_points, numpoints / 8, 2 * max_steps);
|
||||
av_free(temp_points);
|
||||
} else // If not, initialize the codebook with random positions
|
||||
for (int i = 0; i < num_cb; i++)
|
||||
memcpy(codebook + i * dim, points + ((i*BIG_PRIME)%numpoints)*dim,
|
||||
dim * sizeof(*codebook));
|
||||
for (int i = 0; i < elbg->num_cb; i++)
|
||||
memcpy(elbg->codebook + i * dim, points + ((i*BIG_PRIME)%numpoints)*dim,
|
||||
dim * sizeof(*elbg->codebook));
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -477,12 +470,16 @@ int avpriv_elbg_do(ELBGContext **elbgp, int *points, int dim, int numpoints,
|
||||
return AVERROR(ENOMEM);
|
||||
*elbgp = elbg;
|
||||
|
||||
ret = init_elbg(points, dim, numpoints, codebook,
|
||||
num_cb, max_steps, closest_cb, rand_state);
|
||||
elbg->nearest_cb = closest_cb;
|
||||
elbg->rand_state = rand_state;
|
||||
elbg->codebook = codebook;
|
||||
elbg->num_cb = num_cb;
|
||||
elbg->dim = dim;
|
||||
|
||||
ret = init_elbg(elbg, points, numpoints, max_steps);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
return do_elbg (points, dim, numpoints, codebook,
|
||||
num_cb, max_steps, closest_cb, rand_state);
|
||||
return do_elbg (elbg, points, numpoints, max_steps);
|
||||
}
|
||||
|
||||
av_cold void avpriv_elbg_free(ELBGContext **elbgp)
|
||||
|
Loading…
Reference in New Issue
Block a user