| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2014 The WebM project authors. All Rights Reserved. | 2 * Copyright (c) 2014 The WebM project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| 11 | |
| 12 #include "vp9/encoder/vp9_context_tree.h" | 11 #include "vp9/encoder/vp9_context_tree.h" |
| 13 | 12 |
| 14 static const BLOCK_SIZE square[] = { | 13 static const BLOCK_SIZE square[] = { |
| 15 BLOCK_8X8, | 14 BLOCK_8X8, |
| 16 BLOCK_16X16, | 15 BLOCK_16X16, |
| 17 BLOCK_32X32, | 16 BLOCK_32X32, |
| 18 BLOCK_64X64, | 17 BLOCK_64X64, |
| 19 }; | 18 }; |
| 20 | 19 |
| 21 static void alloc_mode_context(VP9_COMMON *cm, int num_4x4_blk, | 20 static void alloc_mode_context(VP9_COMMON *cm, int num_4x4_blk, |
| 22 PICK_MODE_CONTEXT *ctx) { | 21 PICK_MODE_CONTEXT *ctx) { |
| 23 const int num_blk = (num_4x4_blk < 4 ? 4 : num_4x4_blk); | 22 const int num_blk = (num_4x4_blk < 4 ? 4 : num_4x4_blk); |
| 24 const int num_pix = num_blk << 4; | 23 const int num_pix = num_blk << 4; |
| 25 int i, k; | 24 int i, k; |
| 26 ctx->num_4x4_blk = num_blk; | 25 ctx->num_4x4_blk = num_blk; |
| 27 | 26 |
| 28 CHECK_MEM_ERROR(cm, ctx->zcoeff_blk, | 27 CHECK_MEM_ERROR(cm, ctx->zcoeff_blk, |
| (...skipping 26 matching lines...) Expand all Loading... |
| 55 ctx->coeff[i][k] = 0; | 54 ctx->coeff[i][k] = 0; |
| 56 vpx_free(ctx->qcoeff[i][k]); | 55 vpx_free(ctx->qcoeff[i][k]); |
| 57 ctx->qcoeff[i][k] = 0; | 56 ctx->qcoeff[i][k] = 0; |
| 58 vpx_free(ctx->dqcoeff[i][k]); | 57 vpx_free(ctx->dqcoeff[i][k]); |
| 59 ctx->dqcoeff[i][k] = 0; | 58 ctx->dqcoeff[i][k] = 0; |
| 60 vpx_free(ctx->eobs[i][k]); | 59 vpx_free(ctx->eobs[i][k]); |
| 61 ctx->eobs[i][k] = 0; | 60 ctx->eobs[i][k] = 0; |
| 62 } | 61 } |
| 63 } | 62 } |
| 64 } | 63 } |
| 65 static void free_tree_contexts(PC_TREE *this_pc) { | 64 |
| 66 free_mode_context(&this_pc->none); | 65 static void alloc_tree_contexts(VP9_COMMON *cm, PC_TREE *tree, |
| 67 free_mode_context(&this_pc->horizontal[0]); | |
| 68 free_mode_context(&this_pc->horizontal[1]); | |
| 69 free_mode_context(&this_pc->vertical[0]); | |
| 70 free_mode_context(&this_pc->vertical[1]); | |
| 71 } | |
| 72 static void alloc_tree_contexts(VP9_COMMON *cm, PC_TREE *this_pc, | |
| 73 int num_4x4_blk) { | 66 int num_4x4_blk) { |
| 74 alloc_mode_context(cm, num_4x4_blk, &this_pc->none); | 67 alloc_mode_context(cm, num_4x4_blk, &tree->none); |
| 75 alloc_mode_context(cm, num_4x4_blk/2, &this_pc->horizontal[0]); | 68 alloc_mode_context(cm, num_4x4_blk/2, &tree->horizontal[0]); |
| 76 alloc_mode_context(cm, num_4x4_blk/2, &this_pc->vertical[0]); | 69 alloc_mode_context(cm, num_4x4_blk/2, &tree->vertical[0]); |
| 77 | 70 |
| 78 /* TODO(Jbb): for 4x8 and 8x4 these allocated values are not used. | 71 /* TODO(Jbb): for 4x8 and 8x4 these allocated values are not used. |
| 79 * Figure out a better way to do this. */ | 72 * Figure out a better way to do this. */ |
| 80 alloc_mode_context(cm, num_4x4_blk/2, &this_pc->horizontal[1]); | 73 alloc_mode_context(cm, num_4x4_blk/2, &tree->horizontal[1]); |
| 81 alloc_mode_context(cm, num_4x4_blk/2, &this_pc->vertical[1]); | 74 alloc_mode_context(cm, num_4x4_blk/2, &tree->vertical[1]); |
| 75 } |
| 76 |
| 77 static void free_tree_contexts(PC_TREE *tree) { |
| 78 free_mode_context(&tree->none); |
| 79 free_mode_context(&tree->horizontal[0]); |
| 80 free_mode_context(&tree->horizontal[1]); |
| 81 free_mode_context(&tree->vertical[0]); |
| 82 free_mode_context(&tree->vertical[1]); |
| 82 } | 83 } |
| 83 | 84 |
| 84 // This function sets up a tree of contexts such that at each square | 85 // This function sets up a tree of contexts such that at each square |
| 85 // partition level. There are contexts for none, horizontal, vertical, and | 86 // partition level. There are contexts for none, horizontal, vertical, and |
| 86 // split. Along with a block_size value and a selected block_size which | 87 // split. Along with a block_size value and a selected block_size which |
| 87 // represents the state of our search. | 88 // represents the state of our search. |
| 88 void vp9_setup_pc_tree(VP9_COMMON *cm, MACROBLOCK *x) { | 89 void vp9_setup_pc_tree(VP9_COMMON *cm, MACROBLOCK *x) { |
| 89 int i, j; | 90 int i, j; |
| 90 const int leaf_nodes = 64; | 91 const int leaf_nodes = 64; |
| 91 const int tree_nodes = 64 + 16 + 4 + 1; | 92 const int tree_nodes = 64 + 16 + 4 + 1; |
| 92 int pc_tree_index = 0; | 93 int pc_tree_index = 0; |
| 93 PC_TREE *this_pc; | 94 PC_TREE *this_pc; |
| 94 PICK_MODE_CONTEXT *this_leaf; | 95 PICK_MODE_CONTEXT *this_leaf; |
| 95 int square_index = 1; | 96 int square_index = 1; |
| 96 int nodes; | 97 int nodes; |
| 97 | 98 |
| 98 vpx_free(x->leaf_tree); | 99 vpx_free(x->leaf_tree); |
| 99 CHECK_MEM_ERROR(cm, x->leaf_tree, vpx_calloc(leaf_nodes, | 100 CHECK_MEM_ERROR(cm, x->leaf_tree, vpx_calloc(leaf_nodes, |
| 100 sizeof(PICK_MODE_CONTEXT))); | 101 sizeof(*x->leaf_tree))); |
| 101 vpx_free(x->pc_tree); | 102 vpx_free(x->pc_tree); |
| 102 CHECK_MEM_ERROR(cm, x->pc_tree, vpx_calloc(tree_nodes, sizeof(PC_TREE))); | 103 CHECK_MEM_ERROR(cm, x->pc_tree, vpx_calloc(tree_nodes, sizeof(*x->pc_tree))); |
| 103 | 104 |
| 104 this_pc = &x->pc_tree[0]; | 105 this_pc = &x->pc_tree[0]; |
| 105 this_leaf = &x->leaf_tree[0]; | 106 this_leaf = &x->leaf_tree[0]; |
| 106 | 107 |
| 107 // 4x4 blocks smaller than 8x8 but in the same 8x8 block share the same | 108 // 4x4 blocks smaller than 8x8 but in the same 8x8 block share the same |
| 108 // context so we only need to allocate 1 for each 8x8 block. | 109 // context so we only need to allocate 1 for each 8x8 block. |
| 109 for (i = 0; i < leaf_nodes; ++i) | 110 for (i = 0; i < leaf_nodes; ++i) |
| 110 alloc_mode_context(cm, 1, &x->leaf_tree[i]); | 111 alloc_mode_context(cm, 1, &x->leaf_tree[i]); |
| 111 | 112 |
| 112 // Sets up all the leaf nodes in the tree. | 113 // Sets up all the leaf nodes in the tree. |
| 113 for (pc_tree_index = 0; pc_tree_index < leaf_nodes; ++pc_tree_index) { | 114 for (pc_tree_index = 0; pc_tree_index < leaf_nodes; ++pc_tree_index) { |
| 114 x->pc_tree[pc_tree_index].block_size = square[0]; | 115 PC_TREE *const tree = &x->pc_tree[pc_tree_index]; |
| 115 alloc_tree_contexts(cm, &x->pc_tree[pc_tree_index], 4); | 116 tree->block_size = square[0]; |
| 116 x->pc_tree[pc_tree_index].leaf_split[0] = this_leaf++; | 117 alloc_tree_contexts(cm, tree, 4); |
| 117 for (j = 1; j < 4; j++) { | 118 tree->leaf_split[0] = this_leaf++; |
| 118 x->pc_tree[pc_tree_index].leaf_split[j] = | 119 for (j = 1; j < 4; j++) |
| 119 x->pc_tree[pc_tree_index].leaf_split[0]; | 120 tree->leaf_split[j] = tree->leaf_split[0]; |
| 120 } | |
| 121 } | 121 } |
| 122 | 122 |
| 123 // Each node has 4 leaf nodes, fill each block_size level of the tree | 123 // Each node has 4 leaf nodes, fill each block_size level of the tree |
| 124 // from leafs to the root. | 124 // from leafs to the root. |
| 125 for (nodes = 16; nodes > 0; nodes >>= 2, ++square_index) { | 125 for (nodes = 16; nodes > 0; nodes >>= 2) { |
| 126 for (i = 0; i < nodes; ++pc_tree_index, ++i) { | 126 for (i = 0; i < nodes; ++i) { |
| 127 alloc_tree_contexts(cm, &x->pc_tree[pc_tree_index], | 127 PC_TREE *const tree = &x->pc_tree[pc_tree_index]; |
| 128 4 << (2 * square_index)); | 128 alloc_tree_contexts(cm, tree, 4 << (2 * square_index)); |
| 129 x->pc_tree[pc_tree_index].block_size = square[square_index]; | 129 tree->block_size = square[square_index]; |
| 130 for (j = 0; j < 4; j++) { | 130 for (j = 0; j < 4; j++) |
| 131 x->pc_tree[pc_tree_index].split[j] = this_pc++; | 131 tree->split[j] = this_pc++; |
| 132 } | 132 ++pc_tree_index; |
| 133 } | 133 } |
| 134 ++square_index; |
| 134 } | 135 } |
| 135 x->pc_root = &x->pc_tree[tree_nodes-1]; | 136 x->pc_root = &x->pc_tree[tree_nodes - 1]; |
| 136 x->pc_root[0].none.best_mode_index = 2; | 137 x->pc_root[0].none.best_mode_index = 2; |
| 137 } | 138 } |
| 138 | 139 |
| 139 void vp9_free_pc_tree(MACROBLOCK *m) { | 140 void vp9_free_pc_tree(MACROBLOCK *x) { |
| 140 const int tree_nodes = 64 + 16 + 4 + 1; | 141 const int tree_nodes = 64 + 16 + 4 + 1; |
| 141 int i; | 142 int i; |
| 142 | 143 |
| 143 // Set up all 4x4 mode contexts | 144 // Set up all 4x4 mode contexts |
| 144 for (i = 0; i < 64; ++i) | 145 for (i = 0; i < 64; ++i) |
| 145 free_mode_context(&m->leaf_tree[i]); | 146 free_mode_context(&x->leaf_tree[i]); |
| 146 | 147 |
| 147 // Sets up all the leaf nodes in the tree. | 148 // Sets up all the leaf nodes in the tree. |
| 148 for (i = 0; i < tree_nodes; i++) { | 149 for (i = 0; i < tree_nodes; ++i) |
| 149 free_tree_contexts(&m->pc_tree[i]); | 150 free_tree_contexts(&x->pc_tree[i]); |
| 150 } | 151 |
| 151 vpx_free(m->pc_tree); | 152 vpx_free(x->pc_tree); |
| 152 m->pc_tree = 0; | 153 x->pc_tree = NULL; |
| 153 vpx_free(m->leaf_tree); | 154 vpx_free(x->leaf_tree); |
| 154 m->leaf_tree = 0; | 155 x->leaf_tree = NULL; |
| 155 } | 156 } |
| OLD | NEW |