/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 | 99.0k | int height) { |
22 | 99.0k | const int aligned_width = ALIGN_POWER_OF_TWO(width, MI_SIZE_LOG2); |
23 | 99.0k | const int aligned_height = ALIGN_POWER_OF_TWO(height, MI_SIZE_LOG2); |
24 | 99.0k | *mi_cols = aligned_width >> MI_SIZE_LOG2; |
25 | 99.0k | *mi_rows = aligned_height >> MI_SIZE_LOG2; |
26 | 99.0k | *mi_stride = calc_mi_size(*mi_cols); |
27 | 99.0k | } |
28 | | |
29 | | void vp9_set_mb_size(int *mb_rows, int *mb_cols, int *mb_num, int mi_rows, |
30 | 99.0k | int mi_cols) { |
31 | 99.0k | *mb_cols = (mi_cols + 1) >> 1; |
32 | 99.0k | *mb_rows = (mi_rows + 1) >> 1; |
33 | 99.0k | *mb_num = (*mb_rows) * (*mb_cols); |
34 | 99.0k | } |
35 | | |
36 | 99.0k | void vp9_set_mb_mi(VP9_COMMON *cm, int width, int height) { |
37 | 99.0k | vp9_set_mi_size(&cm->mi_rows, &cm->mi_cols, &cm->mi_stride, width, height); |
38 | 99.0k | vp9_set_mb_size(&cm->mb_rows, &cm->mb_cols, &cm->MBs, cm->mi_rows, |
39 | 99.0k | cm->mi_cols); |
40 | 99.0k | } |
41 | | |
42 | 20.5k | static int alloc_seg_map(VP9_COMMON *cm, int seg_map_size) { |
43 | 20.5k | int i; |
44 | | |
45 | 61.5k | for (i = 0; i < NUM_PING_PONG_BUFFERS; ++i) { |
46 | 41.0k | cm->seg_map_array[i] = (uint8_t *)vpx_calloc(seg_map_size, 1); |
47 | 41.0k | if (cm->seg_map_array[i] == NULL) return 1; |
48 | 41.0k | } |
49 | 20.5k | cm->seg_map_alloc_size = seg_map_size; |
50 | | |
51 | | // Init the index. |
52 | 20.5k | cm->seg_map_idx = 0; |
53 | 20.5k | cm->prev_seg_map_idx = 1; |
54 | | |
55 | 20.5k | cm->current_frame_seg_map = cm->seg_map_array[cm->seg_map_idx]; |
56 | 20.5k | cm->last_frame_seg_map = cm->seg_map_array[cm->prev_seg_map_idx]; |
57 | | |
58 | 20.5k | return 0; |
59 | 20.5k | } |
60 | | |
61 | 37.6k | static void free_seg_map(VP9_COMMON *cm) { |
62 | 37.6k | int i; |
63 | | |
64 | 112k | for (i = 0; i < NUM_PING_PONG_BUFFERS; ++i) { |
65 | 75.3k | vpx_free(cm->seg_map_array[i]); |
66 | 75.3k | cm->seg_map_array[i] = NULL; |
67 | 75.3k | } |
68 | | |
69 | 37.6k | cm->current_frame_seg_map = NULL; |
70 | 37.6k | cm->last_frame_seg_map = NULL; |
71 | 37.6k | } |
72 | | |
73 | 17.1k | void vp9_free_ref_frame_buffers(BufferPool *pool) { |
74 | 17.1k | int i; |
75 | | |
76 | 17.1k | if (!pool) return; |
77 | | |
78 | 222k | for (i = 0; i < FRAME_BUFFERS; ++i) { |
79 | 205k | if (!pool->frame_bufs[i].released && |
80 | 205k | pool->frame_bufs[i].raw_frame_buffer.data != NULL) { |
81 | 26.5k | pool->release_fb_cb(pool->cb_priv, &pool->frame_bufs[i].raw_frame_buffer); |
82 | 26.5k | pool->frame_bufs[i].ref_count = 0; |
83 | 26.5k | pool->frame_bufs[i].released = 1; |
84 | 26.5k | } |
85 | 205k | vpx_free(pool->frame_bufs[i].mvs); |
86 | 205k | pool->frame_bufs[i].mvs = NULL; |
87 | 205k | vpx_free_frame_buffer(&pool->frame_bufs[i].buf); |
88 | 205k | } |
89 | 17.1k | } |
90 | | |
91 | 0 | void vp9_free_postproc_buffers(VP9_COMMON *cm) { |
92 | | #if CONFIG_VP9_POSTPROC |
93 | | vpx_free_frame_buffer(&cm->post_proc_buffer); |
94 | | vpx_free_frame_buffer(&cm->post_proc_buffer_int); |
95 | | vpx_free(cm->postproc_state.limits); |
96 | | cm->postproc_state.limits = NULL; |
97 | | vpx_free(cm->postproc_state.generated_noise); |
98 | | cm->postproc_state.generated_noise = NULL; |
99 | | #else |
100 | 0 | (void)cm; |
101 | 0 | #endif |
102 | 0 | } |
103 | | |
104 | 17.1k | void vp9_free_context_buffers(VP9_COMMON *cm) { |
105 | 17.1k | if (cm->free_mi) cm->free_mi(cm); |
106 | 17.1k | free_seg_map(cm); |
107 | 17.1k | vpx_free(cm->above_context); |
108 | 17.1k | cm->above_context = NULL; |
109 | 17.1k | vpx_free(cm->above_seg_context); |
110 | 17.1k | cm->above_seg_context = NULL; |
111 | 17.1k | vpx_free(cm->lf.lfm); |
112 | 17.1k | cm->lf.lfm = NULL; |
113 | 17.1k | } |
114 | | |
115 | 74.5k | int vp9_alloc_loop_filter(VP9_COMMON *cm) { |
116 | 74.5k | vpx_free(cm->lf.lfm); |
117 | | // Each lfm holds bit masks for all the 8x8 blocks in a 64x64 region. The |
118 | | // stride and rows are rounded up / truncated to a multiple of 8. |
119 | 74.5k | cm->lf.lfm_stride = (cm->mi_cols + (MI_BLOCK_SIZE - 1)) >> 3; |
120 | 74.5k | cm->lf.lfm = (LOOP_FILTER_MASK *)vpx_calloc( |
121 | 74.5k | ((cm->mi_rows + (MI_BLOCK_SIZE - 1)) >> 3) * cm->lf.lfm_stride, |
122 | 74.5k | sizeof(*cm->lf.lfm)); |
123 | 74.5k | if (!cm->lf.lfm) return 1; |
124 | 74.5k | return 0; |
125 | 74.5k | } |
126 | | |
127 | 74.5k | int vp9_alloc_context_buffers(VP9_COMMON *cm, int width, int height) { |
128 | 74.5k | int new_mi_size; |
129 | | |
130 | 74.5k | vp9_set_mb_mi(cm, width, height); |
131 | 74.5k | new_mi_size = cm->mi_stride * calc_mi_size(cm->mi_rows); |
132 | 74.5k | if (cm->mi_alloc_size < new_mi_size) { |
133 | 20.5k | cm->free_mi(cm); |
134 | 20.5k | if (cm->alloc_mi(cm, new_mi_size)) goto fail; |
135 | 20.5k | } |
136 | | |
137 | 74.5k | if (cm->seg_map_alloc_size < cm->mi_rows * cm->mi_cols) { |
138 | | // Create the segmentation map structure and set to 0. |
139 | 20.5k | free_seg_map(cm); |
140 | 20.5k | if (alloc_seg_map(cm, cm->mi_rows * cm->mi_cols)) goto fail; |
141 | 20.5k | } |
142 | | |
143 | 74.5k | if (cm->above_context_alloc_cols < cm->mi_cols) { |
144 | 19.3k | vpx_free(cm->above_context); |
145 | 19.3k | cm->above_context = (ENTROPY_CONTEXT *)vpx_calloc( |
146 | 19.3k | 2 * mi_cols_aligned_to_sb(cm->mi_cols) * MAX_MB_PLANE, |
147 | 19.3k | sizeof(*cm->above_context)); |
148 | 19.3k | if (!cm->above_context) goto fail; |
149 | | |
150 | 19.3k | vpx_free(cm->above_seg_context); |
151 | 19.3k | cm->above_seg_context = (PARTITION_CONTEXT *)vpx_calloc( |
152 | 19.3k | mi_cols_aligned_to_sb(cm->mi_cols), sizeof(*cm->above_seg_context)); |
153 | 19.3k | if (!cm->above_seg_context) goto fail; |
154 | 19.3k | cm->above_context_alloc_cols = cm->mi_cols; |
155 | 19.3k | } |
156 | | |
157 | 74.5k | if (vp9_alloc_loop_filter(cm)) goto fail; |
158 | | |
159 | 74.5k | return 0; |
160 | | |
161 | 0 | fail: |
162 | | // clear the mi_* values to force a realloc on resync |
163 | 0 | vp9_set_mb_mi(cm, 0, 0); |
164 | 0 | vp9_free_context_buffers(cm); |
165 | 0 | return 1; |
166 | 74.5k | } |
167 | | |
168 | 17.1k | void vp9_remove_common(VP9_COMMON *cm) { |
169 | | #if CONFIG_VP9_POSTPROC |
170 | | vp9_free_postproc_buffers(cm); |
171 | | #endif |
172 | 17.1k | vp9_free_context_buffers(cm); |
173 | | |
174 | 17.1k | vpx_free(cm->fc); |
175 | 17.1k | cm->fc = NULL; |
176 | 17.1k | vpx_free(cm->frame_contexts); |
177 | 17.1k | cm->frame_contexts = NULL; |
178 | 17.1k | } |
179 | | |
180 | 99.0k | void vp9_init_context_buffers(VP9_COMMON *cm) { |
181 | 99.0k | cm->setup_mi(cm); |
182 | 99.0k | if (cm->last_frame_seg_map) |
183 | 99.0k | memset(cm->last_frame_seg_map, 0, cm->mi_rows * cm->mi_cols); |
184 | 99.0k | } |
185 | | |
186 | 28.5k | void vp9_swap_current_and_last_seg_map(VP9_COMMON *cm) { |
187 | | // Swap indices. |
188 | 28.5k | const int tmp = cm->seg_map_idx; |
189 | 28.5k | cm->seg_map_idx = cm->prev_seg_map_idx; |
190 | 28.5k | cm->prev_seg_map_idx = tmp; |
191 | | |
192 | 28.5k | cm->current_frame_seg_map = cm->seg_map_array[cm->seg_map_idx]; |
193 | 28.5k | cm->last_frame_seg_map = cm->seg_map_array[cm->prev_seg_map_idx]; |
194 | 28.5k | } |