1/*
2 *  Copyright (c) 2014 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#include <assert.h>
12
13#include "vp9/common/vp9_frame_buffers.h"
14#include "vpx_mem/vpx_mem.h"
15
16int vp9_alloc_internal_frame_buffers(InternalFrameBufferList *list) {
17  assert(list != NULL);
18  vp9_free_internal_frame_buffers(list);
19
20  list->num_internal_frame_buffers =
21      VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS;
22  list->int_fb =
23      (InternalFrameBuffer *)vpx_calloc(list->num_internal_frame_buffers,
24                                        sizeof(*list->int_fb));
25  return (list->int_fb == NULL);
26}
27
28void vp9_free_internal_frame_buffers(InternalFrameBufferList *list) {
29  int i;
30
31  assert(list != NULL);
32
33  for (i = 0; i < list->num_internal_frame_buffers; ++i) {
34    vpx_free(list->int_fb[i].data);
35    list->int_fb[i].data = NULL;
36  }
37  vpx_free(list->int_fb);
38  list->int_fb = NULL;
39}
40
41int vp9_get_frame_buffer(void *cb_priv, size_t min_size,
42                         vpx_codec_frame_buffer_t *fb) {
43  int i;
44  InternalFrameBufferList *const int_fb_list =
45      (InternalFrameBufferList *)cb_priv;
46  if (int_fb_list == NULL)
47    return -1;
48
49  // Find a free frame buffer.
50  for (i = 0; i < int_fb_list->num_internal_frame_buffers; ++i) {
51    if (!int_fb_list->int_fb[i].in_use)
52      break;
53  }
54
55  if (i == int_fb_list->num_internal_frame_buffers)
56    return -1;
57
58  if (int_fb_list->int_fb[i].size < min_size) {
59    int_fb_list->int_fb[i].data =
60        (uint8_t *)vpx_realloc(int_fb_list->int_fb[i].data, min_size);
61    if (!int_fb_list->int_fb[i].data)
62      return -1;
63
64    int_fb_list->int_fb[i].size = min_size;
65  }
66
67  fb->data = int_fb_list->int_fb[i].data;
68  fb->size = int_fb_list->int_fb[i].size;
69  int_fb_list->int_fb[i].in_use = 1;
70
71  // Set the frame buffer's private data to point at the internal frame buffer.
72  fb->priv = &int_fb_list->int_fb[i];
73  return 0;
74}
75
76int vp9_release_frame_buffer(void *cb_priv, vpx_codec_frame_buffer_t *fb) {
77  InternalFrameBuffer *const int_fb = (InternalFrameBuffer *)fb->priv;
78  (void)cb_priv;
79  int_fb->in_use = 0;
80  return 0;
81}
82