Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1 | /* |
Yaowu Xu | 2ab7ff0 | 2016-09-02 12:04:54 -0700 | [diff] [blame] | 2 | * Copyright (c) 2016, Alliance for Open Media. All rights reserved |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 3 | * |
Yaowu Xu | 2ab7ff0 | 2016-09-02 12:04:54 -0700 | [diff] [blame] | 4 | * This source code is subject to the terms of the BSD 2 Clause License and |
| 5 | * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License |
| 6 | * was not distributed with this source code in the LICENSE file, you can |
| 7 | * obtain it at www.aomedia.org/license/software. If the Alliance for Open |
| 8 | * Media Patent License 1.0 was not distributed with this source code in the |
| 9 | * PATENTS file, you can obtain it at www.aomedia.org/license/patent. |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 10 | */ |
| 11 | |
| 12 | #include <assert.h> |
| 13 | |
| 14 | #include "av1/common/frame_buffers.h" |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 15 | #include "aom_mem/aom_mem.h" |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 16 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 17 | int av1_alloc_internal_frame_buffers(InternalFrameBufferList *list) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 18 | assert(list != NULL); |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 19 | av1_free_internal_frame_buffers(list); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 20 | |
| 21 | list->num_internal_frame_buffers = |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 22 | AOM_MAXIMUM_REF_BUFFERS + AOM_MAXIMUM_WORK_BUFFERS; |
| 23 | list->int_fb = (InternalFrameBuffer *)aom_calloc( |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 24 | list->num_internal_frame_buffers, sizeof(*list->int_fb)); |
Wan-Teh Chang | 2ab147d | 2018-10-02 16:06:26 -0700 | [diff] [blame] | 25 | if (list->int_fb == NULL) { |
| 26 | list->num_internal_frame_buffers = 0; |
| 27 | return 1; |
| 28 | } |
| 29 | return 0; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 30 | } |
| 31 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 32 | void av1_free_internal_frame_buffers(InternalFrameBufferList *list) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 33 | int i; |
| 34 | |
| 35 | assert(list != NULL); |
| 36 | |
| 37 | for (i = 0; i < list->num_internal_frame_buffers; ++i) { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 38 | aom_free(list->int_fb[i].data); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 39 | list->int_fb[i].data = NULL; |
| 40 | } |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 41 | aom_free(list->int_fb); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 42 | list->int_fb = NULL; |
Wan-Teh Chang | 2ab147d | 2018-10-02 16:06:26 -0700 | [diff] [blame] | 43 | list->num_internal_frame_buffers = 0; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 44 | } |
| 45 | |
Wan-Teh Chang | c613fd4 | 2018-09-06 12:31:17 -0700 | [diff] [blame] | 46 | void av1_zero_unused_internal_frame_buffers(InternalFrameBufferList *list) { |
| 47 | int i; |
| 48 | |
| 49 | assert(list != NULL); |
| 50 | |
| 51 | for (i = 0; i < list->num_internal_frame_buffers; ++i) { |
| 52 | if (list->int_fb[i].data && !list->int_fb[i].in_use) |
| 53 | memset(list->int_fb[i].data, 0, list->int_fb[i].size); |
| 54 | } |
| 55 | } |
| 56 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 57 | int av1_get_frame_buffer(void *cb_priv, size_t min_size, |
| 58 | aom_codec_frame_buffer_t *fb) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 59 | int i; |
| 60 | InternalFrameBufferList *const int_fb_list = |
| 61 | (InternalFrameBufferList *)cb_priv; |
| 62 | if (int_fb_list == NULL) return -1; |
| 63 | |
| 64 | // Find a free frame buffer. |
| 65 | for (i = 0; i < int_fb_list->num_internal_frame_buffers; ++i) { |
| 66 | if (!int_fb_list->int_fb[i].in_use) break; |
| 67 | } |
| 68 | |
| 69 | if (i == int_fb_list->num_internal_frame_buffers) return -1; |
| 70 | |
| 71 | if (int_fb_list->int_fb[i].size < min_size) { |
Alex Converse | 7f094f1 | 2017-02-23 17:29:40 -0800 | [diff] [blame] | 72 | aom_free(int_fb_list->int_fb[i].data); |
Wan-Teh Chang | c613fd4 | 2018-09-06 12:31:17 -0700 | [diff] [blame] | 73 | // The data must be zeroed to fix a valgrind error from the C loop filter |
| 74 | // due to access uninitialized memory in frame border. It could be |
| 75 | // skipped if border were totally removed. |
| 76 | int_fb_list->int_fb[i].data = (uint8_t *)aom_calloc(1, min_size); |
Wan-Teh Chang | 2ab147d | 2018-10-02 16:06:26 -0700 | [diff] [blame] | 77 | if (!int_fb_list->int_fb[i].data) { |
| 78 | int_fb_list->int_fb[i].size = 0; |
| 79 | return -1; |
| 80 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 81 | int_fb_list->int_fb[i].size = min_size; |
| 82 | } |
| 83 | |
| 84 | fb->data = int_fb_list->int_fb[i].data; |
| 85 | fb->size = int_fb_list->int_fb[i].size; |
| 86 | int_fb_list->int_fb[i].in_use = 1; |
| 87 | |
| 88 | // Set the frame buffer's private data to point at the internal frame buffer. |
| 89 | fb->priv = &int_fb_list->int_fb[i]; |
| 90 | return 0; |
| 91 | } |
| 92 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 93 | int av1_release_frame_buffer(void *cb_priv, aom_codec_frame_buffer_t *fb) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 94 | InternalFrameBuffer *const int_fb = (InternalFrameBuffer *)fb->priv; |
| 95 | (void)cb_priv; |
| 96 | if (int_fb) int_fb->in_use = 0; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 97 | return 0; |
| 98 | } |