1 /* 2 * Copyright (c) 2010 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 12 #include "./vpx_config.h" 13 #include "vpx_mem/vpx_mem.h" 14 15 #include "vp9/common/vp9_blockd.h" 16 #include "vp9/common/vp9_entropymode.h" 17 #include "vp9/common/vp9_entropymv.h" 18 #include "vp9/common/vp9_findnearmv.h" 19 #include "vp9/common/vp9_onyxc_int.h" 20 #include "vp9/common/vp9_systemdependent.h" 21 22 void vp9_update_mode_info_border(VP9_COMMON *cm, MODE_INFO *mi) { 23 const int stride = cm->mode_info_stride; 24 int i; 25 26 // Clear down top border row 27 vpx_memset(mi, 0, sizeof(MODE_INFO) * stride); 28 29 // Clear left border column 30 for (i = 1; i < cm->mi_rows + 1; i++) 31 vpx_memset(&mi[i * stride], 0, sizeof(MODE_INFO)); 32 } 33 34 void vp9_free_frame_buffers(VP9_COMMON *cm) { 35 int i; 36 37 for (i = 0; i < NUM_YV12_BUFFERS; i++) 38 vp9_free_frame_buffer(&cm->yv12_fb[i]); 39 40 vp9_free_frame_buffer(&cm->post_proc_buffer); 41 42 vpx_free(cm->mip); 43 vpx_free(cm->prev_mip); 44 vpx_free(cm->above_seg_context); 45 vpx_free(cm->last_frame_seg_map); 46 vpx_free(cm->mi_grid_base); 47 vpx_free(cm->prev_mi_grid_base); 48 49 vpx_free(cm->above_context[0]); 50 for (i = 0; i < MAX_MB_PLANE; i++) 51 cm->above_context[i] = 0; 52 cm->mip = NULL; 53 cm->prev_mip = NULL; 54 cm->above_seg_context = NULL; 55 cm->last_frame_seg_map = NULL; 56 cm->mi_grid_base = NULL; 57 cm->prev_mi_grid_base = NULL; 58 } 59 60 static void set_mb_mi(VP9_COMMON *cm, int aligned_width, int aligned_height) { 61 cm->mb_cols = (aligned_width + 8) >> 4; 62 cm->mb_rows = (aligned_height + 8) >> 4; 63 cm->MBs = cm->mb_rows * cm->mb_cols; 64 65 cm->mi_cols = aligned_width >> MI_SIZE_LOG2; 66 cm->mi_rows = aligned_height >> MI_SIZE_LOG2; 67 cm->mode_info_stride = cm->mi_cols + MI_BLOCK_SIZE; 68 } 69 70 static void setup_mi(VP9_COMMON *cm) { 71 cm->mi = cm->mip + cm->mode_info_stride + 1; 72 cm->prev_mi = cm->prev_mip + cm->mode_info_stride + 1; 73 cm->mi_grid_visible = cm->mi_grid_base + cm->mode_info_stride + 1; 74 cm->prev_mi_grid_visible = cm->prev_mi_grid_base + cm->mode_info_stride + 1; 75 76 vpx_memset(cm->mip, 0, 77 cm->mode_info_stride * (cm->mi_rows + 1) * sizeof(MODE_INFO)); 78 79 vpx_memset(cm->mi_grid_base, 0, 80 cm->mode_info_stride * (cm->mi_rows + 1) * 81 sizeof(*cm->mi_grid_base)); 82 83 vp9_update_mode_info_border(cm, cm->mip); 84 vp9_update_mode_info_border(cm, cm->prev_mip); 85 } 86 87 int vp9_alloc_frame_buffers(VP9_COMMON *cm, int width, int height) { 88 int i, mi_cols; 89 90 const int aligned_width = ALIGN_POWER_OF_TWO(width, MI_SIZE_LOG2); 91 const int aligned_height = ALIGN_POWER_OF_TWO(height, MI_SIZE_LOG2); 92 const int ss_x = cm->subsampling_x; 93 const int ss_y = cm->subsampling_y; 94 int mi_size; 95 96 vp9_free_frame_buffers(cm); 97 98 for (i = 0; i < NUM_YV12_BUFFERS; i++) { 99 cm->fb_idx_ref_cnt[i] = 0; 100 if (vp9_alloc_frame_buffer(&cm->yv12_fb[i], width, height, ss_x, ss_y, 101 VP9BORDERINPIXELS) < 0) 102 goto fail; 103 } 104 105 cm->new_fb_idx = NUM_YV12_BUFFERS - 1; 106 cm->fb_idx_ref_cnt[cm->new_fb_idx] = 1; 107 108 for (i = 0; i < ALLOWED_REFS_PER_FRAME; i++) 109 cm->active_ref_idx[i] = i; 110 111 for (i = 0; i < NUM_REF_FRAMES; i++) { 112 cm->ref_frame_map[i] = i; 113 cm->fb_idx_ref_cnt[i] = 1; 114 } 115 116 if (vp9_alloc_frame_buffer(&cm->post_proc_buffer, width, height, ss_x, ss_y, 117 VP9BORDERINPIXELS) < 0) 118 goto fail; 119 120 set_mb_mi(cm, aligned_width, aligned_height); 121 122 // Allocation 123 mi_size = cm->mode_info_stride * (cm->mi_rows + MI_BLOCK_SIZE); 124 125 cm->mip = vpx_calloc(mi_size, sizeof(MODE_INFO)); 126 if (!cm->mip) 127 goto fail; 128 129 cm->prev_mip = vpx_calloc(mi_size, sizeof(MODE_INFO)); 130 if (!cm->prev_mip) 131 goto fail; 132 133 cm->mi_grid_base = vpx_calloc(mi_size, sizeof(*cm->mi_grid_base)); 134 if (!cm->mi_grid_base) 135 goto fail; 136 137 cm->prev_mi_grid_base = vpx_calloc(mi_size, sizeof(*cm->prev_mi_grid_base)); 138 if (!cm->prev_mi_grid_base) 139 goto fail; 140 141 setup_mi(cm); 142 143 // FIXME(jkoleszar): allocate subsampled arrays for U/V once subsampling 144 // information is exposed at this level 145 mi_cols = mi_cols_aligned_to_sb(cm->mi_cols); 146 147 // 2 contexts per 'mi unit', so that we have one context per 4x4 txfm 148 // block where mi unit size is 8x8. 149 cm->above_context[0] = vpx_calloc(sizeof(ENTROPY_CONTEXT) * MAX_MB_PLANE * 150 (2 * mi_cols), 1); 151 if (!cm->above_context[0]) 152 goto fail; 153 154 cm->above_seg_context = vpx_calloc(sizeof(PARTITION_CONTEXT) * mi_cols, 1); 155 if (!cm->above_seg_context) 156 goto fail; 157 158 // Create the segmentation map structure and set to 0. 159 cm->last_frame_seg_map = vpx_calloc(cm->mi_rows * cm->mi_cols, 1); 160 if (!cm->last_frame_seg_map) 161 goto fail; 162 163 return 0; 164 165 fail: 166 vp9_free_frame_buffers(cm); 167 return 1; 168 } 169 170 void vp9_create_common(VP9_COMMON *cm) { 171 vp9_machine_specific_config(cm); 172 173 vp9_init_mbmode_probs(cm); 174 175 cm->tx_mode = ONLY_4X4; 176 cm->comp_pred_mode = HYBRID_PREDICTION; 177 178 // Initialize reference frame sign bias structure to defaults 179 vpx_memset(cm->ref_frame_sign_bias, 0, sizeof(cm->ref_frame_sign_bias)); 180 } 181 182 void vp9_remove_common(VP9_COMMON *cm) { 183 vp9_free_frame_buffers(cm); 184 } 185 186 void vp9_initialize_common() { 187 vp9_coef_tree_initialize(); 188 vp9_entropy_mode_init(); 189 vp9_entropy_mv_init(); 190 } 191 192 void vp9_update_frame_size(VP9_COMMON *cm) { 193 int i, mi_cols; 194 const int aligned_width = ALIGN_POWER_OF_TWO(cm->width, MI_SIZE_LOG2); 195 const int aligned_height = ALIGN_POWER_OF_TWO(cm->height, MI_SIZE_LOG2); 196 197 set_mb_mi(cm, aligned_width, aligned_height); 198 setup_mi(cm); 199 200 mi_cols = mi_cols_aligned_to_sb(cm->mi_cols); 201 for (i = 1; i < MAX_MB_PLANE; i++) 202 cm->above_context[i] = 203 cm->above_context[0] + i * sizeof(ENTROPY_CONTEXT) * 2 * mi_cols; 204 205 // Initialize the previous frame segment map to 0. 206 if (cm->last_frame_seg_map) 207 vpx_memset(cm->last_frame_seg_map, 0, cm->mi_rows * cm->mi_cols); 208 } 209