blob: 535a2fa0185d52077287ef0424f3f6cacfa75093 [file] [log] [blame]
Yaowu Xuc27fc142016-08-22 16:08:15 -07001/*
Debargha Mukherjee999d2f62016-12-15 13:23:21 -08002 *
Yaowu Xu9c01aa12016-09-01 14:32:49 -07003 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Yaowu Xuc27fc142016-08-22 16:08:15 -07004 *
Yaowu Xu9c01aa12016-09-01 14:32:49 -07005 * This source code is subject to the terms of the BSD 2 Clause License and
6 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
7 * was not distributed with this source code in the LICENSE file, you can
8 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
9 * Media Patent License 1.0 was not distributed with this source code in the
10 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
Yaowu Xuc27fc142016-08-22 16:08:15 -070011 */
12
Yaowu Xuf883b422016-08-30 14:01:10 -070013#include "./aom_config.h"
14#include "aom_mem/aom_mem.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070015
16#include "av1/common/alloccommon.h"
17#include "av1/common/blockd.h"
18#include "av1/common/entropymode.h"
19#include "av1/common/entropymv.h"
20#include "av1/common/onyxc_int.h"
21
Debargha Mukherjee7166f222017-09-05 21:32:42 -070022int av1_get_MBs(int width, int height) {
23 const int aligned_width = ALIGN_POWER_OF_TWO(width, 3);
24 const int aligned_height = ALIGN_POWER_OF_TWO(height, 3);
25 const int mi_cols = aligned_width >> MI_SIZE_LOG2;
26 const int mi_rows = aligned_height >> MI_SIZE_LOG2;
27
Debargha Mukherjee7166f222017-09-05 21:32:42 -070028 const int mb_cols = (mi_cols + 2) >> 2;
29 const int mb_rows = (mi_rows + 2) >> 2;
Debargha Mukherjee7166f222017-09-05 21:32:42 -070030 return mb_rows * mb_cols;
31}
32
Yaowu Xuf883b422016-08-30 14:01:10 -070033void av1_set_mb_mi(AV1_COMMON *cm, int width, int height) {
David Barkeree0fd922017-09-07 15:18:35 +010034 // Ensure that the decoded width and height are both multiples of
35 // 8 luma pixels (note: this may only be a multiple of 4 chroma pixels if
36 // subsampling is used).
37 // This simplifies the implementation of various experiments,
38 // eg. cdef, which operates on units of 8x8 luma pixels.
Jingning Han944b8052017-03-31 08:57:30 -070039 const int aligned_width = ALIGN_POWER_OF_TWO(width, 3);
40 const int aligned_height = ALIGN_POWER_OF_TWO(height, 3);
Yaowu Xuc27fc142016-08-22 16:08:15 -070041
42 cm->mi_cols = aligned_width >> MI_SIZE_LOG2;
43 cm->mi_rows = aligned_height >> MI_SIZE_LOG2;
44 cm->mi_stride = calc_mi_size(cm->mi_cols);
45
Jingning Han91ad0e82016-12-07 17:59:32 -080046 cm->mb_cols = (cm->mi_cols + 2) >> 2;
47 cm->mb_rows = (cm->mi_rows + 2) >> 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -070048 cm->MBs = cm->mb_rows * cm->mb_cols;
49}
50
Soo-Chul Han934af352017-10-15 15:21:51 -040051#if !CONFIG_SEGMENT_PRED_LAST
Rostislav Pehlivanovf624dd52017-10-24 16:46:09 +010052static int alloc_seg_map(AV1_COMMON *cm, int rows, int cols) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070053 int i;
Rostislav Pehlivanovf624dd52017-10-24 16:46:09 +010054 int seg_map_size = rows * cols;
55
Yaowu Xuc27fc142016-08-22 16:08:15 -070056 for (i = 0; i < NUM_PING_PONG_BUFFERS; ++i) {
Yaowu Xuf883b422016-08-30 14:01:10 -070057 cm->seg_map_array[i] = (uint8_t *)aom_calloc(seg_map_size, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -070058 if (cm->seg_map_array[i] == NULL) return 1;
59 }
60 cm->seg_map_alloc_size = seg_map_size;
61
62 // Init the index.
63 cm->seg_map_idx = 0;
64 cm->prev_seg_map_idx = 1;
65
66 cm->current_frame_seg_map = cm->seg_map_array[cm->seg_map_idx];
67 if (!cm->frame_parallel_decode)
68 cm->last_frame_seg_map = cm->seg_map_array[cm->prev_seg_map_idx];
69
70 return 0;
71}
72
Yaowu Xuf883b422016-08-30 14:01:10 -070073static void free_seg_map(AV1_COMMON *cm) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070074 int i;
75
76 for (i = 0; i < NUM_PING_PONG_BUFFERS; ++i) {
Yaowu Xuf883b422016-08-30 14:01:10 -070077 aom_free(cm->seg_map_array[i]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070078 cm->seg_map_array[i] = NULL;
79 }
80
81 cm->current_frame_seg_map = NULL;
82
83 if (!cm->frame_parallel_decode) {
84 cm->last_frame_seg_map = NULL;
85 }
Debargha Mukherjeeccb27262017-09-25 14:19:46 -070086 cm->seg_map_alloc_size = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070087}
Soo-Chul Han934af352017-10-15 15:21:51 -040088#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070089
Yaowu Xuf883b422016-08-30 14:01:10 -070090void av1_free_ref_frame_buffers(BufferPool *pool) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070091 int i;
92
93 for (i = 0; i < FRAME_BUFFERS; ++i) {
94 if (pool->frame_bufs[i].ref_count > 0 &&
95 pool->frame_bufs[i].raw_frame_buffer.data != NULL) {
96 pool->release_fb_cb(pool->cb_priv, &pool->frame_bufs[i].raw_frame_buffer);
97 pool->frame_bufs[i].ref_count = 0;
98 }
Yaowu Xuf883b422016-08-30 14:01:10 -070099 aom_free(pool->frame_bufs[i].mvs);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700100 pool->frame_bufs[i].mvs = NULL;
Soo-Chul Han934af352017-10-15 15:21:51 -0400101#if CONFIG_SEGMENT_PRED_LAST
102 aom_free(pool->frame_bufs[i].seg_map);
103 pool->frame_bufs[i].seg_map = NULL;
104#endif
Yaowu Xuf883b422016-08-30 14:01:10 -0700105 aom_free_frame_buffer(&pool->frame_bufs[i].buf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700106 }
107}
108
109#if CONFIG_LOOP_RESTORATION
Rupert Swarbrickbcb65fe2017-10-25 17:15:28 +0100110// Assumes cm->rst_info[p].restoration_unit_size is already initialized
Debargha Mukherjee874d36d2016-12-14 16:53:17 -0800111void av1_alloc_restoration_buffers(AV1_COMMON *cm) {
Rupert Swarbrickbcb65fe2017-10-25 17:15:28 +0100112 for (int p = 0; p < MAX_MB_PLANE; ++p)
113 av1_alloc_restoration_struct(cm, &cm->rst_info[p], p > 0);
114 aom_free(cm->rst_tmpbuf);
115 CHECK_MEM_ERROR(cm, cm->rst_tmpbuf,
116 (int32_t *)aom_memalign(16, RESTORATION_TMPBUF_SIZE));
117
118#if CONFIG_STRIPED_LOOP_RESTORATION
Rupert Swarbrickdee00eb2017-11-02 17:24:37 +0000119 // For striped loop restoration, we divide each row of tiles into "stripes",
120 // of height 64 luma pixels but with an offset by RESTORATION_TILE_OFFSET
121 // luma pixels to match the output from CDEF. We will need to store 2 *
122 // RESTORATION_CTX_VERT lines of data for each stripe, and also need to be
123 // able to quickly answer the question "Where is the <n>'th stripe for tile
124 // row <m>?" To make that efficient, we generate the rst_last_stripe array.
125 int num_stripes = 0;
126 for (int i = 0; i < cm->tile_rows; ++i) {
127#if CONFIG_MAX_TILE
Dominic Symes917d6c02017-10-11 18:00:52 +0200128 TileInfo tile_info;
129 av1_tile_set_row(&tile_info, cm, i);
130 const int mi_h = tile_info.mi_row_end - tile_info.mi_row_start;
Fergus Simpson9cd57cf2017-06-12 17:02:03 -0700131#else
Rupert Swarbrickdee00eb2017-11-02 17:24:37 +0000132 const int mi_h = ((i + 1) < cm->tile_rows)
133 ? cm->tile_height
134 : (cm->mi_rows - i * cm->tile_height);
135#endif
136 const int ext_h = RESTORATION_TILE_OFFSET + (mi_h << MI_SIZE_LOG2);
137 const int tile_stripes = (ext_h + 63) / 64;
138 num_stripes += tile_stripes;
139 cm->rst_end_stripe[i] = num_stripes;
140 }
Ola Hugosson1e7f2d02017-09-22 21:36:26 +0200141
Rupert Swarbrickdee00eb2017-11-02 17:24:37 +0000142// Now we need to allocate enough space to store the line buffers for the
143// stripes
Urvang Joshi94ad3702017-12-06 11:38:08 -0800144#if CONFIG_HORZONLY_FRAME_SUPERRES
Rupert Swarbrickdee00eb2017-11-02 17:24:37 +0000145 const int frame_w = cm->superres_upscaled_width;
146#else
147 const int frame_w = cm->width;
Urvang Joshi94ad3702017-12-06 11:38:08 -0800148#endif // CONFIG_HORZONLY_FRAME_SUPERRES
Rupert Swarbrickdee00eb2017-11-02 17:24:37 +0000149#if CONFIG_HIGHBITDEPTH
150 const int use_highbd = cm->use_highbitdepth ? 1 : 0;
151#else
152 const int use_highbd = 0;
153#endif
Rupert Swarbrickbcb65fe2017-10-25 17:15:28 +0100154 for (int p = 0; p < MAX_MB_PLANE; ++p) {
Rupert Swarbrickdee00eb2017-11-02 17:24:37 +0000155 const int is_uv = p > 0;
156 const int ss_x = is_uv && cm->subsampling_x;
Rupert Swarbrickefa76d72017-11-06 17:13:46 +0000157 const int plane_w = ((frame_w + ss_x) >> ss_x) + 2 * RESTORATION_EXTRA_HORZ;
Yaowu Xua967ebb2017-12-14 14:25:05 -0800158 const int stride = ALIGN_POWER_OF_TWO(plane_w, 5);
Rupert Swarbrickdee00eb2017-11-02 17:24:37 +0000159 const int buf_size = num_stripes * stride * RESTORATION_CTX_VERT
160 << use_highbd;
Rupert Swarbrickdd6f09a2017-10-19 16:10:23 +0100161 RestorationStripeBoundaries *boundaries = &cm->rst_info[p].boundaries;
162 aom_free(boundaries->stripe_boundary_above);
163 aom_free(boundaries->stripe_boundary_below);
Ola Hugosson1e7f2d02017-09-22 21:36:26 +0200164
Rupert Swarbrickdee00eb2017-11-02 17:24:37 +0000165 CHECK_MEM_ERROR(cm, boundaries->stripe_boundary_above,
Yaowu Xua967ebb2017-12-14 14:25:05 -0800166 (uint8_t *)aom_memalign(32, buf_size));
Rupert Swarbrickdee00eb2017-11-02 17:24:37 +0000167 CHECK_MEM_ERROR(cm, boundaries->stripe_boundary_below,
Yaowu Xua967ebb2017-12-14 14:25:05 -0800168 (uint8_t *)aom_memalign(32, buf_size));
Rupert Swarbrickdee00eb2017-11-02 17:24:37 +0000169
Rupert Swarbrickdd6f09a2017-10-19 16:10:23 +0100170 boundaries->stripe_boundary_stride = stride;
Ola Hugosson1e7f2d02017-09-22 21:36:26 +0200171 }
172#endif // CONFIG_STRIPED_LOOP_RESTORATION
Debargha Mukherjee874d36d2016-12-14 16:53:17 -0800173}
174
Yaowu Xuf883b422016-08-30 14:01:10 -0700175void av1_free_restoration_buffers(AV1_COMMON *cm) {
Debargha Mukherjeea43a2d92017-01-03 15:14:57 -0800176 int p;
177 for (p = 0; p < MAX_MB_PLANE; ++p)
178 av1_free_restoration_struct(&cm->rst_info[p]);
Rupert Swarbrickf88bc042017-10-18 10:45:51 +0100179 aom_free(cm->rst_tmpbuf);
180 cm->rst_tmpbuf = NULL;
Ola Hugosson54671902017-10-24 09:09:36 +0200181#if CONFIG_STRIPED_LOOP_RESTORATION
182 for (p = 0; p < MAX_MB_PLANE; ++p) {
183 RestorationStripeBoundaries *boundaries = &cm->rst_info[p].boundaries;
184 aom_free(boundaries->stripe_boundary_above);
185 aom_free(boundaries->stripe_boundary_below);
186 boundaries->stripe_boundary_above = NULL;
187 boundaries->stripe_boundary_below = NULL;
188 }
189#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700190}
191#endif // CONFIG_LOOP_RESTORATION
192
Yaowu Xuf883b422016-08-30 14:01:10 -0700193void av1_free_context_buffers(AV1_COMMON *cm) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700194 int i;
195 cm->free_mi(cm);
Soo-Chul Han934af352017-10-15 15:21:51 -0400196#if !CONFIG_SEGMENT_PRED_LAST
Yaowu Xuc27fc142016-08-22 16:08:15 -0700197 free_seg_map(cm);
Soo-Chul Han934af352017-10-15 15:21:51 -0400198#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700199 for (i = 0; i < MAX_MB_PLANE; i++) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700200 aom_free(cm->above_context[i]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700201 cm->above_context[i] = NULL;
202 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700203 aom_free(cm->above_seg_context);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700204 cm->above_seg_context = NULL;
Debargha Mukherjeeccb27262017-09-25 14:19:46 -0700205 cm->above_context_alloc_cols = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -0700206 aom_free(cm->above_txfm_context);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700207 cm->above_txfm_context = NULL;
Jingning Han6e4955d2017-05-30 22:54:48 -0700208
209 for (i = 0; i < MAX_MB_PLANE; ++i) {
210 aom_free(cm->top_txfm_context[i]);
211 cm->top_txfm_context[i] = NULL;
212 }
Yaowu Xuc27fc142016-08-22 16:08:15 -0700213}
214
Yaowu Xuf883b422016-08-30 14:01:10 -0700215int av1_alloc_context_buffers(AV1_COMMON *cm, int width, int height) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700216 int new_mi_size;
217
Yaowu Xuf883b422016-08-30 14:01:10 -0700218 av1_set_mb_mi(cm, width, height);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700219 new_mi_size = cm->mi_stride * calc_mi_size(cm->mi_rows);
220 if (cm->mi_alloc_size < new_mi_size) {
221 cm->free_mi(cm);
222 if (cm->alloc_mi(cm, new_mi_size)) goto fail;
223 }
224
Soo-Chul Han934af352017-10-15 15:21:51 -0400225#if !CONFIG_SEGMENT_PRED_LAST
Yaowu Xuc27fc142016-08-22 16:08:15 -0700226 if (cm->seg_map_alloc_size < cm->mi_rows * cm->mi_cols) {
227 // Create the segmentation map structure and set to 0.
228 free_seg_map(cm);
Rostislav Pehlivanovf624dd52017-10-24 16:46:09 +0100229 if (alloc_seg_map(cm, cm->mi_rows, cm->mi_cols)) goto fail;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700230 }
Soo-Chul Han934af352017-10-15 15:21:51 -0400231#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700232
233 if (cm->above_context_alloc_cols < cm->mi_cols) {
234 // TODO(geza.lore): These are bigger than they need to be.
235 // cm->tile_width would be enough but it complicates indexing a
236 // little elsewhere.
237 const int aligned_mi_cols =
238 ALIGN_POWER_OF_TWO(cm->mi_cols, MAX_MIB_SIZE_LOG2);
239 int i;
240
241 for (i = 0; i < MAX_MB_PLANE; i++) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700242 aom_free(cm->above_context[i]);
243 cm->above_context[i] = (ENTROPY_CONTEXT *)aom_calloc(
Timothy B. Terriberry5e816432017-05-05 13:58:32 -0700244 aligned_mi_cols << (MI_SIZE_LOG2 - tx_size_wide_log2[0]),
245 sizeof(*cm->above_context[0]));
Yaowu Xuc27fc142016-08-22 16:08:15 -0700246 if (!cm->above_context[i]) goto fail;
247 }
248
Yaowu Xuf883b422016-08-30 14:01:10 -0700249 aom_free(cm->above_seg_context);
250 cm->above_seg_context = (PARTITION_CONTEXT *)aom_calloc(
Yaowu Xuc27fc142016-08-22 16:08:15 -0700251 aligned_mi_cols, sizeof(*cm->above_seg_context));
252 if (!cm->above_seg_context) goto fail;
253
Yaowu Xuf883b422016-08-30 14:01:10 -0700254 aom_free(cm->above_txfm_context);
255 cm->above_txfm_context = (TXFM_CONTEXT *)aom_calloc(
Jingning Han331662e2017-05-30 17:03:32 -0700256 aligned_mi_cols << TX_UNIT_WIDE_LOG2, sizeof(*cm->above_txfm_context));
Yaowu Xuc27fc142016-08-22 16:08:15 -0700257 if (!cm->above_txfm_context) goto fail;
Jingning Han6e4955d2017-05-30 22:54:48 -0700258
259 for (i = 0; i < MAX_MB_PLANE; ++i) {
260 aom_free(cm->top_txfm_context[i]);
261 cm->top_txfm_context[i] =
262 (TXFM_CONTEXT *)aom_calloc(aligned_mi_cols << TX_UNIT_WIDE_LOG2,
263 sizeof(*cm->top_txfm_context[0]));
264 if (!cm->top_txfm_context[i]) goto fail;
265 }
Yaowu Xuc27fc142016-08-22 16:08:15 -0700266
267 cm->above_context_alloc_cols = aligned_mi_cols;
268 }
269
270 return 0;
271
272fail:
273 // clear the mi_* values to force a realloc on resync
Yaowu Xuf883b422016-08-30 14:01:10 -0700274 av1_set_mb_mi(cm, 0, 0);
275 av1_free_context_buffers(cm);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700276 return 1;
277}
278
Yaowu Xuf883b422016-08-30 14:01:10 -0700279void av1_remove_common(AV1_COMMON *cm) {
280 av1_free_context_buffers(cm);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700281
Yaowu Xuf883b422016-08-30 14:01:10 -0700282 aom_free(cm->fc);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700283 cm->fc = NULL;
Yaowu Xuf883b422016-08-30 14:01:10 -0700284 aom_free(cm->frame_contexts);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700285 cm->frame_contexts = NULL;
286}
287
Yaowu Xuf883b422016-08-30 14:01:10 -0700288void av1_init_context_buffers(AV1_COMMON *cm) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700289 cm->setup_mi(cm);
Soo-Chul Han934af352017-10-15 15:21:51 -0400290#if !CONFIG_SEGMENT_PRED_LAST
Yaowu Xuc27fc142016-08-22 16:08:15 -0700291 if (cm->last_frame_seg_map && !cm->frame_parallel_decode)
292 memset(cm->last_frame_seg_map, 0, cm->mi_rows * cm->mi_cols);
Soo-Chul Han934af352017-10-15 15:21:51 -0400293#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700294}
Soo-Chul Han934af352017-10-15 15:21:51 -0400295#if !CONFIG_SEGMENT_PRED_LAST
Yaowu Xuf883b422016-08-30 14:01:10 -0700296void av1_swap_current_and_last_seg_map(AV1_COMMON *cm) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700297 // Swap indices.
298 const int tmp = cm->seg_map_idx;
299 cm->seg_map_idx = cm->prev_seg_map_idx;
300 cm->prev_seg_map_idx = tmp;
301
302 cm->current_frame_seg_map = cm->seg_map_array[cm->seg_map_idx];
303 cm->last_frame_seg_map = cm->seg_map_array[cm->prev_seg_map_idx];
304}
Soo-Chul Han934af352017-10-15 15:21:51 -0400305#endif