/src/libvpx/vp9/common/vp9_alloccommon.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (c) 2010 The WebM project authors. All Rights Reserved. |
3 | | * |
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 |
6 | | * tree. An additional intellectual property rights grant can be found |
7 | | * in the file PATENTS. All contributing project authors may |
8 | | * be found in the AUTHORS file in the root of the source tree. |
9 | | */ |
10 | | |
11 | | #include "./vpx_config.h" |
12 | | #include "vpx_mem/vpx_mem.h" |
13 | | |
14 | | #include "vp9/common/vp9_alloccommon.h" |
15 | | #include "vp9/common/vp9_blockd.h" |
16 | | #include "vp9/common/vp9_entropymode.h" |
17 | | #include "vp9/common/vp9_entropymv.h" |
18 | | #include "vp9/common/vp9_onyxc_int.h" |
19 | | |
20 | | void vp9_set_mi_size(int *mi_rows, int *mi_cols, int *mi_stride, int width, |
21 | 57.3k | int height) { |
22 | 57.3k | const int aligned_width = ALIGN_POWER_OF_TWO(width, MI_SIZE_LOG2); |
23 | 57.3k | const int aligned_height = ALIGN_POWER_OF_TWO(height, MI_SIZE_LOG2); |
24 | 57.3k | *mi_cols = aligned_width >> MI_SIZE_LOG2; |
25 | 57.3k | *mi_rows = aligned_height >> MI_SIZE_LOG2; |
26 | 57.3k | *mi_stride = calc_mi_size(*mi_cols); |
27 | 57.3k | } |
28 | | |
29 | | void vp9_set_mb_size(int *mb_rows, int *mb_cols, int *mb_num, int mi_rows, |
30 | 57.3k | int mi_cols) { |
31 | 57.3k | *mb_cols = (mi_cols + 1) >> 1; |
32 | 57.3k | *mb_rows = (mi_rows + 1) >> 1; |
33 | 57.3k | *mb_num = (*mb_rows) * (*mb_cols); |
34 | 57.3k | } |
35 | | |
36 | 54.3k | void vp9_set_mb_mi(VP9_COMMON *cm, int width, int height) { |
37 | 54.3k | vp9_set_mi_size(&cm->mi_rows, &cm->mi_cols, &cm->mi_stride, width, height); |
38 | 54.3k | vp9_set_mb_size(&cm->mb_rows, &cm->mb_cols, &cm->MBs, cm->mi_rows, |
39 | 54.3k | cm->mi_cols); |
40 | 54.3k | } |
41 | | |
42 | 2.98k | static int alloc_seg_map(VP9_COMMON *cm, int seg_map_size) { |
43 | 2.98k | int i; |
44 | | |
45 | 8.94k | for (i = 0; i < NUM_PING_PONG_BUFFERS; ++i) { |
46 | 5.96k | cm->seg_map_array[i] = (uint8_t *)vpx_calloc(seg_map_size, 1); |
47 | 5.96k | if (cm->seg_map_array[i] == NULL) return 1; |
48 | 5.96k | } |
49 | 2.98k | cm->seg_map_alloc_size = seg_map_size; |
50 | | |
51 | | // Init the index. |
52 | 2.98k | cm->seg_map_idx = 0; |
53 | 2.98k | cm->prev_seg_map_idx = 1; |
54 | | |
55 | 2.98k | cm->current_frame_seg_map = cm->seg_map_array[cm->seg_map_idx]; |
56 | 2.98k | cm->last_frame_seg_map = cm->seg_map_array[cm->prev_seg_map_idx]; |
57 | | |
58 | 2.98k | return 0; |
59 | 2.98k | } |
60 | | |
61 | 8.94k | static void free_seg_map(VP9_COMMON *cm) { |
62 | 8.94k | int i; |
63 | | |
64 | 26.8k | for (i = 0; i < NUM_PING_PONG_BUFFERS; ++i) { |
65 | 17.8k | vpx_free(cm->seg_map_array[i]); |
66 | 17.8k | cm->seg_map_array[i] = NULL; |
67 | 17.8k | } |
68 | 8.94k | cm->seg_map_alloc_size = 0; |
69 | | |
70 | 8.94k | cm->current_frame_seg_map = NULL; |
71 | 8.94k | cm->last_frame_seg_map = NULL; |
72 | 8.94k | } |
73 | | |
74 | 5.96k | void vp9_free_ref_frame_buffers(BufferPool *pool) { |
75 | 5.96k | int i; |
76 | | |
77 | 5.96k | if (!pool) return; |
78 | | |
79 | 77.5k | for (i = 0; i < FRAME_BUFFERS; ++i) { |
80 | 71.5k | if (!pool->frame_bufs[i].released && |
81 | 71.5k | pool->frame_bufs[i].raw_frame_buffer.data != NULL) { |
82 | 0 | pool->release_fb_cb(pool->cb_priv, &pool->frame_bufs[i].raw_frame_buffer); |
83 | 0 | pool->frame_bufs[i].ref_count = 0; |
84 | 0 | pool->frame_bufs[i].released = 1; |
85 | 0 | } |
86 | 71.5k | vpx_free(pool->frame_bufs[i].mvs); |
87 | 71.5k | pool->frame_bufs[i].mvs = NULL; |
88 | 71.5k | vpx_free_frame_buffer(&pool->frame_bufs[i].buf); |
89 | 71.5k | } |
90 | 5.96k | } |
91 | | |
92 | 0 | void vp9_free_postproc_buffers(VP9_COMMON *cm) { |
93 | | #if CONFIG_VP9_POSTPROC |
94 | | vpx_free_frame_buffer(&cm->post_proc_buffer); |
95 | | vpx_free_frame_buffer(&cm->post_proc_buffer_int); |
96 | | vpx_free(cm->postproc_state.limits); |
97 | | cm->postproc_state.limits = NULL; |
98 | | vpx_free(cm->postproc_state.generated_noise); |
99 | | cm->postproc_state.generated_noise = NULL; |
100 | | #else |
101 | 0 | (void)cm; |
102 | 0 | #endif |
103 | 0 | } |
104 | | |
105 | 5.96k | void vp9_free_context_buffers(VP9_COMMON *cm) { |
106 | 5.96k | if (cm->free_mi) cm->free_mi(cm); |
107 | 5.96k | free_seg_map(cm); |
108 | 5.96k | vpx_free(cm->above_context); |
109 | 5.96k | cm->above_context = NULL; |
110 | 5.96k | vpx_free(cm->above_seg_context); |
111 | 5.96k | cm->above_seg_context = NULL; |
112 | 5.96k | cm->above_context_alloc_cols = 0; |
113 | 5.96k | vpx_free(cm->lf.lfm); |
114 | 5.96k | cm->lf.lfm = NULL; |
115 | 5.96k | } |
116 | | |
117 | 2.98k | int vp9_alloc_loop_filter(VP9_COMMON *cm) { |
118 | 2.98k | vpx_free(cm->lf.lfm); |
119 | | // Each lfm holds bit masks for all the 8x8 blocks in a 64x64 region. The |
120 | | // stride and rows are rounded up / truncated to a multiple of 8. |
121 | 2.98k | cm->lf.lfm_stride = (cm->mi_cols + (MI_BLOCK_SIZE - 1)) >> 3; |
122 | 2.98k | cm->lf.lfm = (LOOP_FILTER_MASK *)vpx_calloc( |
123 | 2.98k | ((cm->mi_rows + (MI_BLOCK_SIZE - 1)) >> 3) * cm->lf.lfm_stride, |
124 | 2.98k | sizeof(*cm->lf.lfm)); |
125 | 2.98k | if (!cm->lf.lfm) return 1; |
126 | 2.98k | return 0; |
127 | 2.98k | } |
128 | | |
129 | 2.98k | int vp9_alloc_context_buffers(VP9_COMMON *cm, int width, int height) { |
130 | 2.98k | int new_mi_size; |
131 | | |
132 | 2.98k | vp9_set_mb_mi(cm, width, height); |
133 | 2.98k | new_mi_size = cm->mi_stride * calc_mi_size(cm->mi_rows); |
134 | 2.98k | if (cm->mi_alloc_size < new_mi_size) { |
135 | 2.98k | cm->free_mi(cm); |
136 | 2.98k | if (cm->alloc_mi(cm, new_mi_size)) goto fail; |
137 | 2.98k | } |
138 | 2.98k | if (cm->above_context_alloc_cols < cm->mi_cols) { |
139 | 2.98k | vpx_free(cm->above_context); |
140 | 2.98k | cm->above_context = (ENTROPY_CONTEXT *)vpx_calloc( |
141 | 2.98k | 2 * mi_cols_aligned_to_sb(cm->mi_cols) * MAX_MB_PLANE, |
142 | 2.98k | sizeof(*cm->above_context)); |
143 | 2.98k | if (!cm->above_context) goto fail; |
144 | | |
145 | 2.98k | vpx_free(cm->above_seg_context); |
146 | 2.98k | cm->above_seg_context = (PARTITION_CONTEXT *)vpx_calloc( |
147 | 2.98k | mi_cols_aligned_to_sb(cm->mi_cols), sizeof(*cm->above_seg_context)); |
148 | 2.98k | if (!cm->above_seg_context) goto fail; |
149 | 2.98k | cm->above_context_alloc_cols = cm->mi_cols; |
150 | 2.98k | } |
151 | | |
152 | 2.98k | if (cm->seg_map_alloc_size < cm->mi_rows * cm->mi_cols) { |
153 | | // Create the segmentation map structure and set to 0. |
154 | 2.98k | free_seg_map(cm); |
155 | 2.98k | if (alloc_seg_map(cm, cm->mi_rows * cm->mi_cols)) goto fail; |
156 | 2.98k | } |
157 | | |
158 | 2.98k | if (vp9_alloc_loop_filter(cm)) goto fail; |
159 | | |
160 | 2.98k | return 0; |
161 | | |
162 | 0 | fail: |
163 | | // clear the mi_* values to force a realloc on resync |
164 | 0 | vp9_set_mb_mi(cm, 0, 0); |
165 | 0 | vp9_free_context_buffers(cm); |
166 | 0 | return 1; |
167 | 2.98k | } |
168 | | |
169 | 2.98k | void vp9_remove_common(VP9_COMMON *cm) { |
170 | | #if CONFIG_VP9_POSTPROC |
171 | | vp9_free_postproc_buffers(cm); |
172 | | #endif |
173 | 2.98k | vp9_free_context_buffers(cm); |
174 | | |
175 | 2.98k | vpx_free(cm->fc); |
176 | 2.98k | cm->fc = NULL; |
177 | 2.98k | vpx_free(cm->frame_contexts); |
178 | 2.98k | cm->frame_contexts = NULL; |
179 | 2.98k | } |
180 | | |
181 | 25.6k | void vp9_init_context_buffers(VP9_COMMON *cm) { |
182 | 25.6k | cm->setup_mi(cm); |
183 | 25.6k | if (cm->last_frame_seg_map) |
184 | 25.6k | memset(cm->last_frame_seg_map, 0, cm->mi_rows * cm->mi_cols); |
185 | 25.6k | } |
186 | | |
187 | 0 | void vp9_swap_current_and_last_seg_map(VP9_COMMON *cm) { |
188 | | // Swap indices. |
189 | 0 | const int tmp = cm->seg_map_idx; |
190 | 0 | cm->seg_map_idx = cm->prev_seg_map_idx; |
191 | 0 | cm->prev_seg_map_idx = tmp; |
192 | |
|
193 | 0 | cm->current_frame_seg_map = cm->seg_map_array[cm->seg_map_idx]; |
194 | 0 | cm->last_frame_seg_map = cm->seg_map_array[cm->prev_seg_map_idx]; |
195 | 0 | } |