/*
- * Copyright (C) 2007 Vitor <vitor1001@gmail.com>
+ * Copyright (C) 2007 Vitor Sessak <vitor1001@gmail.com>
*
* This file is part of FFmpeg.
*
*/
/**
- * @file cbook_gen.c
+ * @file libavcodec/elbg.c
* Codebook Generator using the ELBG algorithm
*/
#include <string.h>
+#include "libavutil/lfg.h"
#include "elbg.h"
#include "avcodec.h"
-#include "random.h"
#define DELTA_ERR_MAX 0.1 ///< Precision of the ELBG algorithm (as percentual error)
int *utility_inc;
int *nearest_cb;
int *points;
- AVRandomState *rand_state;
+ AVLFG *rand_state;
} elbg_data;
static inline int distance_limited(int *a, int *b, int dim, int limit)
{
int i=0;
/* Using linear search, do binary if it ever turns to be speed critical */
- int r = av_random(elbg->rand_state)%elbg->utility_inc[elbg->numCB-1];
+ int r = av_lfg_get(elbg->rand_state)%elbg->utility_inc[elbg->numCB-1] + 1;
while (elbg->utility_inc[i] < r)
i++;
+
+ assert(!elbg->cells[i]);
+
return i;
}
* Implementation of the simple LBG algorithm for just two codebooks
*/
static int simple_lbg(int dim,
- int centroid[3][dim],
+ int *centroid[3],
int newutility[3],
int *points,
cell *cells)
* @param newcentroid A vector with the position of the new centroids
*/
static void shift_codebook(elbg_data *elbg, int *indexes,
- int newcentroid[3][elbg->dim])
+ int *newcentroid[3])
{
cell *tempdata;
cell **pp = &elbg->cells[indexes[2]];
int j, k, olderror=0, newerror, cont=0;
int newutility[3];
int newcentroid[3][elbg->dim];
+ int *newcentroid_ptrs[3];
cell *tempcell;
+ newcentroid_ptrs[0] = newcentroid[0];
+ newcentroid_ptrs[1] = newcentroid[1];
+ newcentroid_ptrs[2] = newcentroid[2];
+
for (j=0; j<3; j++)
olderror += elbg->utility[idx[j]];
newerror = newutility[2];
- newerror += simple_lbg(elbg->dim, newcentroid, newutility, elbg->points,
+ newerror += simple_lbg(elbg->dim, newcentroid_ptrs, newutility, elbg->points,
elbg->cells[idx[1]]);
if (olderror > newerror) {
- shift_codebook(elbg, idx, newcentroid);
+ shift_codebook(elbg, idx, newcentroid_ptrs);
elbg->error += newerror - olderror;
idx[1] = get_high_utility_cell(elbg);
idx[2] = get_closest_codebook(elbg, idx[0]);
- try_shift_candidate(elbg, idx);
+ if (idx[1] != idx[0] && idx[1] != idx[2])
+ try_shift_candidate(elbg, idx);
}
}
void ff_init_elbg(int *points, int dim, int numpoints, int *codebook,
int numCB, int max_steps, int *closest_cb,
- AVRandomState *rand_state)
+ AVLFG *rand_state)
{
int i, k;
void ff_do_elbg(int *points, int dim, int numpoints, int *codebook,
int numCB, int max_steps, int *closest_cb,
- AVRandomState *rand_state)
+ AVLFG *rand_state)
{
int dist;
elbg_data elbg_d;