1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/media/libvpx/vp9/common/vp9_reconintra.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,385 @@ 1.4 +/* 1.5 + * Copyright (c) 2010 The WebM project authors. All Rights Reserved. 1.6 + * 1.7 + * Use of this source code is governed by a BSD-style license 1.8 + * that can be found in the LICENSE file in the root of the source 1.9 + * tree. An additional intellectual property rights grant can be found 1.10 + * in the file PATENTS. All contributing project authors may 1.11 + * be found in the AUTHORS file in the root of the source tree. 1.12 + */ 1.13 + 1.14 +#include "./vpx_config.h" 1.15 + 1.16 +#include "vpx_mem/vpx_mem.h" 1.17 +#include "vpx_ports/vpx_once.h" 1.18 + 1.19 +#include "./vp9_rtcd.h" 1.20 + 1.21 +#include "vp9/common/vp9_reconintra.h" 1.22 +#include "vp9/common/vp9_onyxc_int.h" 1.23 + 1.24 +const TX_TYPE mode2txfm_map[MB_MODE_COUNT] = { 1.25 + DCT_DCT, // DC 1.26 + ADST_DCT, // V 1.27 + DCT_ADST, // H 1.28 + DCT_DCT, // D45 1.29 + ADST_ADST, // D135 1.30 + ADST_DCT, // D117 1.31 + DCT_ADST, // D153 1.32 + DCT_ADST, // D207 1.33 + ADST_DCT, // D63 1.34 + ADST_ADST, // TM 1.35 + DCT_DCT, // NEARESTMV 1.36 + DCT_DCT, // NEARMV 1.37 + DCT_DCT, // ZEROMV 1.38 + DCT_DCT // NEWMV 1.39 +}; 1.40 + 1.41 +#define intra_pred_sized(type, size) \ 1.42 + void vp9_##type##_predictor_##size##x##size##_c(uint8_t *dst, \ 1.43 + ptrdiff_t stride, \ 1.44 + const uint8_t *above, \ 1.45 + const uint8_t *left) { \ 1.46 + type##_predictor(dst, stride, size, above, left); \ 1.47 + } 1.48 + 1.49 +#define intra_pred_allsizes(type) \ 1.50 + intra_pred_sized(type, 4) \ 1.51 + intra_pred_sized(type, 8) \ 1.52 + intra_pred_sized(type, 16) \ 1.53 + intra_pred_sized(type, 32) 1.54 + 1.55 +static INLINE void d207_predictor(uint8_t *dst, ptrdiff_t stride, int bs, 1.56 + const uint8_t *above, const uint8_t *left) { 1.57 + int r, c; 1.58 + 1.59 + // first column 1.60 + for (r = 0; r < bs - 1; ++r) 1.61 + dst[r * stride] = ROUND_POWER_OF_TWO(left[r] + left[r + 1], 1); 1.62 + dst[(bs - 1) * stride] = left[bs - 1]; 1.63 + dst++; 1.64 + 1.65 + // second column 1.66 + for (r = 0; r < bs - 2; ++r) 1.67 + dst[r * stride] = ROUND_POWER_OF_TWO(left[r] + left[r + 1] * 2 + 1.68 + left[r + 2], 2); 1.69 + dst[(bs - 2) * stride] = ROUND_POWER_OF_TWO(left[bs - 2] + 1.70 + left[bs - 1] * 3, 2); 1.71 + dst[(bs - 1) * stride] = left[bs - 1]; 1.72 + dst++; 1.73 + 1.74 + // rest of last row 1.75 + for (c = 0; c < bs - 2; ++c) 1.76 + dst[(bs - 1) * stride + c] = left[bs - 1]; 1.77 + 1.78 + for (r = bs - 2; r >= 0; --r) 1.79 + for (c = 0; c < bs - 2; ++c) 1.80 + dst[r * stride + c] = dst[(r + 1) * stride + c - 2]; 1.81 +} 1.82 +intra_pred_allsizes(d207) 1.83 + 1.84 +static INLINE void d63_predictor(uint8_t *dst, ptrdiff_t stride, int bs, 1.85 + const uint8_t *above, const uint8_t *left) { 1.86 + int r, c; 1.87 + for (r = 0; r < bs; ++r) { 1.88 + for (c = 0; c < bs; ++c) 1.89 + dst[c] = r & 1 ? ROUND_POWER_OF_TWO(above[r/2 + c] + 1.90 + above[r/2 + c + 1] * 2 + 1.91 + above[r/2 + c + 2], 2) 1.92 + : ROUND_POWER_OF_TWO(above[r/2 + c] + 1.93 + above[r/2 + c + 1], 1); 1.94 + dst += stride; 1.95 + } 1.96 +} 1.97 +intra_pred_allsizes(d63) 1.98 + 1.99 +static INLINE void d45_predictor(uint8_t *dst, ptrdiff_t stride, int bs, 1.100 + const uint8_t *above, const uint8_t *left) { 1.101 + int r, c; 1.102 + for (r = 0; r < bs; ++r) { 1.103 + for (c = 0; c < bs; ++c) 1.104 + dst[c] = r + c + 2 < bs * 2 ? ROUND_POWER_OF_TWO(above[r + c] + 1.105 + above[r + c + 1] * 2 + 1.106 + above[r + c + 2], 2) 1.107 + : above[bs * 2 - 1]; 1.108 + dst += stride; 1.109 + } 1.110 +} 1.111 +intra_pred_allsizes(d45) 1.112 + 1.113 +static INLINE void d117_predictor(uint8_t *dst, ptrdiff_t stride, int bs, 1.114 + const uint8_t *above, const uint8_t *left) { 1.115 + int r, c; 1.116 + 1.117 + // first row 1.118 + for (c = 0; c < bs; c++) 1.119 + dst[c] = ROUND_POWER_OF_TWO(above[c - 1] + above[c], 1); 1.120 + dst += stride; 1.121 + 1.122 + // second row 1.123 + dst[0] = ROUND_POWER_OF_TWO(left[0] + above[-1] * 2 + above[0], 2); 1.124 + for (c = 1; c < bs; c++) 1.125 + dst[c] = ROUND_POWER_OF_TWO(above[c - 2] + above[c - 1] * 2 + above[c], 2); 1.126 + dst += stride; 1.127 + 1.128 + // the rest of first col 1.129 + dst[0] = ROUND_POWER_OF_TWO(above[-1] + left[0] * 2 + left[1], 2); 1.130 + for (r = 3; r < bs; ++r) 1.131 + dst[(r - 2) * stride] = ROUND_POWER_OF_TWO(left[r - 3] + left[r - 2] * 2 + 1.132 + left[r - 1], 2); 1.133 + 1.134 + // the rest of the block 1.135 + for (r = 2; r < bs; ++r) { 1.136 + for (c = 1; c < bs; c++) 1.137 + dst[c] = dst[-2 * stride + c - 1]; 1.138 + dst += stride; 1.139 + } 1.140 +} 1.141 +intra_pred_allsizes(d117) 1.142 + 1.143 +static INLINE void d135_predictor(uint8_t *dst, ptrdiff_t stride, int bs, 1.144 + const uint8_t *above, const uint8_t *left) { 1.145 + int r, c; 1.146 + dst[0] = ROUND_POWER_OF_TWO(left[0] + above[-1] * 2 + above[0], 2); 1.147 + for (c = 1; c < bs; c++) 1.148 + dst[c] = ROUND_POWER_OF_TWO(above[c - 2] + above[c - 1] * 2 + above[c], 2); 1.149 + 1.150 + dst[stride] = ROUND_POWER_OF_TWO(above[-1] + left[0] * 2 + left[1], 2); 1.151 + for (r = 2; r < bs; ++r) 1.152 + dst[r * stride] = ROUND_POWER_OF_TWO(left[r - 2] + left[r - 1] * 2 + 1.153 + left[r], 2); 1.154 + 1.155 + dst += stride; 1.156 + for (r = 1; r < bs; ++r) { 1.157 + for (c = 1; c < bs; c++) 1.158 + dst[c] = dst[-stride + c - 1]; 1.159 + dst += stride; 1.160 + } 1.161 +} 1.162 +intra_pred_allsizes(d135) 1.163 + 1.164 +static INLINE void d153_predictor(uint8_t *dst, ptrdiff_t stride, int bs, 1.165 + const uint8_t *above, const uint8_t *left) { 1.166 + int r, c; 1.167 + dst[0] = ROUND_POWER_OF_TWO(above[-1] + left[0], 1); 1.168 + for (r = 1; r < bs; r++) 1.169 + dst[r * stride] = ROUND_POWER_OF_TWO(left[r - 1] + left[r], 1); 1.170 + dst++; 1.171 + 1.172 + dst[0] = ROUND_POWER_OF_TWO(left[0] + above[-1] * 2 + above[0], 2); 1.173 + dst[stride] = ROUND_POWER_OF_TWO(above[-1] + left[0] * 2 + left[1], 2); 1.174 + for (r = 2; r < bs; r++) 1.175 + dst[r * stride] = ROUND_POWER_OF_TWO(left[r - 2] + left[r - 1] * 2 + 1.176 + left[r], 2); 1.177 + dst++; 1.178 + 1.179 + for (c = 0; c < bs - 2; c++) 1.180 + dst[c] = ROUND_POWER_OF_TWO(above[c - 1] + above[c] * 2 + above[c + 1], 2); 1.181 + dst += stride; 1.182 + 1.183 + for (r = 1; r < bs; ++r) { 1.184 + for (c = 0; c < bs - 2; c++) 1.185 + dst[c] = dst[-stride + c - 2]; 1.186 + dst += stride; 1.187 + } 1.188 +} 1.189 +intra_pred_allsizes(d153) 1.190 + 1.191 +static INLINE void v_predictor(uint8_t *dst, ptrdiff_t stride, int bs, 1.192 + const uint8_t *above, const uint8_t *left) { 1.193 + int r; 1.194 + 1.195 + for (r = 0; r < bs; r++) { 1.196 + vpx_memcpy(dst, above, bs); 1.197 + dst += stride; 1.198 + } 1.199 +} 1.200 +intra_pred_allsizes(v) 1.201 + 1.202 +static INLINE void h_predictor(uint8_t *dst, ptrdiff_t stride, int bs, 1.203 + const uint8_t *above, const uint8_t *left) { 1.204 + int r; 1.205 + 1.206 + for (r = 0; r < bs; r++) { 1.207 + vpx_memset(dst, left[r], bs); 1.208 + dst += stride; 1.209 + } 1.210 +} 1.211 +intra_pred_allsizes(h) 1.212 + 1.213 +static INLINE void tm_predictor(uint8_t *dst, ptrdiff_t stride, int bs, 1.214 + const uint8_t *above, const uint8_t *left) { 1.215 + int r, c; 1.216 + int ytop_left = above[-1]; 1.217 + 1.218 + for (r = 0; r < bs; r++) { 1.219 + for (c = 0; c < bs; c++) 1.220 + dst[c] = clip_pixel(left[r] + above[c] - ytop_left); 1.221 + dst += stride; 1.222 + } 1.223 +} 1.224 +intra_pred_allsizes(tm) 1.225 + 1.226 +static INLINE void dc_128_predictor(uint8_t *dst, ptrdiff_t stride, int bs, 1.227 + const uint8_t *above, const uint8_t *left) { 1.228 + int r; 1.229 + 1.230 + for (r = 0; r < bs; r++) { 1.231 + vpx_memset(dst, 128, bs); 1.232 + dst += stride; 1.233 + } 1.234 +} 1.235 +intra_pred_allsizes(dc_128) 1.236 + 1.237 +static INLINE void dc_left_predictor(uint8_t *dst, ptrdiff_t stride, int bs, 1.238 + const uint8_t *above, 1.239 + const uint8_t *left) { 1.240 + int i, r, expected_dc, sum = 0; 1.241 + 1.242 + for (i = 0; i < bs; i++) 1.243 + sum += left[i]; 1.244 + expected_dc = (sum + (bs >> 1)) / bs; 1.245 + 1.246 + for (r = 0; r < bs; r++) { 1.247 + vpx_memset(dst, expected_dc, bs); 1.248 + dst += stride; 1.249 + } 1.250 +} 1.251 +intra_pred_allsizes(dc_left) 1.252 + 1.253 +static INLINE void dc_top_predictor(uint8_t *dst, ptrdiff_t stride, int bs, 1.254 + const uint8_t *above, const uint8_t *left) { 1.255 + int i, r, expected_dc, sum = 0; 1.256 + 1.257 + for (i = 0; i < bs; i++) 1.258 + sum += above[i]; 1.259 + expected_dc = (sum + (bs >> 1)) / bs; 1.260 + 1.261 + for (r = 0; r < bs; r++) { 1.262 + vpx_memset(dst, expected_dc, bs); 1.263 + dst += stride; 1.264 + } 1.265 +} 1.266 +intra_pred_allsizes(dc_top) 1.267 + 1.268 +static INLINE void dc_predictor(uint8_t *dst, ptrdiff_t stride, int bs, 1.269 + const uint8_t *above, const uint8_t *left) { 1.270 + int i, r, expected_dc, sum = 0; 1.271 + const int count = 2 * bs; 1.272 + 1.273 + for (i = 0; i < bs; i++) { 1.274 + sum += above[i]; 1.275 + sum += left[i]; 1.276 + } 1.277 + 1.278 + expected_dc = (sum + (count >> 1)) / count; 1.279 + 1.280 + for (r = 0; r < bs; r++) { 1.281 + vpx_memset(dst, expected_dc, bs); 1.282 + dst += stride; 1.283 + } 1.284 +} 1.285 +intra_pred_allsizes(dc) 1.286 +#undef intra_pred_allsizes 1.287 + 1.288 +typedef void (*intra_pred_fn)(uint8_t *dst, ptrdiff_t stride, 1.289 + const uint8_t *above, const uint8_t *left); 1.290 + 1.291 +static intra_pred_fn pred[INTRA_MODES][4]; 1.292 +static intra_pred_fn dc_pred[2][2][4]; 1.293 + 1.294 +static void init_intra_pred_fn_ptrs(void) { 1.295 +#define intra_pred_allsizes(l, type) \ 1.296 + l[0] = vp9_##type##_predictor_4x4; \ 1.297 + l[1] = vp9_##type##_predictor_8x8; \ 1.298 + l[2] = vp9_##type##_predictor_16x16; \ 1.299 + l[3] = vp9_##type##_predictor_32x32 1.300 + 1.301 + intra_pred_allsizes(pred[V_PRED], v); 1.302 + intra_pred_allsizes(pred[H_PRED], h); 1.303 + intra_pred_allsizes(pred[D207_PRED], d207); 1.304 + intra_pred_allsizes(pred[D45_PRED], d45); 1.305 + intra_pred_allsizes(pred[D63_PRED], d63); 1.306 + intra_pred_allsizes(pred[D117_PRED], d117); 1.307 + intra_pred_allsizes(pred[D135_PRED], d135); 1.308 + intra_pred_allsizes(pred[D153_PRED], d153); 1.309 + intra_pred_allsizes(pred[TM_PRED], tm); 1.310 + 1.311 + intra_pred_allsizes(dc_pred[0][0], dc_128); 1.312 + intra_pred_allsizes(dc_pred[0][1], dc_top); 1.313 + intra_pred_allsizes(dc_pred[1][0], dc_left); 1.314 + intra_pred_allsizes(dc_pred[1][1], dc); 1.315 + 1.316 +#undef intra_pred_allsizes 1.317 +} 1.318 + 1.319 +static void build_intra_predictors(const uint8_t *ref, int ref_stride, 1.320 + uint8_t *dst, int dst_stride, 1.321 + MB_PREDICTION_MODE mode, TX_SIZE tx_size, 1.322 + int up_available, int left_available, 1.323 + int right_available) { 1.324 + int i; 1.325 + DECLARE_ALIGNED_ARRAY(16, uint8_t, left_col, 64); 1.326 + DECLARE_ALIGNED_ARRAY(16, uint8_t, above_data, 128 + 16); 1.327 + uint8_t *above_row = above_data + 16; 1.328 + const uint8_t *const_above_row = above_row; 1.329 + const int bs = 4 << tx_size; 1.330 + 1.331 + // 127 127 127 .. 127 127 127 127 127 127 1.332 + // 129 A B .. Y Z 1.333 + // 129 C D .. W X 1.334 + // 129 E F .. U V 1.335 + // 129 G H .. S T T T T T 1.336 + // .. 1.337 + 1.338 + once(init_intra_pred_fn_ptrs); 1.339 + 1.340 + // left 1.341 + if (left_available) { 1.342 + for (i = 0; i < bs; i++) 1.343 + left_col[i] = ref[i * ref_stride - 1]; 1.344 + } else { 1.345 + vpx_memset(left_col, 129, bs); 1.346 + } 1.347 + 1.348 + // above 1.349 + if (up_available) { 1.350 + const uint8_t *above_ref = ref - ref_stride; 1.351 + if (bs == 4 && right_available && left_available) { 1.352 + const_above_row = above_ref; 1.353 + } else { 1.354 + vpx_memcpy(above_row, above_ref, bs); 1.355 + if (bs == 4 && right_available) 1.356 + vpx_memcpy(above_row + bs, above_ref + bs, bs); 1.357 + else 1.358 + vpx_memset(above_row + bs, above_row[bs - 1], bs); 1.359 + above_row[-1] = left_available ? above_ref[-1] : 129; 1.360 + } 1.361 + } else { 1.362 + vpx_memset(above_row, 127, bs * 2); 1.363 + above_row[-1] = 127; 1.364 + } 1.365 + 1.366 + // predict 1.367 + if (mode == DC_PRED) { 1.368 + dc_pred[left_available][up_available][tx_size](dst, dst_stride, 1.369 + const_above_row, left_col); 1.370 + } else { 1.371 + pred[mode][tx_size](dst, dst_stride, const_above_row, left_col); 1.372 + } 1.373 +} 1.374 + 1.375 +void vp9_predict_intra_block(const MACROBLOCKD *xd, int block_idx, int bwl_in, 1.376 + TX_SIZE tx_size, int mode, 1.377 + const uint8_t *ref, int ref_stride, 1.378 + uint8_t *dst, int dst_stride) { 1.379 + const int bwl = bwl_in - tx_size; 1.380 + const int wmask = (1 << bwl) - 1; 1.381 + const int have_top = (block_idx >> bwl) || xd->up_available; 1.382 + const int have_left = (block_idx & wmask) || xd->left_available; 1.383 + const int have_right = ((block_idx & wmask) != wmask); 1.384 + 1.385 + assert(bwl >= 0); 1.386 + build_intra_predictors(ref, ref_stride, dst, dst_stride, mode, tx_size, 1.387 + have_top, have_left, have_right); 1.388 +}