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 |