2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
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.
11 #include "./vpx_config.h"
12 #include "vpx_mem/vpx_mem.h"
14 #include "vp9/common/vp9_blockd.h"
15 #include "vp9/common/vp9_entropymode.h"
16 #include "vp9/common/vp9_entropymv.h"
17 #include "vp9/common/vp9_onyxc_int.h"
18 #include "vp9/common/vp9_systemdependent.h"
20 static void clear_mi_border(const VP9_COMMON
*cm
, MODE_INFO
*mi
) {
24 vpx_memset(mi
, 0, sizeof(*mi
) * cm
->mi_stride
);
27 for (i
= 1; i
< cm
->mi_rows
+ 1; ++i
)
28 vpx_memset(&mi
[i
* cm
->mi_stride
], 0, sizeof(*mi
));
31 static void set_mb_mi(VP9_COMMON
*cm
, int aligned_width
, int aligned_height
) {
32 cm
->mi_cols
= aligned_width
>> MI_SIZE_LOG2
;
33 cm
->mi_rows
= aligned_height
>> MI_SIZE_LOG2
;
34 cm
->mi_stride
= cm
->mi_cols
+ MI_BLOCK_SIZE
;
36 cm
->mb_cols
= (cm
->mi_cols
+ 1) >> 1;
37 cm
->mb_rows
= (cm
->mi_rows
+ 1) >> 1;
38 cm
->MBs
= cm
->mb_rows
* cm
->mb_cols
;
41 static void setup_mi(VP9_COMMON
*cm
) {
42 cm
->mi
= cm
->mip
+ cm
->mi_stride
+ 1;
43 cm
->prev_mi
= cm
->prev_mip
+ cm
->mi_stride
+ 1;
44 cm
->mi_grid_visible
= cm
->mi_grid_base
+ cm
->mi_stride
+ 1;
45 cm
->prev_mi_grid_visible
= cm
->prev_mi_grid_base
+ cm
->mi_stride
+ 1;
47 vpx_memset(cm
->mip
, 0, cm
->mi_stride
* (cm
->mi_rows
+ 1) * sizeof(*cm
->mip
));
49 vpx_memset(cm
->mi_grid_base
, 0, cm
->mi_stride
* (cm
->mi_rows
+ 1) *
50 sizeof(*cm
->mi_grid_base
));
52 clear_mi_border(cm
, cm
->prev_mip
);
55 static int alloc_mi(VP9_COMMON
*cm
, int mi_size
) {
58 for (i
= 0; i
< 2; ++i
) {
60 (MODE_INFO
*)vpx_calloc(mi_size
, sizeof(*cm
->mip
));
61 if (cm
->mip_array
[i
] == NULL
)
64 cm
->mi_grid_base_array
[i
] =
65 (MODE_INFO
**)vpx_calloc(mi_size
, sizeof(*cm
->mi_grid_base
));
66 if (cm
->mi_grid_base_array
[i
] == NULL
)
74 cm
->mip
= cm
->mip_array
[cm
->mi_idx
];
75 cm
->prev_mip
= cm
->mip_array
[cm
->prev_mi_idx
];
76 cm
->mi_grid_base
= cm
->mi_grid_base_array
[cm
->mi_idx
];
77 cm
->prev_mi_grid_base
= cm
->mi_grid_base_array
[cm
->prev_mi_idx
];
82 static void free_mi(VP9_COMMON
*cm
) {
85 for (i
= 0; i
< 2; ++i
) {
86 vpx_free(cm
->mip_array
[i
]);
87 cm
->mip_array
[i
] = NULL
;
88 vpx_free(cm
->mi_grid_base_array
[i
]);
89 cm
->mi_grid_base_array
[i
] = NULL
;
94 cm
->mi_grid_base
= NULL
;
95 cm
->prev_mi_grid_base
= NULL
;
98 void vp9_free_frame_buffers(VP9_COMMON
*cm
) {
101 for (i
= 0; i
< FRAME_BUFFERS
; ++i
) {
102 vp9_free_frame_buffer(&cm
->frame_bufs
[i
].buf
);
104 if (cm
->frame_bufs
[i
].ref_count
> 0 &&
105 cm
->frame_bufs
[i
].raw_frame_buffer
.data
!= NULL
) {
106 cm
->release_fb_cb(cm
->cb_priv
, &cm
->frame_bufs
[i
].raw_frame_buffer
);
107 cm
->frame_bufs
[i
].ref_count
= 0;
111 vp9_free_frame_buffer(&cm
->post_proc_buffer
);
114 void vp9_free_context_buffers(VP9_COMMON
*cm
) {
117 vpx_free(cm
->last_frame_seg_map
);
118 cm
->last_frame_seg_map
= NULL
;
120 vpx_free(cm
->above_context
);
121 cm
->above_context
= NULL
;
123 vpx_free(cm
->above_seg_context
);
124 cm
->above_seg_context
= NULL
;
127 int vp9_resize_frame_buffers(VP9_COMMON
*cm
, int width
, int height
) {
128 const int aligned_width
= ALIGN_POWER_OF_TWO(width
, MI_SIZE_LOG2
);
129 const int aligned_height
= ALIGN_POWER_OF_TWO(height
, MI_SIZE_LOG2
);
130 const int ss_x
= cm
->subsampling_x
;
131 const int ss_y
= cm
->subsampling_y
;
133 if (vp9_realloc_frame_buffer(&cm
->post_proc_buffer
, width
, height
, ss_x
, ss_y
,
134 VP9_DEC_BORDER_IN_PIXELS
, NULL
, NULL
, NULL
) < 0)
137 set_mb_mi(cm
, aligned_width
, aligned_height
);
140 if (alloc_mi(cm
, cm
->mi_stride
* (cm
->mi_rows
+ MI_BLOCK_SIZE
)))
145 // Create the segmentation map structure and set to 0.
146 vpx_free(cm
->last_frame_seg_map
);
147 cm
->last_frame_seg_map
= (uint8_t *)vpx_calloc(cm
->mi_rows
* cm
->mi_cols
, 1);
148 if (!cm
->last_frame_seg_map
)
151 vpx_free(cm
->above_context
);
153 (ENTROPY_CONTEXT
*)vpx_calloc(2 * mi_cols_aligned_to_sb(cm
->mi_cols
) *
155 sizeof(*cm
->above_context
));
156 if (!cm
->above_context
)
159 vpx_free(cm
->above_seg_context
);
160 cm
->above_seg_context
=
161 (PARTITION_CONTEXT
*)vpx_calloc(mi_cols_aligned_to_sb(cm
->mi_cols
),
162 sizeof(*cm
->above_seg_context
));
163 if (!cm
->above_seg_context
)
169 vp9_free_frame_buffers(cm
);
170 vp9_free_context_buffers(cm
);
174 static void init_frame_bufs(VP9_COMMON
*cm
) {
177 cm
->new_fb_idx
= FRAME_BUFFERS
- 1;
178 cm
->frame_bufs
[cm
->new_fb_idx
].ref_count
= 1;
180 for (i
= 0; i
< REF_FRAMES
; ++i
) {
181 cm
->ref_frame_map
[i
] = i
;
182 cm
->frame_bufs
[i
].ref_count
= 1;
186 int vp9_alloc_frame_buffers(VP9_COMMON
*cm
, int width
, int height
) {
188 const int ss_x
= cm
->subsampling_x
;
189 const int ss_y
= cm
->subsampling_y
;
191 vp9_free_frame_buffers(cm
);
193 for (i
= 0; i
< FRAME_BUFFERS
; ++i
) {
194 cm
->frame_bufs
[i
].ref_count
= 0;
195 if (vp9_alloc_frame_buffer(&cm
->frame_bufs
[i
].buf
, width
, height
,
196 ss_x
, ss_y
, VP9_ENC_BORDER_IN_PIXELS
) < 0)
202 if (vp9_alloc_frame_buffer(&cm
->post_proc_buffer
, width
, height
, ss_x
, ss_y
,
203 VP9_ENC_BORDER_IN_PIXELS
) < 0)
209 vp9_free_frame_buffers(cm
);
213 int vp9_alloc_context_buffers(VP9_COMMON
*cm
, int width
, int height
) {
214 const int aligned_width
= ALIGN_POWER_OF_TWO(width
, MI_SIZE_LOG2
);
215 const int aligned_height
= ALIGN_POWER_OF_TWO(height
, MI_SIZE_LOG2
);
217 vp9_free_context_buffers(cm
);
219 set_mb_mi(cm
, aligned_width
, aligned_height
);
221 if (alloc_mi(cm
, cm
->mi_stride
* (cm
->mi_rows
+ MI_BLOCK_SIZE
)))
226 // Create the segmentation map structure and set to 0.
227 cm
->last_frame_seg_map
= (uint8_t *)vpx_calloc(cm
->mi_rows
* cm
->mi_cols
, 1);
228 if (!cm
->last_frame_seg_map
)
232 (ENTROPY_CONTEXT
*)vpx_calloc(2 * mi_cols_aligned_to_sb(cm
->mi_cols
) *
234 sizeof(*cm
->above_context
));
235 if (!cm
->above_context
)
238 cm
->above_seg_context
=
239 (PARTITION_CONTEXT
*)vpx_calloc(mi_cols_aligned_to_sb(cm
->mi_cols
),
240 sizeof(*cm
->above_seg_context
));
241 if (!cm
->above_seg_context
)
247 vp9_free_context_buffers(cm
);
251 void vp9_remove_common(VP9_COMMON
*cm
) {
252 vp9_free_frame_buffers(cm
);
253 vp9_free_context_buffers(cm
);
254 vp9_free_internal_frame_buffers(&cm
->int_frame_buffers
);
257 void vp9_update_frame_size(VP9_COMMON
*cm
) {
258 const int aligned_width
= ALIGN_POWER_OF_TWO(cm
->width
, MI_SIZE_LOG2
);
259 const int aligned_height
= ALIGN_POWER_OF_TWO(cm
->height
, MI_SIZE_LOG2
);
261 set_mb_mi(cm
, aligned_width
, aligned_height
);
264 // Initialize the previous frame segment map to 0.
265 if (cm
->last_frame_seg_map
)
266 vpx_memset(cm
->last_frame_seg_map
, 0, cm
->mi_rows
* cm
->mi_cols
);
269 void vp9_swap_mi_and_prev_mi(VP9_COMMON
*cm
) {
271 const int tmp
= cm
->mi_idx
;
272 cm
->mi_idx
= cm
->prev_mi_idx
;
273 cm
->prev_mi_idx
= tmp
;
275 // Current mip will be the prev_mip for the next frame.
276 cm
->mip
= cm
->mip_array
[cm
->mi_idx
];
277 cm
->prev_mip
= cm
->mip_array
[cm
->prev_mi_idx
];
278 cm
->mi_grid_base
= cm
->mi_grid_base_array
[cm
->mi_idx
];
279 cm
->prev_mi_grid_base
= cm
->mi_grid_base_array
[cm
->prev_mi_idx
];
281 // Update the upper left visible macroblock ptrs.
282 cm
->mi
= cm
->mip
+ cm
->mi_stride
+ 1;
283 cm
->prev_mi
= cm
->prev_mip
+ cm
->mi_stride
+ 1;
284 cm
->mi_grid_visible
= cm
->mi_grid_base
+ cm
->mi_stride
+ 1;
285 cm
->prev_mi_grid_visible
= cm
->prev_mi_grid_base
+ cm
->mi_stride
+ 1;