LCOV - code coverage report
Current view: top level - third_party/aom/av1/encoder - context_tree.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 101 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 6 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 "av1/encoder/context_tree.h"
      13             : #include "av1/encoder/encoder.h"
      14             : 
      15             : static const BLOCK_SIZE square[MAX_SB_SIZE_LOG2 - 1] = {
      16             : #if CONFIG_CB4X4
      17             :   BLOCK_4X4,
      18             : #endif
      19             :   BLOCK_8X8,     BLOCK_16X16, BLOCK_32X32, BLOCK_64X64,
      20             : #if CONFIG_EXT_PARTITION
      21             :   BLOCK_128X128,
      22             : #endif  // CONFIG_EXT_PARTITION
      23             : };
      24             : 
      25           0 : static void alloc_mode_context(AV1_COMMON *cm, int num_4x4_blk,
      26             : #if CONFIG_EXT_PARTITION_TYPES
      27             :                                PARTITION_TYPE partition,
      28             : #endif
      29             :                                PICK_MODE_CONTEXT *ctx) {
      30           0 :   const int num_blk = (num_4x4_blk < 4 ? 4 : num_4x4_blk);
      31           0 :   const int num_pix = num_blk * tx_size_2d[0];
      32             :   int i;
      33             : #if CONFIG_CB4X4 && CONFIG_VAR_TX
      34           0 :   ctx->num_4x4_blk = num_blk / 4;
      35             : #else
      36             :   ctx->num_4x4_blk = num_blk;
      37             : #endif
      38             : 
      39             : #if CONFIG_EXT_PARTITION_TYPES
      40             :   ctx->partition = partition;
      41             : #endif
      42             : 
      43           0 :   for (i = 0; i < MAX_MB_PLANE; ++i) {
      44             : #if CONFIG_VAR_TX
      45           0 :     CHECK_MEM_ERROR(cm, ctx->blk_skip[i], aom_calloc(num_blk, sizeof(uint8_t)));
      46             : #endif
      47           0 :     CHECK_MEM_ERROR(cm, ctx->coeff[i],
      48             :                     aom_memalign(32, num_pix * sizeof(*ctx->coeff[i])));
      49           0 :     CHECK_MEM_ERROR(cm, ctx->qcoeff[i],
      50             :                     aom_memalign(32, num_pix * sizeof(*ctx->qcoeff[i])));
      51           0 :     CHECK_MEM_ERROR(cm, ctx->dqcoeff[i],
      52             :                     aom_memalign(32, num_pix * sizeof(*ctx->dqcoeff[i])));
      53           0 :     CHECK_MEM_ERROR(cm, ctx->eobs[i],
      54             :                     aom_memalign(32, num_blk * sizeof(*ctx->eobs[i])));
      55             : #if CONFIG_LV_MAP
      56             :     CHECK_MEM_ERROR(
      57             :         cm, ctx->txb_entropy_ctx[i],
      58             :         aom_memalign(32, num_blk * sizeof(*ctx->txb_entropy_ctx[i])));
      59             : #endif
      60             : 
      61             : #if CONFIG_PVQ
      62             :     CHECK_MEM_ERROR(cm, ctx->pvq_ref_coeff[i],
      63             :                     aom_memalign(32, num_pix * sizeof(*ctx->pvq_ref_coeff[i])));
      64             : #endif
      65             :   }
      66             : 
      67             : #if CONFIG_PALETTE
      68           0 :   if (cm->allow_screen_content_tools) {
      69           0 :     for (i = 0; i < 2; ++i) {
      70           0 :       CHECK_MEM_ERROR(
      71             :           cm, ctx->color_index_map[i],
      72             :           aom_memalign(32, num_pix * sizeof(*ctx->color_index_map[i])));
      73             :     }
      74             :   }
      75             : #endif  // CONFIG_PALETTE
      76           0 : }
      77             : 
      78           0 : static void free_mode_context(PICK_MODE_CONTEXT *ctx) {
      79             :   int i;
      80           0 :   for (i = 0; i < MAX_MB_PLANE; ++i) {
      81             : #if CONFIG_VAR_TX
      82           0 :     aom_free(ctx->blk_skip[i]);
      83           0 :     ctx->blk_skip[i] = 0;
      84             : #endif
      85           0 :     aom_free(ctx->coeff[i]);
      86           0 :     ctx->coeff[i] = 0;
      87           0 :     aom_free(ctx->qcoeff[i]);
      88           0 :     ctx->qcoeff[i] = 0;
      89           0 :     aom_free(ctx->dqcoeff[i]);
      90           0 :     ctx->dqcoeff[i] = 0;
      91             : #if CONFIG_PVQ
      92             :     aom_free(ctx->pvq_ref_coeff[i]);
      93             :     ctx->pvq_ref_coeff[i] = 0;
      94             : #endif
      95           0 :     aom_free(ctx->eobs[i]);
      96           0 :     ctx->eobs[i] = 0;
      97             : #if CONFIG_LV_MAP
      98             :     aom_free(ctx->txb_entropy_ctx[i]);
      99             :     ctx->txb_entropy_ctx[i] = 0;
     100             : #endif
     101             :   }
     102             : 
     103             : #if CONFIG_PALETTE
     104           0 :   for (i = 0; i < 2; ++i) {
     105           0 :     aom_free(ctx->color_index_map[i]);
     106           0 :     ctx->color_index_map[i] = 0;
     107             :   }
     108             : #endif  // CONFIG_PALETTE
     109           0 : }
     110             : 
     111           0 : static void alloc_tree_contexts(AV1_COMMON *cm, PC_TREE *tree,
     112             :                                 int num_4x4_blk) {
     113             : #if CONFIG_EXT_PARTITION_TYPES
     114             :   alloc_mode_context(cm, num_4x4_blk, PARTITION_NONE, &tree->none);
     115             :   alloc_mode_context(cm, num_4x4_blk / 2, PARTITION_HORZ, &tree->horizontal[0]);
     116             :   alloc_mode_context(cm, num_4x4_blk / 2, PARTITION_VERT, &tree->vertical[0]);
     117             :   alloc_mode_context(cm, num_4x4_blk / 2, PARTITION_VERT, &tree->horizontal[1]);
     118             :   alloc_mode_context(cm, num_4x4_blk / 2, PARTITION_VERT, &tree->vertical[1]);
     119             : 
     120             :   alloc_mode_context(cm, num_4x4_blk / 4, PARTITION_HORZ_A,
     121             :                      &tree->horizontala[0]);
     122             :   alloc_mode_context(cm, num_4x4_blk / 4, PARTITION_HORZ_A,
     123             :                      &tree->horizontala[1]);
     124             :   alloc_mode_context(cm, num_4x4_blk / 2, PARTITION_HORZ_A,
     125             :                      &tree->horizontala[2]);
     126             :   alloc_mode_context(cm, num_4x4_blk / 2, PARTITION_HORZ_B,
     127             :                      &tree->horizontalb[0]);
     128             :   alloc_mode_context(cm, num_4x4_blk / 4, PARTITION_HORZ_B,
     129             :                      &tree->horizontalb[1]);
     130             :   alloc_mode_context(cm, num_4x4_blk / 4, PARTITION_HORZ_B,
     131             :                      &tree->horizontalb[2]);
     132             :   alloc_mode_context(cm, num_4x4_blk / 4, PARTITION_VERT_A,
     133             :                      &tree->verticala[0]);
     134             :   alloc_mode_context(cm, num_4x4_blk / 4, PARTITION_VERT_A,
     135             :                      &tree->verticala[1]);
     136             :   alloc_mode_context(cm, num_4x4_blk / 2, PARTITION_VERT_A,
     137             :                      &tree->verticala[2]);
     138             :   alloc_mode_context(cm, num_4x4_blk / 2, PARTITION_VERT_B,
     139             :                      &tree->verticalb[0]);
     140             :   alloc_mode_context(cm, num_4x4_blk / 4, PARTITION_VERT_B,
     141             :                      &tree->verticalb[1]);
     142             :   alloc_mode_context(cm, num_4x4_blk / 4, PARTITION_VERT_B,
     143             :                      &tree->verticalb[2]);
     144             : #ifdef CONFIG_SUPERTX
     145             :   alloc_mode_context(cm, num_4x4_blk, PARTITION_HORZ,
     146             :                      &tree->horizontal_supertx);
     147             :   alloc_mode_context(cm, num_4x4_blk, PARTITION_VERT, &tree->vertical_supertx);
     148             :   alloc_mode_context(cm, num_4x4_blk, PARTITION_SPLIT, &tree->split_supertx);
     149             :   alloc_mode_context(cm, num_4x4_blk, PARTITION_HORZ_A,
     150             :                      &tree->horizontala_supertx);
     151             :   alloc_mode_context(cm, num_4x4_blk, PARTITION_HORZ_B,
     152             :                      &tree->horizontalb_supertx);
     153             :   alloc_mode_context(cm, num_4x4_blk, PARTITION_VERT_A,
     154             :                      &tree->verticala_supertx);
     155             :   alloc_mode_context(cm, num_4x4_blk, PARTITION_VERT_B,
     156             :                      &tree->verticalb_supertx);
     157             : #endif  // CONFIG_SUPERTX
     158             : #else
     159           0 :   alloc_mode_context(cm, num_4x4_blk, &tree->none);
     160           0 :   alloc_mode_context(cm, num_4x4_blk / 2, &tree->horizontal[0]);
     161           0 :   alloc_mode_context(cm, num_4x4_blk / 2, &tree->vertical[0]);
     162             : #ifdef CONFIG_SUPERTX
     163           0 :   alloc_mode_context(cm, num_4x4_blk, &tree->horizontal_supertx);
     164           0 :   alloc_mode_context(cm, num_4x4_blk, &tree->vertical_supertx);
     165           0 :   alloc_mode_context(cm, num_4x4_blk, &tree->split_supertx);
     166             : #endif
     167             : 
     168           0 :   if (num_4x4_blk > 4) {
     169           0 :     alloc_mode_context(cm, num_4x4_blk / 2, &tree->horizontal[1]);
     170           0 :     alloc_mode_context(cm, num_4x4_blk / 2, &tree->vertical[1]);
     171             :   } else {
     172           0 :     memset(&tree->horizontal[1], 0, sizeof(tree->horizontal[1]));
     173           0 :     memset(&tree->vertical[1], 0, sizeof(tree->vertical[1]));
     174             :   }
     175             : #endif  // CONFIG_EXT_PARTITION_TYPES
     176           0 : }
     177             : 
     178           0 : static void free_tree_contexts(PC_TREE *tree) {
     179             : #if CONFIG_EXT_PARTITION_TYPES
     180             :   int i;
     181             :   for (i = 0; i < 3; i++) {
     182             :     free_mode_context(&tree->horizontala[i]);
     183             :     free_mode_context(&tree->horizontalb[i]);
     184             :     free_mode_context(&tree->verticala[i]);
     185             :     free_mode_context(&tree->verticalb[i]);
     186             :   }
     187             : #endif  // CONFIG_EXT_PARTITION_TYPES
     188           0 :   free_mode_context(&tree->none);
     189           0 :   free_mode_context(&tree->horizontal[0]);
     190           0 :   free_mode_context(&tree->horizontal[1]);
     191           0 :   free_mode_context(&tree->vertical[0]);
     192           0 :   free_mode_context(&tree->vertical[1]);
     193             : #ifdef CONFIG_SUPERTX
     194           0 :   free_mode_context(&tree->horizontal_supertx);
     195           0 :   free_mode_context(&tree->vertical_supertx);
     196           0 :   free_mode_context(&tree->split_supertx);
     197             : #if CONFIG_EXT_PARTITION_TYPES
     198             :   free_mode_context(&tree->horizontala_supertx);
     199             :   free_mode_context(&tree->horizontalb_supertx);
     200             :   free_mode_context(&tree->verticala_supertx);
     201             :   free_mode_context(&tree->verticalb_supertx);
     202             : #endif  // CONFIG_EXT_PARTITION_TYPES
     203             : #endif  // CONFIG_SUPERTX
     204           0 : }
     205             : 
     206             : // This function sets up a tree of contexts such that at each square
     207             : // partition level. There are contexts for none, horizontal, vertical, and
     208             : // split.  Along with a block_size value and a selected block_size which
     209             : // represents the state of our search.
     210           0 : void av1_setup_pc_tree(AV1_COMMON *cm, ThreadData *td) {
     211             :   int i, j;
     212             : // TODO(jingning): The pc_tree allocation is redundant. We can take out all
     213             : // the leaf nodes after cb4x4 mode is enabled.
     214             : #if CONFIG_CB4X4
     215             : #if CONFIG_EXT_PARTITION
     216             :   const int tree_nodes_inc = 1024;
     217             : #else
     218           0 :   const int tree_nodes_inc = 256;
     219             : #endif  // CONFIG_EXT_PARTITION
     220           0 :   const int leaf_factor = 4;
     221             : #else
     222             :   const int tree_nodes_inc = 0;
     223             :   const int leaf_factor = 1;
     224             : #endif
     225             : #if CONFIG_EXT_PARTITION
     226             :   const int leaf_nodes = 256 * leaf_factor;
     227             :   const int tree_nodes = tree_nodes_inc + 256 + 64 + 16 + 4 + 1;
     228             : #else
     229           0 :   const int leaf_nodes = 64 * leaf_factor;
     230           0 :   const int tree_nodes = tree_nodes_inc + 64 + 16 + 4 + 1;
     231             : #endif  // CONFIG_EXT_PARTITION
     232           0 :   int pc_tree_index = 0;
     233             :   PC_TREE *this_pc;
     234             :   PICK_MODE_CONTEXT *this_leaf;
     235           0 :   int square_index = 1;
     236             :   int nodes;
     237             : 
     238           0 :   aom_free(td->leaf_tree);
     239           0 :   CHECK_MEM_ERROR(cm, td->leaf_tree,
     240             :                   aom_calloc(leaf_nodes, sizeof(*td->leaf_tree)));
     241           0 :   aom_free(td->pc_tree);
     242           0 :   CHECK_MEM_ERROR(cm, td->pc_tree,
     243             :                   aom_calloc(tree_nodes, sizeof(*td->pc_tree)));
     244             : 
     245           0 :   this_pc = &td->pc_tree[0];
     246           0 :   this_leaf = &td->leaf_tree[0];
     247             : 
     248             :   // 4x4 blocks smaller than 8x8 but in the same 8x8 block share the same
     249             :   // context so we only need to allocate 1 for each 8x8 block.
     250           0 :   for (i = 0; i < leaf_nodes; ++i) {
     251             : #if CONFIG_EXT_PARTITION_TYPES
     252             :     alloc_mode_context(cm, 4, PARTITION_NONE, &td->leaf_tree[i]);
     253             : #else
     254           0 :     alloc_mode_context(cm, 16, &td->leaf_tree[i]);
     255             : #endif
     256             :   }
     257             : 
     258             :   // Sets up all the leaf nodes in the tree.
     259           0 :   for (pc_tree_index = 0; pc_tree_index < leaf_nodes; ++pc_tree_index) {
     260           0 :     PC_TREE *const tree = &td->pc_tree[pc_tree_index];
     261           0 :     tree->block_size = square[0];
     262             : #if CONFIG_CB4X4
     263           0 :     alloc_tree_contexts(cm, tree, 16);
     264             : #else
     265             :     alloc_tree_contexts(cm, tree, 4);
     266             : #endif
     267           0 :     tree->leaf_split[0] = this_leaf++;
     268           0 :     for (j = 1; j < 4; j++) tree->leaf_split[j] = tree->leaf_split[0];
     269             :   }
     270             : 
     271             :   // Each node has 4 leaf nodes, fill each block_size level of the tree
     272             :   // from leafs to the root.
     273           0 :   for (nodes = leaf_nodes >> 2; nodes > 0; nodes >>= 2) {
     274           0 :     for (i = 0; i < nodes; ++i) {
     275           0 :       PC_TREE *const tree = &td->pc_tree[pc_tree_index];
     276             : #if CONFIG_CB4X4
     277           0 :       alloc_tree_contexts(cm, tree, 16 << (2 * square_index));
     278             : #else
     279             :       alloc_tree_contexts(cm, tree, 4 << (2 * square_index));
     280             : #endif
     281           0 :       tree->block_size = square[square_index];
     282           0 :       for (j = 0; j < 4; j++) tree->split[j] = this_pc++;
     283           0 :       ++pc_tree_index;
     284             :     }
     285           0 :     ++square_index;
     286             :   }
     287             : 
     288             :   // Set up the root node for the largest superblock size
     289           0 :   i = MAX_MIB_SIZE_LOG2 - MIN_MIB_SIZE_LOG2;
     290           0 :   td->pc_root[i] = &td->pc_tree[tree_nodes - 1];
     291           0 :   td->pc_root[i]->none.best_mode_index = 2;
     292             :   // Set up the root nodes for the rest of the possible superblock sizes
     293           0 :   while (--i >= 0) {
     294           0 :     td->pc_root[i] = td->pc_root[i + 1]->split[0];
     295           0 :     td->pc_root[i]->none.best_mode_index = 2;
     296             :   }
     297           0 : }
     298             : 
     299           0 : void av1_free_pc_tree(ThreadData *td) {
     300             : #if CONFIG_CB4X4
     301             : #if CONFIG_EXT_PARTITION
     302             :   const int tree_nodes_inc = 1024;
     303             : #else
     304           0 :   const int tree_nodes_inc = 256;
     305             : #endif  // CONFIG_EXT_PARTITION
     306           0 :   const int leaf_factor = 4;
     307             : #else
     308             :   const int tree_nodes_inc = 0;
     309             :   const int leaf_factor = 1;
     310             : #endif
     311             : 
     312             : #if CONFIG_EXT_PARTITION
     313             :   const int leaf_nodes = 256 * leaf_factor;
     314             :   const int tree_nodes = tree_nodes_inc + 256 + 64 + 16 + 4 + 1;
     315             : #else
     316           0 :   const int leaf_nodes = 64 * leaf_factor;
     317           0 :   const int tree_nodes = tree_nodes_inc + 64 + 16 + 4 + 1;
     318             : #endif  // CONFIG_EXT_PARTITION
     319             :   int i;
     320             : 
     321             :   // Set up all 4x4 mode contexts
     322           0 :   for (i = 0; i < leaf_nodes; ++i) free_mode_context(&td->leaf_tree[i]);
     323             : 
     324             :   // Sets up all the leaf nodes in the tree.
     325           0 :   for (i = 0; i < tree_nodes; ++i) free_tree_contexts(&td->pc_tree[i]);
     326             : 
     327           0 :   aom_free(td->pc_tree);
     328           0 :   td->pc_tree = NULL;
     329           0 :   aom_free(td->leaf_tree);
     330           0 :   td->leaf_tree = NULL;
     331           0 : }

Generated by: LCOV version 1.13