Beispiel #1
0
void
kdtree_semigreedy_tour(kdtree *tree, data *d, int start, int *tour, int *len)
{
    int dim = d->numnodes;
    int i, current, next;
    int lenght = 0;
    /* RCL. */
    int j, k;
    double total_bias, prob_acc, prob_pick, prob;
    struct rcl params;

    params.candidates = MALLOC(dim, struct heapelm);

    tour[0] = start;
    current = start;
    for (i = 1; i < dim; i++) {
        kdtree_delete(tree, current);

        /* Define RCL size. */
        params.rcl_used = 0;
        params.rcl_size = RANDOM(3) + 1;

        kdtree_m_nearest_neighbours(tree, d, current, &params);

        /*printf("RCL size: %d, used: %d\n", params.rcl_size, params.rcl_used);
        heap_dump(params.candidates, params.rcl_used);*/

        /* Pick an element from RCL. */
        total_bias = 0;
        for (j = 1; j <= params.rcl_used; j++) {
            total_bias += BIAS(j);
        }

        prob_acc = 0;
        prob_pick = RANDOM_UNIT();
        for (j = params.rcl_used, k = 1; j >= 0; j--, k++) {
            prob = BIAS(k) / total_bias;
            if (prob + prob_acc > prob_pick) {
                break;
            }
            prob_acc += prob;
        }
        /*printf("Picked %d: %d, %d\n", j, params.candidates[j - 1].num,
                params.candidates[j - 1].cost);*/
        next = params.candidates[j - 1].num;

        /* Update tour. */
        tour[i] = next;
        lenght += params.candidates[j - 1].cost;
        current = next;
    }
    lenght += d->dist(d, current, start);
    *len = lenght;

    kdtree_undelete_all(tree, d->numnodes);

    free(params.candidates);
}
Beispiel #2
0
static void mix22toS (sample_t * samples, sample_t bias)
{
    int i;
    sample_t surround;

    for (i = 0; i < 256; i++) {
	surround = samples[i + 512] + samples[i + 768];
	samples[i] += BIAS (-surround);
	samples[i + 256] += BIAS (surround);
    }
}
Beispiel #3
0
static void move2to1 (sample_t * src, sample_t * dest, sample_t bias)
{
    int i;

    for (i = 0; i < 256; i++)
	dest[i] = BIAS (src[i] + src[i + 256]);
}
Beispiel #4
0
static void mix3to1 (sample_t * samples, sample_t bias)
{
    int i;

    for (i = 0; i < 256; i++)
	samples[i] += BIAS (samples[i + 256] + samples[i + 512]);
}
Beispiel #5
0
static void mix2to1 (sample_t * dest, sample_t * src, sample_t bias)
{
    int i;

    for (i = 0; i < 256; i++)
	dest[i] += BIAS (src[i]);
}
Beispiel #6
0
static void mix32to2 (sample_t * samples, sample_t bias)
{
    int i;
    sample_t common;

    for (i = 0; i < 256; i++) {
	common = BIAS (samples[i + 256]);
	samples[i] += common + samples[i + 768];
	samples[i + 256] = common + samples[i + 512] + samples[i + 1024];
    }
}
Beispiel #7
0
static void mix31to2 (sample_t * samples, sample_t bias)
{
    int i;
    sample_t common;

    for (i = 0; i < 256; i++) {
	common = BIAS (samples[i + 256] + samples[i + 768]);
	samples[i] += common;
	samples[i + 256] = samples[i + 512] + common;
    }
}
Beispiel #8
0
static void mix21to2 (sample_t * left, sample_t * right, sample_t bias)
{
    int i;
    sample_t common;

    for (i = 0; i < 256; i++) {
	common = BIAS (right[i + 256]);
	left[i] += common;
	right[i] += common;
    }
}
Beispiel #9
0
static void mix32toS (sample_t * samples, sample_t bias)
{
    int i;
    sample_t common, surround;

    for (i = 0; i < 256; i++) {
	common = BIAS (samples[i + 256]);
	surround = samples[i + 768] + samples[i + 1024];
	samples[i] += common - surround;
	samples[i + 256] = samples[i + 512] + common + surround;
    }
}
Beispiel #10
0
// Returns the average quantizer
static int ExpandMatrix(VP8Matrix* const m, int type) {
  int i;
  int sum = 0;
  for (i = 2; i < 16; ++i) {
    m->q_[i] = m->q_[1];
  }
  for (i = 0; i < 16; ++i) {
    const int is_ac_coeff = (i > 0);
    const int bias = kBiasMatrices[type][is_ac_coeff];
    m->iq_[i] = (1 << QFIX) / m->q_[i];
    m->bias_[i] = BIAS(bias);
    // TODO(skal): tune kCoeffThresh[]
    m->zthresh_[i] = ((256 /*+ kCoeffThresh[i]*/ - bias) * m->q_[i] + 127) >> 8;
    m->sharpen_[i] = (kFreqSharpening[i] * m->q_[i]) >> 11;
    sum += m->q_[i];
  }
  return (sum + 8) >> 4;
}
Beispiel #11
0
// Returns the average quantizer
static int ExpandMatrix(VP8Matrix* const m, int type) {
  int i, sum;
  for (i = 0; i < 2; ++i) {
    const int is_ac_coeff = (i > 0);
    const int bias = kBiasMatrices[type][is_ac_coeff];
    m->iq_[i] = (1 << QFIX) / m->q_[i];
    m->bias_[i] = BIAS(bias);
    // zthresh_ is the exact value such that QUANTDIV(coeff, iQ, B) is:
    //   * zero if coeff <= zthresh
    //   * non-zero if coeff > zthresh
    m->zthresh_[i] = ((1 << QFIX) - 1 - m->bias_[i]) / m->iq_[i];
  }
  for (i = 2; i < 16; ++i) {
    m->q_[i] = m->q_[1];
    m->iq_[i] = m->iq_[1];
    m->bias_[i] = m->bias_[1];
    m->zthresh_[i] = m->zthresh_[1];
  }
  for (sum = 0, i = 0; i < 16; ++i) {
    if (type == 0) {  // we only use sharpening for AC luma coeffs
      m->sharpen_[i] = (kFreqSharpening[i] * m->q_[i]) >> SHARPEN_BITS;
    } else {
Beispiel #12
0
static int TrellisQuantizeBlock(const VP8EncIterator* const it,
                                int16_t in[16], int16_t out[16],
                                int ctx0, int coeff_type,
                                const VP8Matrix* const mtx,
                                int lambda) {
  ProbaArray* const last_costs = it->enc_->proba_.coeffs_[coeff_type];
  CostArray* const costs = it->enc_->proba_.level_cost_[coeff_type];
  const int first = (coeff_type == 0) ? 1 : 0;
  Node nodes[17][NUM_NODES];
  int best_path[3] = {-1, -1, -1};   // store best-last/best-level/best-previous
  score_t best_score;
  int best_node;
  int last = first - 1;
  int n, m, p, nz;

  {
    score_t cost;
    score_t max_error;
    const int thresh = mtx->q_[1] * mtx->q_[1] / 4;
    const int last_proba = last_costs[VP8EncBands[first]][ctx0][0];

    // compute maximal distortion.
    max_error = 0;
    for (n = first; n < 16; ++n) {
      const int j  = kZigzag[n];
      const int err = in[j] * in[j];
      max_error += kWeightTrellis[j] * err;
      if (err > thresh) last = n;
    }
    // we don't need to go inspect up to n = 16 coeffs. We can just go up
    // to last + 1 (inclusive) without losing much.
    if (last < 15) ++last;

    // compute 'skip' score. This is the max score one can do.
    cost = VP8BitCost(0, last_proba);
    best_score = RDScoreTrellis(lambda, cost, max_error);

    // initialize source node.
    n = first - 1;
    for (m = -MIN_DELTA; m <= MAX_DELTA; ++m) {
      NODE(n, m).cost = 0;
      NODE(n, m).error = max_error;
      NODE(n, m).ctx = ctx0;
    }
  }

  // traverse trellis.
  for (n = first; n <= last; ++n) {
    const int j  = kZigzag[n];
    const int Q  = mtx->q_[j];
    const int iQ = mtx->iq_[j];
    const int B = BIAS(0x00);     // neutral bias
    // note: it's important to take sign of the _original_ coeff,
    // so we don't have to consider level < 0 afterward.
    const int sign = (in[j] < 0);
    int coeff0 = (sign ? -in[j] : in[j]) + mtx->sharpen_[j];
    int level0;
    if (coeff0 > 2047) coeff0 = 2047;

    level0 = QUANTDIV(coeff0, iQ, B);
    // test all alternate level values around level0.
    for (m = -MIN_DELTA; m <= MAX_DELTA; ++m) {
      Node* const cur = &NODE(n, m);
      int delta_error, new_error;
      score_t cur_score = MAX_COST;
      int level = level0 + m;
      int last_proba;

      cur->sign = sign;
      cur->level = level;
      cur->ctx = (level == 0) ? 0 : (level == 1) ? 1 : 2;
      if (level >= 2048 || level < 0) {   // node is dead?
        cur->cost = MAX_COST;
        continue;
      }
      last_proba = last_costs[VP8EncBands[n + 1]][cur->ctx][0];

      // Compute delta_error = how much coding this level will
      // subtract as distortion to max_error
      new_error = coeff0 - level * Q;
      delta_error =
        kWeightTrellis[j] * (coeff0 * coeff0 - new_error * new_error);

      // Inspect all possible non-dead predecessors. Retain only the best one.
      for (p = -MIN_DELTA; p <= MAX_DELTA; ++p) {
        const Node* const prev = &NODE(n - 1, p);
        const int prev_ctx = prev->ctx;
        const uint16_t* const tcost = costs[VP8EncBands[n]][prev_ctx];
        const score_t total_error = prev->error - delta_error;
        score_t cost, base_cost, score;

        if (prev->cost >= MAX_COST) {   // dead node?
          continue;
        }

        // Base cost of both terminal/non-terminal
        base_cost = prev->cost + VP8LevelCost(tcost, level);

        // Examine node assuming it's a non-terminal one.
        cost = base_cost;
        if (level && n < 15) {
          cost += VP8BitCost(1, last_proba);
        }
        score = RDScoreTrellis(lambda, cost, total_error);
        if (score < cur_score) {
          cur_score = score;
          cur->cost  = cost;
          cur->error = total_error;
          cur->prev  = p;
        }

        // Now, record best terminal node (and thus best entry in the graph).
        if (level) {
          cost = base_cost;
          if (n < 15) cost += VP8BitCost(0, last_proba);
          score = RDScoreTrellis(lambda, cost, total_error);
          if (score < best_score) {
            best_score = score;
            best_path[0] = n;   // best eob position
            best_path[1] = m;   // best level
            best_path[2] = p;   // best predecessor
          }
        }
      }
    }
  }

  // Fresh start
  memset(in + first, 0, (16 - first) * sizeof(*in));
  memset(out + first, 0, (16 - first) * sizeof(*out));
  if (best_path[0] == -1) {
    return 0;   // skip!
  }

  // Unwind the best path.
  // Note: best-prev on terminal node is not necessarily equal to the
  // best_prev for non-terminal. So we patch best_path[2] in.
  n = best_path[0];
  best_node = best_path[1];
  NODE(n, best_node).prev = best_path[2];   // force best-prev for terminal
  nz = 0;

  for (; n >= first; --n) {
    const Node* const node = &NODE(n, best_node);
    const int j = kZigzag[n];
    out[n] = node->sign ? -node->level : node->level;
    nz |= (node->level != 0);
    in[j] = out[n] * mtx->q_[j];
    best_node = node->prev;
  }
  return nz;
}
Beispiel #13
0
static void
semi_greedy(data *d, int start, int *tour, int *tour_length)
{
    int i, j, k;
    int dim = d->numnodes;
    int current, len, dist;
    int *visited = MALLOC(dim, int);
    /* RCL. */
    struct heapelm *candidates = MALLOC(dim, struct heapelm);
    int rclsize, rclused;
    double total_bias, rprob, racc, rpick;

    memset(visited, 0, dim * sizeof(int));

    len = 0;
    current = start;
    for (i = 0; i < dim - 1; i++) {
        visited[current] = 1;
        tour[i] = current;

        /* Define RCL size. */
        rclused = 0;
        if (RANDOM_UNIT() < 0.05) rclsize = dim - i - 2;
        else rclsize = RANDOM(((dim - i - 2) / 4) + 1);
        rclsize++;

        DEBUG("RCL size: %d\n", rclsize);

        /* Define RCL. */
        for (j = 0; j < dim; j++) {
            if (!visited[j]) {
                dist = d->dist(d, current, j);
                if (rclused < rclsize) {
                    candidates[rclused].num = j;
                    candidates[rclused].cost = dist;
                    rclused++;

                    if (rclused == rclsize) {
                        heap_build_max(candidates, rclsize);
                    }
                } else if (dist < candidates[0].cost) {
                    heap_replace_root(candidates, rclsize, j, dist);
                }
            }
        }

        DEBUG("RCL used: %d\n", rclused);
        heap_dump(candidates, rclused);

        /* Pick RCL element based on logarithmic bias. */
#define BIAS_LOG(r) (1/log((r)+1))
#define BIAS_LINEAR(r) (1./(r))
#define BIAS_EXP(r) (1/exp(r))
#define BIAS_RANDOM(r) 1
#define BIAS(r) BIAS_LOG(r)
        total_bias = 0;
        for (j = 1; j <= rclused; j++) {
            total_bias += BIAS(j);
        }
        racc = 0;
        rpick = RANDOM_UNIT();
#if DEBUGGING
        for (j = rclused; j >= 1; j--) {
            DEBUG("%f ", BIAS(j) / total_bias);
        }
        DEBUG("\nR: %f\n", rpick);
#endif
        for (j = rclused, k = 1; j >= 0; j--, k++) {
            rprob = BIAS(k) / total_bias;
            if (rprob + racc > rpick) {
                break;
            }
            racc += rprob;
        }
        DEBUG("Picked: j = %d, %d %d\n\n", j,
              candidates[j-1].num, candidates[j-1].cost);


        current = candidates[j - 1].num;
        len += candidates[j - 1].cost;
    }
    tour[i] = current;
    len += d->dist(d, current, start);
    *tour_length = len;

    free(visited);
    free(candidates);

#undef BIAS
#undef BIAS_LOG
}