vp9_alloccommon.c 6.59 KB
Newer Older
John Koleszar's avatar
John Koleszar committed
1
/*
2
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
John Koleszar's avatar
John Koleszar committed
3
 *
4
 *  Use of this source code is governed by a BSD-style license
5 6
 *  that can be found in the LICENSE file in the root of the source
 *  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.
John Koleszar's avatar
John Koleszar committed
9 10 11
 */


12
#include "./vpx_config.h"
John Koleszar's avatar
John Koleszar committed
13
#include "vpx_mem/vpx_mem.h"
14

15
#include "vp9/common/vp9_blockd.h"
16 17
#include "vp9/common/vp9_entropymode.h"
#include "vp9/common/vp9_entropymv.h"
18
#include "vp9/common/vp9_onyxc_int.h"
19
#include "vp9/common/vp9_systemdependent.h"
John Koleszar's avatar
John Koleszar committed
20

21 22
void vp9_update_mode_info_border(VP9_COMMON *cm, MODE_INFO *mi) {
  const int stride = cm->mode_info_stride;
John Koleszar's avatar
John Koleszar committed
23 24 25
  int i;

  // Clear down top border row
Dmitry Kovalev's avatar
Dmitry Kovalev committed
26
  vpx_memset(mi, 0, sizeof(MODE_INFO) * stride);
John Koleszar's avatar
John Koleszar committed
27 28

  // Clear left border column
29
  for (i = 1; i < cm->mi_rows + 1; i++)
Dmitry Kovalev's avatar
Dmitry Kovalev committed
30
    vpx_memset(&mi[i * stride], 0, sizeof(MODE_INFO));
31
}
32

33
void vp9_free_frame_buffers(VP9_COMMON *cm) {
John Koleszar's avatar
John Koleszar committed
34
  int i;
35

36
  for (i = 0; i < cm->fb_count; i++)
37
    vp9_free_frame_buffer(&cm->yv12_fb[i]);
38

39
  vp9_free_frame_buffer(&cm->post_proc_buffer);
John Koleszar's avatar
John Koleszar committed
40

41 42 43
  vpx_free(cm->mip);
  vpx_free(cm->prev_mip);
  vpx_free(cm->last_frame_seg_map);
44 45
  vpx_free(cm->mi_grid_base);
  vpx_free(cm->prev_mi_grid_base);
John Koleszar's avatar
John Koleszar committed
46

47 48 49
  cm->mip = NULL;
  cm->prev_mip = NULL;
  cm->last_frame_seg_map = NULL;
50 51
  cm->mi_grid_base = NULL;
  cm->prev_mi_grid_base = NULL;
John Koleszar's avatar
John Koleszar committed
52 53
}

54
static void set_mb_mi(VP9_COMMON *cm, int aligned_width, int aligned_height) {
James Zern's avatar
James Zern committed
55 56
  cm->mi_cols = aligned_width >> MI_SIZE_LOG2;
  cm->mi_rows = aligned_height >> MI_SIZE_LOG2;
57
  cm->mode_info_stride = cm->mi_cols + MI_BLOCK_SIZE;
58 59 60 61

  cm->mb_cols = (cm->mi_cols + 1) >> 1;
  cm->mb_rows = (cm->mi_rows + 1) >> 1;
  cm->MBs = cm->mb_rows * cm->mb_cols;
62 63 64 65 66
}

static void setup_mi(VP9_COMMON *cm) {
  cm->mi = cm->mip + cm->mode_info_stride + 1;
  cm->prev_mi = cm->prev_mip + cm->mode_info_stride + 1;
67 68
  cm->mi_grid_visible = cm->mi_grid_base + cm->mode_info_stride + 1;
  cm->prev_mi_grid_visible = cm->prev_mi_grid_base + cm->mode_info_stride + 1;
69 70 71 72

  vpx_memset(cm->mip, 0,
             cm->mode_info_stride * (cm->mi_rows + 1) * sizeof(MODE_INFO));

73 74 75
  vpx_memset(cm->mi_grid_base, 0,
             cm->mode_info_stride * (cm->mi_rows + 1) *
             sizeof(*cm->mi_grid_base));
76

77 78 79
  vp9_update_mode_info_border(cm, cm->prev_mip);
}

80 81 82 83 84 85 86 87
int vp9_resize_frame_buffers(VP9_COMMON *cm, int width, int height) {
  const int aligned_width = ALIGN_POWER_OF_TWO(width, MI_SIZE_LOG2);
  const int aligned_height = ALIGN_POWER_OF_TWO(height, MI_SIZE_LOG2);
  const int ss_x = cm->subsampling_x;
  const int ss_y = cm->subsampling_y;
  int mi_size;

  if (vp9_realloc_frame_buffer(&cm->post_proc_buffer, width, height, ss_x, ss_y,
88
                               VP9BORDERINPIXELS, NULL, NULL, NULL) < 0)
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
    goto fail;

  set_mb_mi(cm, aligned_width, aligned_height);

  // Allocation
  mi_size = cm->mode_info_stride * (cm->mi_rows + MI_BLOCK_SIZE);

  vpx_free(cm->mip);
  cm->mip = vpx_calloc(mi_size, sizeof(MODE_INFO));
  if (!cm->mip)
    goto fail;

  vpx_free(cm->prev_mip);
  cm->prev_mip = vpx_calloc(mi_size, sizeof(MODE_INFO));
  if (!cm->prev_mip)
    goto fail;

  vpx_free(cm->mi_grid_base);
  cm->mi_grid_base = vpx_calloc(mi_size, sizeof(*cm->mi_grid_base));
  if (!cm->mi_grid_base)
    goto fail;

  vpx_free(cm->prev_mi_grid_base);
  cm->prev_mi_grid_base = vpx_calloc(mi_size, sizeof(*cm->prev_mi_grid_base));
  if (!cm->prev_mi_grid_base)
    goto fail;

  setup_mi(cm);

  // Create the segmentation map structure and set to 0.
  vpx_free(cm->last_frame_seg_map);
  cm->last_frame_seg_map = vpx_calloc(cm->mi_rows * cm->mi_cols, 1);
  if (!cm->last_frame_seg_map)
    goto fail;

  return 0;

 fail:
  vp9_free_frame_buffers(cm);
  return 1;
}

131
int vp9_alloc_frame_buffers(VP9_COMMON *cm, int width, int height) {
132
  int i;
133

James Zern's avatar
James Zern committed
134 135
  const int aligned_width = ALIGN_POWER_OF_TWO(width, MI_SIZE_LOG2);
  const int aligned_height = ALIGN_POWER_OF_TWO(height, MI_SIZE_LOG2);
136 137
  const int ss_x = cm->subsampling_x;
  const int ss_y = cm->subsampling_y;
138
  int mi_size;
John Koleszar's avatar
John Koleszar committed
139

140 141 142 143 144 145
  if (cm->fb_count == 0) {
    cm->fb_count = FRAME_BUFFERS;
    CHECK_MEM_ERROR(cm, cm->yv12_fb,
                    vpx_calloc(cm->fb_count, sizeof(*cm->yv12_fb)));
    CHECK_MEM_ERROR(cm, cm->fb_idx_ref_cnt,
                    vpx_calloc(cm->fb_count, sizeof(*cm->fb_idx_ref_cnt)));
Frank Galligan's avatar
Frank Galligan committed
146 147 148 149
    if (cm->fb_lru) {
      CHECK_MEM_ERROR(cm, cm->fb_idx_ref_lru,
                      vpx_calloc(cm->fb_count, sizeof(*cm->fb_idx_ref_lru)));
    }
150 151
  }

152
  vp9_free_frame_buffers(cm);
John Koleszar's avatar
John Koleszar committed
153

154
  for (i = 0; i < cm->fb_count; i++) {
155 156
    cm->fb_idx_ref_cnt[i] = 0;
    if (vp9_alloc_frame_buffer(&cm->yv12_fb[i], width, height, ss_x, ss_y,
157 158
                               VP9BORDERINPIXELS) < 0)
      goto fail;
John Koleszar's avatar
John Koleszar committed
159
  }
John Koleszar's avatar
John Koleszar committed
160

161
  cm->new_fb_idx = cm->fb_count - 1;
162
  cm->fb_idx_ref_cnt[cm->new_fb_idx] = 1;
163

Dmitry Kovalev's avatar
Dmitry Kovalev committed
164
  for (i = 0; i < REF_FRAMES; i++) {
165 166
    cm->ref_frame_map[i] = i;
    cm->fb_idx_ref_cnt[i] = 1;
167
  }
John Koleszar's avatar
John Koleszar committed
168

169
  if (vp9_alloc_frame_buffer(&cm->post_proc_buffer, width, height, ss_x, ss_y,
170 171 172
                             VP9BORDERINPIXELS) < 0)
    goto fail;

173
  set_mb_mi(cm, aligned_width, aligned_height);
John Koleszar's avatar
John Koleszar committed
174

175
  // Allocation
176
  mi_size = cm->mode_info_stride * (cm->mi_rows + MI_BLOCK_SIZE);
177

178 179
  cm->mip = vpx_calloc(mi_size, sizeof(MODE_INFO));
  if (!cm->mip)
180
    goto fail;
Paul Wilkins's avatar
Paul Wilkins committed
181

182 183
  cm->prev_mip = vpx_calloc(mi_size, sizeof(MODE_INFO));
  if (!cm->prev_mip)
184
    goto fail;
185

186 187 188 189 190 191 192 193
  cm->mi_grid_base = vpx_calloc(mi_size, sizeof(*cm->mi_grid_base));
  if (!cm->mi_grid_base)
    goto fail;

  cm->prev_mi_grid_base = vpx_calloc(mi_size, sizeof(*cm->prev_mi_grid_base));
  if (!cm->prev_mi_grid_base)
    goto fail;

194
  setup_mi(cm);
John Koleszar's avatar
John Koleszar committed
195

196
  // Create the segmentation map structure and set to 0.
197 198
  cm->last_frame_seg_map = vpx_calloc(cm->mi_rows * cm->mi_cols, 1);
  if (!cm->last_frame_seg_map)
199 200
    goto fail;

John Koleszar's avatar
John Koleszar committed
201
  return 0;
202 203

 fail:
204
  vp9_free_frame_buffers(cm);
205
  return 1;
John Koleszar's avatar
John Koleszar committed
206
}
207

208 209
void vp9_create_common(VP9_COMMON *cm) {
  vp9_machine_specific_config(cm);
John Koleszar's avatar
John Koleszar committed
210 211
}

212 213
void vp9_remove_common(VP9_COMMON *cm) {
  vp9_free_frame_buffers(cm);
214 215 216

  vpx_free(cm->yv12_fb);
  vpx_free(cm->fb_idx_ref_cnt);
Frank Galligan's avatar
Frank Galligan committed
217
  vpx_free(cm->fb_idx_ref_lru);
218 219 220

  cm->yv12_fb = NULL;
  cm->fb_idx_ref_cnt = NULL;
Frank Galligan's avatar
Frank Galligan committed
221
  cm->fb_idx_ref_lru = NULL;
John Koleszar's avatar
John Koleszar committed
222 223
}

224
void vp9_initialize_common() {
225
  vp9_init_neighbors();
John Koleszar's avatar
John Koleszar committed
226
}
227 228

void vp9_update_frame_size(VP9_COMMON *cm) {
James Zern's avatar
James Zern committed
229 230
  const int aligned_width = ALIGN_POWER_OF_TWO(cm->width, MI_SIZE_LOG2);
  const int aligned_height = ALIGN_POWER_OF_TWO(cm->height, MI_SIZE_LOG2);
231

232 233
  set_mb_mi(cm, aligned_width, aligned_height);
  setup_mi(cm);
John Koleszar's avatar
John Koleszar committed
234

235 236 237
  // Initialize the previous frame segment map to 0.
  if (cm->last_frame_seg_map)
    vpx_memset(cm->last_frame_seg_map, 0, cm->mi_rows * cm->mi_cols);
238
}