|
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 |
|
12 #include "./vpx_config.h" |
|
13 #include "vpx_mem/vpx_mem.h" |
|
14 |
|
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_findnearmv.h" |
|
19 #include "vp9/common/vp9_onyxc_int.h" |
|
20 #include "vp9/common/vp9_systemdependent.h" |
|
21 |
|
22 void vp9_update_mode_info_border(VP9_COMMON *cm, MODE_INFO *mi) { |
|
23 const int stride = cm->mode_info_stride; |
|
24 int i; |
|
25 |
|
26 // Clear down top border row |
|
27 vpx_memset(mi, 0, sizeof(MODE_INFO) * stride); |
|
28 |
|
29 // Clear left border column |
|
30 for (i = 1; i < cm->mi_rows + 1; i++) |
|
31 vpx_memset(&mi[i * stride], 0, sizeof(MODE_INFO)); |
|
32 } |
|
33 |
|
34 void vp9_free_frame_buffers(VP9_COMMON *cm) { |
|
35 int i; |
|
36 |
|
37 for (i = 0; i < NUM_YV12_BUFFERS; i++) |
|
38 vp9_free_frame_buffer(&cm->yv12_fb[i]); |
|
39 |
|
40 vp9_free_frame_buffer(&cm->post_proc_buffer); |
|
41 |
|
42 vpx_free(cm->mip); |
|
43 vpx_free(cm->prev_mip); |
|
44 vpx_free(cm->last_frame_seg_map); |
|
45 vpx_free(cm->mi_grid_base); |
|
46 vpx_free(cm->prev_mi_grid_base); |
|
47 |
|
48 cm->mip = NULL; |
|
49 cm->prev_mip = NULL; |
|
50 cm->last_frame_seg_map = NULL; |
|
51 cm->mi_grid_base = NULL; |
|
52 cm->prev_mi_grid_base = NULL; |
|
53 } |
|
54 |
|
55 static void set_mb_mi(VP9_COMMON *cm, int aligned_width, int aligned_height) { |
|
56 cm->mi_cols = aligned_width >> MI_SIZE_LOG2; |
|
57 cm->mi_rows = aligned_height >> MI_SIZE_LOG2; |
|
58 cm->mode_info_stride = cm->mi_cols + MI_BLOCK_SIZE; |
|
59 |
|
60 cm->mb_cols = (cm->mi_cols + 1) >> 1; |
|
61 cm->mb_rows = (cm->mi_rows + 1) >> 1; |
|
62 cm->MBs = cm->mb_rows * cm->mb_cols; |
|
63 } |
|
64 |
|
65 static void setup_mi(VP9_COMMON *cm) { |
|
66 cm->mi = cm->mip + cm->mode_info_stride + 1; |
|
67 cm->prev_mi = cm->prev_mip + cm->mode_info_stride + 1; |
|
68 cm->mi_grid_visible = cm->mi_grid_base + cm->mode_info_stride + 1; |
|
69 cm->prev_mi_grid_visible = cm->prev_mi_grid_base + cm->mode_info_stride + 1; |
|
70 |
|
71 vpx_memset(cm->mip, 0, |
|
72 cm->mode_info_stride * (cm->mi_rows + 1) * sizeof(MODE_INFO)); |
|
73 |
|
74 vpx_memset(cm->mi_grid_base, 0, |
|
75 cm->mode_info_stride * (cm->mi_rows + 1) * |
|
76 sizeof(*cm->mi_grid_base)); |
|
77 |
|
78 vp9_update_mode_info_border(cm, cm->mip); |
|
79 vp9_update_mode_info_border(cm, cm->prev_mip); |
|
80 } |
|
81 |
|
82 int vp9_resize_frame_buffers(VP9_COMMON *cm, int width, int height) { |
|
83 const int aligned_width = ALIGN_POWER_OF_TWO(width, MI_SIZE_LOG2); |
|
84 const int aligned_height = ALIGN_POWER_OF_TWO(height, MI_SIZE_LOG2); |
|
85 const int ss_x = cm->subsampling_x; |
|
86 const int ss_y = cm->subsampling_y; |
|
87 int mi_size; |
|
88 |
|
89 if (vp9_realloc_frame_buffer(&cm->post_proc_buffer, width, height, ss_x, ss_y, |
|
90 VP9BORDERINPIXELS) < 0) |
|
91 goto fail; |
|
92 |
|
93 set_mb_mi(cm, aligned_width, aligned_height); |
|
94 |
|
95 // Allocation |
|
96 mi_size = cm->mode_info_stride * (cm->mi_rows + MI_BLOCK_SIZE); |
|
97 |
|
98 vpx_free(cm->mip); |
|
99 cm->mip = vpx_calloc(mi_size, sizeof(MODE_INFO)); |
|
100 if (!cm->mip) |
|
101 goto fail; |
|
102 |
|
103 vpx_free(cm->prev_mip); |
|
104 cm->prev_mip = vpx_calloc(mi_size, sizeof(MODE_INFO)); |
|
105 if (!cm->prev_mip) |
|
106 goto fail; |
|
107 |
|
108 vpx_free(cm->mi_grid_base); |
|
109 cm->mi_grid_base = vpx_calloc(mi_size, sizeof(*cm->mi_grid_base)); |
|
110 if (!cm->mi_grid_base) |
|
111 goto fail; |
|
112 |
|
113 vpx_free(cm->prev_mi_grid_base); |
|
114 cm->prev_mi_grid_base = vpx_calloc(mi_size, sizeof(*cm->prev_mi_grid_base)); |
|
115 if (!cm->prev_mi_grid_base) |
|
116 goto fail; |
|
117 |
|
118 setup_mi(cm); |
|
119 |
|
120 // Create the segmentation map structure and set to 0. |
|
121 vpx_free(cm->last_frame_seg_map); |
|
122 cm->last_frame_seg_map = vpx_calloc(cm->mi_rows * cm->mi_cols, 1); |
|
123 if (!cm->last_frame_seg_map) |
|
124 goto fail; |
|
125 |
|
126 return 0; |
|
127 |
|
128 fail: |
|
129 vp9_free_frame_buffers(cm); |
|
130 return 1; |
|
131 } |
|
132 |
|
133 int vp9_alloc_frame_buffers(VP9_COMMON *cm, int width, int height) { |
|
134 int i; |
|
135 |
|
136 const int aligned_width = ALIGN_POWER_OF_TWO(width, MI_SIZE_LOG2); |
|
137 const int aligned_height = ALIGN_POWER_OF_TWO(height, MI_SIZE_LOG2); |
|
138 const int ss_x = cm->subsampling_x; |
|
139 const int ss_y = cm->subsampling_y; |
|
140 int mi_size; |
|
141 |
|
142 vp9_free_frame_buffers(cm); |
|
143 |
|
144 for (i = 0; i < NUM_YV12_BUFFERS; i++) { |
|
145 cm->fb_idx_ref_cnt[i] = 0; |
|
146 if (vp9_alloc_frame_buffer(&cm->yv12_fb[i], width, height, ss_x, ss_y, |
|
147 VP9BORDERINPIXELS) < 0) |
|
148 goto fail; |
|
149 } |
|
150 |
|
151 cm->new_fb_idx = NUM_YV12_BUFFERS - 1; |
|
152 cm->fb_idx_ref_cnt[cm->new_fb_idx] = 1; |
|
153 |
|
154 for (i = 0; i < ALLOWED_REFS_PER_FRAME; i++) |
|
155 cm->active_ref_idx[i] = i; |
|
156 |
|
157 for (i = 0; i < NUM_REF_FRAMES; i++) { |
|
158 cm->ref_frame_map[i] = i; |
|
159 cm->fb_idx_ref_cnt[i] = 1; |
|
160 } |
|
161 |
|
162 if (vp9_alloc_frame_buffer(&cm->post_proc_buffer, width, height, ss_x, ss_y, |
|
163 VP9BORDERINPIXELS) < 0) |
|
164 goto fail; |
|
165 |
|
166 set_mb_mi(cm, aligned_width, aligned_height); |
|
167 |
|
168 // Allocation |
|
169 mi_size = cm->mode_info_stride * (cm->mi_rows + MI_BLOCK_SIZE); |
|
170 |
|
171 cm->mip = vpx_calloc(mi_size, sizeof(MODE_INFO)); |
|
172 if (!cm->mip) |
|
173 goto fail; |
|
174 |
|
175 cm->prev_mip = vpx_calloc(mi_size, sizeof(MODE_INFO)); |
|
176 if (!cm->prev_mip) |
|
177 goto fail; |
|
178 |
|
179 cm->mi_grid_base = vpx_calloc(mi_size, sizeof(*cm->mi_grid_base)); |
|
180 if (!cm->mi_grid_base) |
|
181 goto fail; |
|
182 |
|
183 cm->prev_mi_grid_base = vpx_calloc(mi_size, sizeof(*cm->prev_mi_grid_base)); |
|
184 if (!cm->prev_mi_grid_base) |
|
185 goto fail; |
|
186 |
|
187 setup_mi(cm); |
|
188 |
|
189 // Create the segmentation map structure and set to 0. |
|
190 cm->last_frame_seg_map = vpx_calloc(cm->mi_rows * cm->mi_cols, 1); |
|
191 if (!cm->last_frame_seg_map) |
|
192 goto fail; |
|
193 |
|
194 return 0; |
|
195 |
|
196 fail: |
|
197 vp9_free_frame_buffers(cm); |
|
198 return 1; |
|
199 } |
|
200 |
|
201 void vp9_create_common(VP9_COMMON *cm) { |
|
202 vp9_machine_specific_config(cm); |
|
203 |
|
204 cm->tx_mode = ONLY_4X4; |
|
205 cm->comp_pred_mode = HYBRID_PREDICTION; |
|
206 } |
|
207 |
|
208 void vp9_remove_common(VP9_COMMON *cm) { |
|
209 vp9_free_frame_buffers(cm); |
|
210 } |
|
211 |
|
212 void vp9_initialize_common() { |
|
213 vp9_init_neighbors(); |
|
214 vp9_coef_tree_initialize(); |
|
215 vp9_entropy_mode_init(); |
|
216 vp9_entropy_mv_init(); |
|
217 } |
|
218 |
|
219 void vp9_update_frame_size(VP9_COMMON *cm) { |
|
220 const int aligned_width = ALIGN_POWER_OF_TWO(cm->width, MI_SIZE_LOG2); |
|
221 const int aligned_height = ALIGN_POWER_OF_TWO(cm->height, MI_SIZE_LOG2); |
|
222 |
|
223 set_mb_mi(cm, aligned_width, aligned_height); |
|
224 setup_mi(cm); |
|
225 |
|
226 // Initialize the previous frame segment map to 0. |
|
227 if (cm->last_frame_seg_map) |
|
228 vpx_memset(cm->last_frame_seg_map, 0, cm->mi_rows * cm->mi_cols); |
|
229 } |