1 /*
2 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
3 *
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.
10 */
11
12 #include <assert.h>
13
14 #include "av1/common/frame_buffers.h"
15 #include "aom_mem/aom_mem.h"
16
av1_alloc_internal_frame_buffers(InternalFrameBufferList * list)17 int av1_alloc_internal_frame_buffers(InternalFrameBufferList *list) {
18 assert(list != NULL);
19 av1_free_internal_frame_buffers(list);
20
21 list->num_internal_frame_buffers =
22 AOM_MAXIMUM_REF_BUFFERS + AOM_MAXIMUM_WORK_BUFFERS;
23 list->int_fb = (InternalFrameBuffer *)aom_calloc(
24 list->num_internal_frame_buffers, sizeof(*list->int_fb));
25 if (list->int_fb == NULL) {
26 list->num_internal_frame_buffers = 0;
27 return 1;
28 }
29 return 0;
30 }
31
av1_free_internal_frame_buffers(InternalFrameBufferList * list)32 void av1_free_internal_frame_buffers(InternalFrameBufferList *list) {
33 int i;
34
35 assert(list != NULL);
36
37 for (i = 0; i < list->num_internal_frame_buffers; ++i) {
38 aom_free(list->int_fb[i].data);
39 list->int_fb[i].data = NULL;
40 }
41 aom_free(list->int_fb);
42 list->int_fb = NULL;
43 list->num_internal_frame_buffers = 0;
44 }
45
av1_zero_unused_internal_frame_buffers(InternalFrameBufferList * list)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
av1_get_frame_buffer(void * cb_priv,size_t min_size,aom_codec_frame_buffer_t * fb)57 int av1_get_frame_buffer(void *cb_priv, size_t min_size,
58 aom_codec_frame_buffer_t *fb) {
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) {
72 aom_free(int_fb_list->int_fb[i].data);
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);
77 if (!int_fb_list->int_fb[i].data) {
78 int_fb_list->int_fb[i].size = 0;
79 return -1;
80 }
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
av1_release_frame_buffer(void * cb_priv,aom_codec_frame_buffer_t * fb)93 int av1_release_frame_buffer(void *cb_priv, aom_codec_frame_buffer_t *fb) {
94 InternalFrameBuffer *const int_fb = (InternalFrameBuffer *)fb->priv;
95 (void)cb_priv;
96 if (int_fb) int_fb->in_use = 0;
97 return 0;
98 }
99