media/libvpx/vp9/common/vp9_reconintra.c

changeset 0
6474c204b198
     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 +}

mercurial