LCOV - code coverage report
Current view: top level - third_party/aom/aom_dsp - prob.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 107 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 9 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2016, Alliance for Open Media. All rights reserved
       3             :  *
       4             :  * This source code is subject to the terms of the BSD 2 Clause License and
       5             :  * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
       6             :  * was not distributed with this source code in the LICENSE file, you can
       7             :  * obtain it at www.aomedia.org/license/software. If the Alliance for Open
       8             :  * Media Patent License 1.0 was not distributed with this source code in the
       9             :  * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
      10             :  */
      11             : 
      12             : #include "./aom_config.h"
      13             : 
      14             : #include <string.h>
      15             : 
      16             : #include "aom_dsp/prob.h"
      17             : 
      18           0 : static unsigned int tree_merge_probs_impl(unsigned int i,
      19             :                                           const aom_tree_index *tree,
      20             :                                           const aom_prob *pre_probs,
      21             :                                           const unsigned int *counts,
      22             :                                           aom_prob *probs) {
      23           0 :   const int l = tree[i];
      24           0 :   const unsigned int left_count =
      25           0 :       (l <= 0) ? counts[-l]
      26           0 :                : tree_merge_probs_impl(l, tree, pre_probs, counts, probs);
      27           0 :   const int r = tree[i + 1];
      28           0 :   const unsigned int right_count =
      29           0 :       (r <= 0) ? counts[-r]
      30           0 :                : tree_merge_probs_impl(r, tree, pre_probs, counts, probs);
      31           0 :   const unsigned int ct[2] = { left_count, right_count };
      32           0 :   probs[i >> 1] = mode_mv_merge_probs(pre_probs[i >> 1], ct);
      33           0 :   return left_count + right_count;
      34             : }
      35             : 
      36           0 : void aom_tree_merge_probs(const aom_tree_index *tree, const aom_prob *pre_probs,
      37             :                           const unsigned int *counts, aom_prob *probs) {
      38           0 :   tree_merge_probs_impl(0, tree, pre_probs, counts, probs);
      39           0 : }
      40             : 
      41             : typedef struct tree_node tree_node;
      42             : 
      43             : struct tree_node {
      44             :   aom_tree_index index;
      45             :   uint8_t probs[16];
      46             :   uint8_t prob;
      47             :   int path;
      48             :   int len;
      49             :   int l;
      50             :   int r;
      51             :   aom_cdf_prob pdf;
      52             : };
      53             : 
      54             : /* Compute the probability of this node in Q23 */
      55           0 : static uint32_t tree_node_prob(tree_node n, int i) {
      56             :   uint32_t prob;
      57             :   /* 1.0 in Q23 */
      58           0 :   prob = 16777216;
      59           0 :   for (; i < n.len; i++) {
      60           0 :     prob = prob * n.probs[i] >> 8;
      61             :   }
      62           0 :   return prob;
      63             : }
      64             : 
      65           0 : static int tree_node_cmp(tree_node a, tree_node b) {
      66             :   int i;
      67             :   uint32_t pa;
      68             :   uint32_t pb;
      69           0 :   for (i = 0; i < AOMMIN(a.len, b.len) && a.probs[i] == b.probs[i]; i++) {
      70             :   }
      71           0 :   pa = tree_node_prob(a, i);
      72           0 :   pb = tree_node_prob(b, i);
      73           0 :   return pa > pb ? 1 : pa < pb ? -1 : 0;
      74             : }
      75             : 
      76             : /* Given a Q15 probability for symbol subtree rooted at tree[n], this function
      77             :     computes the probability of each symbol (defined as a node that has no
      78             :     children). */
      79           0 : static aom_cdf_prob tree_node_compute_probs(tree_node *tree, int n,
      80             :                                             aom_cdf_prob pdf) {
      81           0 :   if (tree[n].l == 0) {
      82             :     /* This prevents probability computations in Q15 that underflow from
      83             :         producing a symbol that has zero probability. */
      84           0 :     if (pdf == 0) pdf = 1;
      85           0 :     tree[n].pdf = pdf;
      86           0 :     return pdf;
      87             :   } else {
      88             :     /* We process the smaller probability first,  */
      89           0 :     if (tree[n].prob < 128) {
      90             :       aom_cdf_prob lp;
      91             :       aom_cdf_prob rp;
      92           0 :       lp = (((uint32_t)pdf) * tree[n].prob + 128) >> 8;
      93           0 :       lp = tree_node_compute_probs(tree, tree[n].l, lp);
      94           0 :       rp = tree_node_compute_probs(tree, tree[n].r, lp > pdf ? 0 : pdf - lp);
      95           0 :       return lp + rp;
      96             :     } else {
      97             :       aom_cdf_prob rp;
      98             :       aom_cdf_prob lp;
      99           0 :       rp = (((uint32_t)pdf) * (256 - tree[n].prob) + 128) >> 8;
     100           0 :       rp = tree_node_compute_probs(tree, tree[n].r, rp);
     101           0 :       lp = tree_node_compute_probs(tree, tree[n].l, rp > pdf ? 0 : pdf - rp);
     102           0 :       return lp + rp;
     103             :     }
     104             :   }
     105             : }
     106             : 
     107           0 : static int tree_node_extract(tree_node *tree, int n, int symb,
     108             :                              aom_cdf_prob *pdf, aom_tree_index *index,
     109             :                              int *path, int *len) {
     110           0 :   if (tree[n].l == 0) {
     111           0 :     pdf[symb] = tree[n].pdf;
     112           0 :     if (index != NULL) index[symb] = tree[n].index;
     113           0 :     if (path != NULL) path[symb] = tree[n].path;
     114           0 :     if (len != NULL) len[symb] = tree[n].len;
     115           0 :     return symb + 1;
     116             :   } else {
     117           0 :     symb = tree_node_extract(tree, tree[n].l, symb, pdf, index, path, len);
     118           0 :     return tree_node_extract(tree, tree[n].r, symb, pdf, index, path, len);
     119             :   }
     120             : }
     121             : 
     122           0 : int tree_to_cdf(const aom_tree_index *tree, const aom_prob *probs,
     123             :                 aom_tree_index root, aom_cdf_prob *cdf, aom_tree_index *index,
     124             :                 int *path, int *len) {
     125             :   tree_node symb[2 * 16 - 1];
     126             :   int nodes;
     127             :   int next[16];
     128             :   int size;
     129             :   int nsymbs;
     130             :   int i;
     131             :   /* Create the root node with probability 1 in Q15. */
     132           0 :   symb[0].index = root;
     133           0 :   symb[0].path = 0;
     134           0 :   symb[0].len = 0;
     135           0 :   symb[0].l = symb[0].r = 0;
     136           0 :   nodes = 1;
     137           0 :   next[0] = 0;
     138           0 :   size = 1;
     139           0 :   nsymbs = 1;
     140           0 :   while (size > 0 && nsymbs < 16) {
     141             :     int m;
     142             :     tree_node n;
     143             :     aom_tree_index j;
     144             :     uint8_t prob;
     145           0 :     m = 0;
     146             :     /* Find the internal node with the largest probability. */
     147           0 :     for (i = 1; i < size; i++) {
     148           0 :       if (tree_node_cmp(symb[next[i]], symb[next[m]]) > 0) m = i;
     149             :     }
     150           0 :     i = next[m];
     151           0 :     memmove(&next[m], &next[m + 1], sizeof(*next) * (size - (m + 1)));
     152           0 :     size--;
     153             :     /* Split this symbol into two symbols */
     154           0 :     n = symb[i];
     155           0 :     j = n.index;
     156           0 :     prob = probs[j >> 1];
     157             :     /* Left */
     158           0 :     n.index = tree[j];
     159           0 :     n.path <<= 1;
     160           0 :     n.len++;
     161           0 :     n.probs[n.len - 1] = prob;
     162           0 :     symb[nodes] = n;
     163           0 :     if (n.index > 0) {
     164           0 :       next[size++] = nodes;
     165             :     }
     166             :     /* Right */
     167           0 :     n.index = tree[j + 1];
     168           0 :     n.path += 1;
     169           0 :     n.probs[n.len - 1] = 256 - prob;
     170           0 :     symb[nodes + 1] = n;
     171           0 :     if (n.index > 0) {
     172           0 :       next[size++] = nodes + 1;
     173             :     }
     174           0 :     symb[i].prob = prob;
     175           0 :     symb[i].l = nodes;
     176           0 :     symb[i].r = nodes + 1;
     177           0 :     nodes += 2;
     178           0 :     nsymbs++;
     179             :   }
     180             :   /* Compute the probabilities of each symbol in Q15 */
     181           0 :   tree_node_compute_probs(symb, 0, CDF_PROB_TOP);
     182             :   /* Extract the cdf, index, path and length */
     183           0 :   tree_node_extract(symb, 0, 0, cdf, index, path, len);
     184             :   /* Convert to CDF */
     185           0 :   cdf[0] = AOM_ICDF(cdf[0]);
     186           0 :   for (i = 1; i < nsymbs; i++) {
     187           0 :     cdf[i] = AOM_ICDF(AOM_ICDF(cdf[i - 1]) + cdf[i]);
     188             :   }
     189             : // Store symbol count at the end of the CDF
     190             : #if CONFIG_EC_ADAPT
     191           0 :   cdf[nsymbs] = 0;
     192             : #endif
     193           0 :   return nsymbs;
     194             : }
     195             : 
     196             : /* This code assumes that tree contains as unique leaf nodes the integer values
     197             :     0 to len - 1 and produces the forward and inverse mapping tables in ind[]
     198             :     and inv[] respectively. */
     199           0 : static void tree_to_index(int *stack_index, int *ind, int *inv,
     200             :                           const aom_tree_index *tree, int value, int index) {
     201           0 :   value *= 2;
     202             : 
     203             :   do {
     204           0 :     const aom_tree_index content = tree[index];
     205           0 :     ++index;
     206           0 :     if (content <= 0) {
     207           0 :       inv[*stack_index] = -content;
     208           0 :       ind[-content] = *stack_index;
     209           0 :       ++(*stack_index);
     210             :     } else {
     211           0 :       tree_to_index(stack_index, ind, inv, tree, value, content);
     212             :     }
     213           0 :   } while (++value & 1);
     214           0 : }
     215             : 
     216           0 : void av1_indices_from_tree(int *ind, int *inv, const aom_tree_index *tree) {
     217           0 :   int stack_index = 0;
     218           0 :   tree_to_index(&stack_index, ind, inv, tree, 0, 0);
     219           0 : }

Generated by: LCOV version 1.13