vp9_alloccommon.c 6.49 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 19
#include "vp9/common/vp9_findnearmv.h"
#include "vp9/common/vp9_onyxc_int.h"
20
#include "vp9/common/vp9_systemdependent.h"
John Koleszar's avatar
John Koleszar committed
21

22 23
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
24 25 26
  int i;

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

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

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

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

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

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

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

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

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

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;
68 69
  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;
70 71 72 73

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

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

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

81 82 83 84 85 86 87 88
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,
89
                               VP9BORDERINPIXELS, NULL, NULL, NULL) < 0)
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 131
    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;
}

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

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

141 142 143 144 145 146 147 148
  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)));
  }

149
  vp9_free_frame_buffers(cm);
John Koleszar's avatar
John Koleszar committed
150

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

158
  cm->new_fb_idx = cm->fb_count - 1;
159
  cm->fb_idx_ref_cnt[cm->new_fb_idx] = 1;
160

Dmitry Kovalev's avatar
Dmitry Kovalev committed
161
  for (i = 0; i < REFS_PER_FRAME; i++)
162
    cm->active_ref_idx[i] = i;
John Koleszar's avatar
John Koleszar committed
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 217 218 219

  vpx_free(cm->yv12_fb);
  vpx_free(cm->fb_idx_ref_cnt);

  cm->yv12_fb = NULL;
  cm->fb_idx_ref_cnt = NULL;
John Koleszar's avatar
John Koleszar committed
220 221
}

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

void vp9_update_frame_size(VP9_COMMON *cm) {
James Zern's avatar
James Zern committed
227 228
  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);
229

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

233 234 235
  // 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);
236
}