vp9_reconintra.c 29.9 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
#include "./vpx_config.h"
12
#include "./vp9_rtcd.h"
13
14
15

#include "vpx_mem/vpx_mem.h"

16
#include "vp9/common/vp9_reconintra.h"
17
#include "vp9/common/vp9_onyxc_int.h"
John Koleszar's avatar
John Koleszar committed
18

19
const TX_TYPE intra_mode_to_tx_type_lookup[INTRA_MODES] = {
20
21
22
23
24
25
26
27
28
29
  DCT_DCT,    // DC
  ADST_DCT,   // V
  DCT_ADST,   // H
  DCT_DCT,    // D45
  ADST_ADST,  // D135
  ADST_DCT,   // D117
  DCT_ADST,   // D153
  DCT_ADST,   // D207
  ADST_DCT,   // D63
  ADST_ADST,  // TM
30
31
};

32
33
34
// This serves as a wrapper function, so that all the prediction functions
// can be unified and accessed as a pointer array. Note that the boundary
// above and left are not necessarily used all the time.
35
#define intra_pred_sized(type, size) \
36
37
38
39
40
41
42
  void vp9_##type##_predictor_##size##x##size##_c(uint8_t *dst, \
                                                  ptrdiff_t stride, \
                                                  const uint8_t *above, \
                                                  const uint8_t *left) { \
    type##_predictor(dst, stride, size, above, left); \
  }

43
#if CONFIG_VP9_HIGHBITDEPTH
44
45
#define intra_pred_highbd_sized(type, size) \
  void vp9_highbd_##type##_predictor_##size##x##size##_c( \
46
47
      uint16_t *dst, ptrdiff_t stride, const uint16_t *above, \
      const uint16_t *left, int bd) { \
48
    highbd_##type##_predictor(dst, stride, size, above, left, bd); \
49
50
51
52
53
54
55
  }

#define intra_pred_allsizes(type) \
  intra_pred_sized(type, 4) \
  intra_pred_sized(type, 8) \
  intra_pred_sized(type, 16) \
  intra_pred_sized(type, 32) \
56
57
58
59
  intra_pred_highbd_sized(type, 4) \
  intra_pred_highbd_sized(type, 8) \
  intra_pred_highbd_sized(type, 16) \
  intra_pred_highbd_sized(type, 32)
60
61
62

#else

63
64
65
66
67
#define intra_pred_allsizes(type) \
  intra_pred_sized(type, 4) \
  intra_pred_sized(type, 8) \
  intra_pred_sized(type, 16) \
  intra_pred_sized(type, 32)
68
69
70
#endif  // CONFIG_VP9_HIGHBITDEPTH

#if CONFIG_VP9_HIGHBITDEPTH
71
72
73
static INLINE void highbd_d207_predictor(uint16_t *dst, ptrdiff_t stride,
                                         int bs, const uint16_t *above,
                                         const uint16_t *left, int bd) {
Deb Mukherjee's avatar
Deb Mukherjee committed
74
  int r, c;
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
  (void) above;
  (void) bd;

  // First column.
  for (r = 0; r < bs - 1; ++r) {
    dst[r * stride] = ROUND_POWER_OF_TWO(left[r] + left[r + 1], 1);
  }
  dst[(bs - 1) * stride] = left[bs - 1];
  dst++;

  // Second column.
  for (r = 0; r < bs - 2; ++r) {
    dst[r * stride] = ROUND_POWER_OF_TWO(left[r] + left[r + 1] * 2 +
                                         left[r + 2], 2);
  }
  dst[(bs - 2) * stride] = ROUND_POWER_OF_TWO(left[bs - 2] +
                                              left[bs - 1] * 3, 2);
  dst[(bs - 1) * stride] = left[bs - 1];
  dst++;

  // Rest of last row.
  for (c = 0; c < bs - 2; ++c)
    dst[(bs - 1) * stride + c] = left[bs - 1];

  for (r = bs - 2; r >= 0; --r) {
    for (c = 0; c < bs - 2; ++c)
      dst[r * stride + c] = dst[(r + 1) * stride + c - 2];
  }
}

105
106
107
static INLINE void highbd_d63_predictor(uint16_t *dst, ptrdiff_t stride,
                                        int bs, const uint16_t *above,
                                        const uint16_t *left, int bd) {
Deb Mukherjee's avatar
Deb Mukherjee committed
108
  int r, c;
109
110
111
112
113
114
115
116
117
118
119
120
121
122
  (void) left;
  (void) bd;
  for (r = 0; r < bs; ++r) {
    for (c = 0; c < bs; ++c) {
      dst[c] = r & 1 ? ROUND_POWER_OF_TWO(above[r/2 + c] +
                                          above[r/2 + c + 1] * 2 +
                                          above[r/2 + c + 2], 2)
                     : ROUND_POWER_OF_TWO(above[r/2 + c] +
                                          above[r/2 + c + 1], 1);
    }
    dst += stride;
  }
}

123
124
125
static INLINE void highbd_d45_predictor(uint16_t *dst, ptrdiff_t stride, int bs,
                                        const uint16_t *above,
                                        const uint16_t *left, int bd) {
Deb Mukherjee's avatar
Deb Mukherjee committed
126
  int r, c;
127
128
129
130
131
132
133
134
135
136
137
138
139
  (void) left;
  (void) bd;
  for (r = 0; r < bs; ++r) {
    for (c = 0; c < bs; ++c) {
      dst[c] = r + c + 2 < bs * 2 ?  ROUND_POWER_OF_TWO(above[r + c] +
                                                        above[r + c + 1] * 2 +
                                                        above[r + c + 2], 2)
                                  : above[bs * 2 - 1];
    }
    dst += stride;
  }
}

140
141
142
static INLINE void highbd_d117_predictor(uint16_t *dst, ptrdiff_t stride,
                                         int bs, const uint16_t *above,
                                         const uint16_t *left, int bd) {
143
  int r, c;
Deb Mukherjee's avatar
Deb Mukherjee committed
144
  (void) bd;
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170

  // first row
  for (c = 0; c < bs; c++)
    dst[c] = ROUND_POWER_OF_TWO(above[c - 1] + above[c], 1);
  dst += stride;

  // second row
  dst[0] = ROUND_POWER_OF_TWO(left[0] + above[-1] * 2 + above[0], 2);
  for (c = 1; c < bs; c++)
    dst[c] = ROUND_POWER_OF_TWO(above[c - 2] + above[c - 1] * 2 + above[c], 2);
  dst += stride;

  // the rest of first col
  dst[0] = ROUND_POWER_OF_TWO(above[-1] + left[0] * 2 + left[1], 2);
  for (r = 3; r < bs; ++r)
    dst[(r - 2) * stride] = ROUND_POWER_OF_TWO(left[r - 3] + left[r - 2] * 2 +
                                               left[r - 1], 2);

  // the rest of the block
  for (r = 2; r < bs; ++r) {
    for (c = 1; c < bs; c++)
      dst[c] = dst[-2 * stride + c - 1];
    dst += stride;
  }
}

171
172
173
static INLINE void highbd_d135_predictor(uint16_t *dst, ptrdiff_t stride,
                                         int bs, const uint16_t *above,
                                         const uint16_t *left, int bd) {
174
  int r, c;
Deb Mukherjee's avatar
Deb Mukherjee committed
175
  (void) bd;
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
  dst[0] = ROUND_POWER_OF_TWO(left[0] + above[-1] * 2 + above[0], 2);
  for (c = 1; c < bs; c++)
    dst[c] = ROUND_POWER_OF_TWO(above[c - 2] + above[c - 1] * 2 + above[c], 2);

  dst[stride] = ROUND_POWER_OF_TWO(above[-1] + left[0] * 2 + left[1], 2);
  for (r = 2; r < bs; ++r)
    dst[r * stride] = ROUND_POWER_OF_TWO(left[r - 2] + left[r - 1] * 2 +
                                         left[r], 2);

  dst += stride;
  for (r = 1; r < bs; ++r) {
    for (c = 1; c < bs; c++)
      dst[c] = dst[-stride + c - 1];
    dst += stride;
  }
}

193
194
195
static INLINE void highbd_d153_predictor(uint16_t *dst, ptrdiff_t stride,
                                         int bs, const uint16_t *above,
                                         const uint16_t *left, int bd) {
196
  int r, c;
Deb Mukherjee's avatar
Deb Mukherjee committed
197
  (void) bd;
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
  dst[0] = ROUND_POWER_OF_TWO(above[-1] + left[0], 1);
  for (r = 1; r < bs; r++)
    dst[r * stride] = ROUND_POWER_OF_TWO(left[r - 1] + left[r], 1);
  dst++;

  dst[0] = ROUND_POWER_OF_TWO(left[0] + above[-1] * 2 + above[0], 2);
  dst[stride] = ROUND_POWER_OF_TWO(above[-1] + left[0] * 2 + left[1], 2);
  for (r = 2; r < bs; r++)
    dst[r * stride] = ROUND_POWER_OF_TWO(left[r - 2] + left[r - 1] * 2 +
                                         left[r], 2);
  dst++;

  for (c = 0; c < bs - 2; c++)
    dst[c] = ROUND_POWER_OF_TWO(above[c - 1] + above[c] * 2 + above[c + 1], 2);
  dst += stride;

  for (r = 1; r < bs; ++r) {
    for (c = 0; c < bs - 2; c++)
      dst[c] = dst[-stride + c - 2];
    dst += stride;
  }
}

221
222
223
static INLINE void highbd_v_predictor(uint16_t *dst, ptrdiff_t stride,
                                      int bs, const uint16_t *above,
                                      const uint16_t *left, int bd) {
Deb Mukherjee's avatar
Deb Mukherjee committed
224
  int r;
225
226
227
228
229
230
231
232
  (void) left;
  (void) bd;
  for (r = 0; r < bs; r++) {
    vpx_memcpy(dst, above, bs * sizeof(uint16_t));
    dst += stride;
  }
}

233
234
235
static INLINE void highbd_h_predictor(uint16_t *dst, ptrdiff_t stride,
                                      int bs, const uint16_t *above,
                                      const uint16_t *left, int bd) {
Deb Mukherjee's avatar
Deb Mukherjee committed
236
  int r;
237
238
239
240
241
242
243
244
  (void) above;
  (void) bd;
  for (r = 0; r < bs; r++) {
    vpx_memset16(dst, left[r], bs);
    dst += stride;
  }
}

245
246
247
static INLINE void highbd_tm_predictor(uint16_t *dst, ptrdiff_t stride,
                                       int bs, const uint16_t *above,
                                       const uint16_t *left, int bd) {
248
249
  int r, c;
  int ytop_left = above[-1];
Deb Mukherjee's avatar
Deb Mukherjee committed
250
  (void) bd;
251
252
253

  for (r = 0; r < bs; r++) {
    for (c = 0; c < bs; c++)
254
      dst[c] = clip_pixel_highbd(left[r] + above[c] - ytop_left, bd);
255
256
257
258
    dst += stride;
  }
}

259
260
261
static INLINE void highbd_dc_128_predictor(uint16_t *dst, ptrdiff_t stride,
                                           int bs, const uint16_t *above,
                                           const uint16_t *left, int bd) {
Deb Mukherjee's avatar
Deb Mukherjee committed
262
  int r;
263
264
265
266
267
268
269
270
271
  (void) above;
  (void) left;

  for (r = 0; r < bs; r++) {
    vpx_memset16(dst, 128 << (bd - 8), bs);
    dst += stride;
  }
}

272
273
274
static INLINE void highbd_dc_left_predictor(uint16_t *dst, ptrdiff_t stride,
                                            int bs, const uint16_t *above,
                                            const uint16_t *left, int bd) {
Deb Mukherjee's avatar
Deb Mukherjee committed
275
  int i, r, expected_dc, sum = 0;
276
277
278
279
280
281
282
283
284
285
286
287
288
  (void) above;
  (void) bd;

  for (i = 0; i < bs; i++)
    sum += left[i];
  expected_dc = (sum + (bs >> 1)) / bs;

  for (r = 0; r < bs; r++) {
    vpx_memset16(dst, expected_dc, bs);
    dst += stride;
  }
}

289
290
291
static INLINE void highbd_dc_top_predictor(uint16_t *dst, ptrdiff_t stride,
                                           int bs, const uint16_t *above,
                                           const uint16_t *left, int bd) {
Deb Mukherjee's avatar
Deb Mukherjee committed
292
  int i, r, expected_dc, sum = 0;
293
294
295
296
297
298
299
300
301
302
303
304
305
  (void) left;
  (void) bd;

  for (i = 0; i < bs; i++)
    sum += above[i];
  expected_dc = (sum + (bs >> 1)) / bs;

  for (r = 0; r < bs; r++) {
    vpx_memset16(dst, expected_dc, bs);
    dst += stride;
  }
}

306
307
308
static INLINE void highbd_dc_predictor(uint16_t *dst, ptrdiff_t stride,
                                       int bs, const uint16_t *above,
                                       const uint16_t *left, int bd) {
309
310
  int i, r, expected_dc, sum = 0;
  const int count = 2 * bs;
Deb Mukherjee's avatar
Deb Mukherjee committed
311
  (void) bd;
312
313
314
315
316
317
318
319
320
321
322
323
324
325

  for (i = 0; i < bs; i++) {
    sum += above[i];
    sum += left[i];
  }

  expected_dc = (sum + (count >> 1)) / count;

  for (r = 0; r < bs; r++) {
    vpx_memset16(dst, expected_dc, bs);
    dst += stride;
  }
}
#endif  // CONFIG_VP9_HIGHBITDEPTH
326

327
328
static INLINE void d207_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
                                  const uint8_t *above, const uint8_t *left) {
329
  int r, c;
330
  (void) above;
331
  // first column
Dmitry Kovalev's avatar
Dmitry Kovalev committed
332
  for (r = 0; r < bs - 1; ++r)
333
334
335
    dst[r * stride] = ROUND_POWER_OF_TWO(left[r] + left[r + 1], 1);
  dst[(bs - 1) * stride] = left[bs - 1];
  dst++;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
336

337
  // second column
Dmitry Kovalev's avatar
Dmitry Kovalev committed
338
  for (r = 0; r < bs - 2; ++r)
339
340
341
342
343
344
    dst[r * stride] = ROUND_POWER_OF_TWO(left[r] + left[r + 1] * 2 +
                                         left[r + 2], 2);
  dst[(bs - 2) * stride] = ROUND_POWER_OF_TWO(left[bs - 2] +
                                              left[bs - 1] * 3, 2);
  dst[(bs - 1) * stride] = left[bs - 1];
  dst++;
345

346
  // rest of last row
Dmitry Kovalev's avatar
Dmitry Kovalev committed
347
  for (c = 0; c < bs - 2; ++c)
348
    dst[(bs - 1) * stride + c] = left[bs - 1];
349

Dmitry Kovalev's avatar
Dmitry Kovalev committed
350
351
  for (r = bs - 2; r >= 0; --r)
    for (c = 0; c < bs - 2; ++c)
352
      dst[r * stride + c] = dst[(r + 1) * stride + c - 2];
353
}
354
intra_pred_allsizes(d207)
355

356
357
static INLINE void d63_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
                                 const uint8_t *above, const uint8_t *left) {
358
  int r, c;
359
  (void) left;
360
  for (r = 0; r < bs; ++r) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
361
    for (c = 0; c < bs; ++c)
362
363
364
365
366
367
      dst[c] = r & 1 ? ROUND_POWER_OF_TWO(above[r/2 + c] +
                                          above[r/2 + c + 1] * 2 +
                                          above[r/2 + c + 2], 2)
                     : ROUND_POWER_OF_TWO(above[r/2 + c] +
                                          above[r/2 + c + 1], 1);
    dst += stride;
John Koleszar's avatar
John Koleszar committed
368
  }
369
}
370
intra_pred_allsizes(d63)
371

372
373
static INLINE void d45_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
                                 const uint8_t *above, const uint8_t *left) {
John Koleszar's avatar
John Koleszar committed
374
  int r, c;
375
  (void) left;
376
  for (r = 0; r < bs; ++r) {
377
378
379
380
381
382
    for (c = 0; c < bs; ++c)
      dst[c] = r + c + 2 < bs * 2 ?  ROUND_POWER_OF_TWO(above[r + c] +
                                                        above[r + c + 1] * 2 +
                                                        above[r + c + 2], 2)
                                  : above[bs * 2 - 1];
    dst += stride;
John Koleszar's avatar
John Koleszar committed
383
  }
384
}
385
intra_pred_allsizes(d45)
386

387
388
static INLINE void d117_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
                                  const uint8_t *above, const uint8_t *left) {
John Koleszar's avatar
John Koleszar committed
389
  int r, c;
390

391
  // first row
392
  for (c = 0; c < bs; c++)
393
394
    dst[c] = ROUND_POWER_OF_TWO(above[c - 1] + above[c], 1);
  dst += stride;
395
396

  // second row
397
  dst[0] = ROUND_POWER_OF_TWO(left[0] + above[-1] * 2 + above[0], 2);
398
  for (c = 1; c < bs; c++)
399
400
    dst[c] = ROUND_POWER_OF_TWO(above[c - 2] + above[c - 1] * 2 + above[c], 2);
  dst += stride;
401
402

  // the rest of first col
403
  dst[0] = ROUND_POWER_OF_TWO(above[-1] + left[0] * 2 + left[1], 2);
404
  for (r = 3; r < bs; ++r)
405
406
407
    dst[(r - 2) * stride] = ROUND_POWER_OF_TWO(left[r - 3] + left[r - 2] * 2 +
                                               left[r - 1], 2);

408
  // the rest of the block
409
410
  for (r = 2; r < bs; ++r) {
    for (c = 1; c < bs; c++)
411
412
      dst[c] = dst[-2 * stride + c - 1];
    dst += stride;
John Koleszar's avatar
John Koleszar committed
413
  }
414
}
415
intra_pred_allsizes(d117)
416

417
418
static INLINE void d135_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
                                  const uint8_t *above, const uint8_t *left) {
John Koleszar's avatar
John Koleszar committed
419
  int r, c;
420
  dst[0] = ROUND_POWER_OF_TWO(left[0] + above[-1] * 2 + above[0], 2);
421
  for (c = 1; c < bs; c++)
422
    dst[c] = ROUND_POWER_OF_TWO(above[c - 2] + above[c - 1] * 2 + above[c], 2);
423

424
  dst[stride] = ROUND_POWER_OF_TWO(above[-1] + left[0] * 2 + left[1], 2);
425
  for (r = 2; r < bs; ++r)
426
427
    dst[r * stride] = ROUND_POWER_OF_TWO(left[r - 2] + left[r - 1] * 2 +
                                         left[r], 2);
John Koleszar's avatar
John Koleszar committed
428

429
  dst += stride;
430
431
  for (r = 1; r < bs; ++r) {
    for (c = 1; c < bs; c++)
432
433
      dst[c] = dst[-stride + c - 1];
    dst += stride;
John Koleszar's avatar
John Koleszar committed
434
  }
435
}
436
intra_pred_allsizes(d135)
437

438
439
static INLINE void d153_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
                                  const uint8_t *above, const uint8_t *left) {
John Koleszar's avatar
John Koleszar committed
440
  int r, c;
441
  dst[0] = ROUND_POWER_OF_TWO(above[-1] + left[0], 1);
442
  for (r = 1; r < bs; r++)
443
444
445
446
447
    dst[r * stride] = ROUND_POWER_OF_TWO(left[r - 1] + left[r], 1);
  dst++;

  dst[0] = ROUND_POWER_OF_TWO(left[0] + above[-1] * 2 + above[0], 2);
  dst[stride] = ROUND_POWER_OF_TWO(above[-1] + left[0] * 2 + left[1], 2);
448
  for (r = 2; r < bs; r++)
449
450
451
    dst[r * stride] = ROUND_POWER_OF_TWO(left[r - 2] + left[r - 1] * 2 +
                                         left[r], 2);
  dst++;
John Koleszar's avatar
John Koleszar committed
452

453
  for (c = 0; c < bs - 2; c++)
454
455
456
    dst[c] = ROUND_POWER_OF_TWO(above[c - 1] + above[c] * 2 + above[c + 1], 2);
  dst += stride;

457
458
  for (r = 1; r < bs; ++r) {
    for (c = 0; c < bs - 2; c++)
459
460
      dst[c] = dst[-stride + c - 2];
    dst += stride;
John Koleszar's avatar
John Koleszar committed
461
  }
462
}
463
intra_pred_allsizes(d153)
464

465
466
static INLINE void v_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
                               const uint8_t *above, const uint8_t *left) {
467
  int r;
468
  (void) left;
469
470

  for (r = 0; r < bs; r++) {
471
472
    vpx_memcpy(dst, above, bs);
    dst += stride;
473
474
  }
}
475
intra_pred_allsizes(v)
476

477
478
static INLINE void h_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
                               const uint8_t *above, const uint8_t *left) {
479
  int r;
480
  (void) above;
481
482

  for (r = 0; r < bs; r++) {
483
484
    vpx_memset(dst, left[r], bs);
    dst += stride;
485
486
  }
}
487
intra_pred_allsizes(h)
488

489
490
static INLINE void tm_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
                                const uint8_t *above, const uint8_t *left) {
491
  int r, c;
492
  int ytop_left = above[-1];
493
494
495

  for (r = 0; r < bs; r++) {
    for (c = 0; c < bs; c++)
496
497
      dst[c] = clip_pixel(left[r] + above[c] - ytop_left);
    dst += stride;
498
499
  }
}
500
intra_pred_allsizes(tm)
501

502
503
static INLINE void dc_128_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
                                    const uint8_t *above, const uint8_t *left) {
504
  int r;
505
506
  (void) above;
  (void) left;
507
508

  for (r = 0; r < bs; r++) {
509
510
    vpx_memset(dst, 128, bs);
    dst += stride;
511
512
  }
}
513
intra_pred_allsizes(dc_128)
514

515
516
517
518
static INLINE void dc_left_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
                                     const uint8_t *above,
                                     const uint8_t *left) {
  int i, r, expected_dc, sum = 0;
519
  (void) above;
520
521

  for (i = 0; i < bs; i++)
522
523
    sum += left[i];
  expected_dc = (sum + (bs >> 1)) / bs;
524
525

  for (r = 0; r < bs; r++) {
526
527
    vpx_memset(dst, expected_dc, bs);
    dst += stride;
528
529
  }
}
530
intra_pred_allsizes(dc_left)
531

532
533
534
static INLINE void dc_top_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
                                    const uint8_t *above, const uint8_t *left) {
  int i, r, expected_dc, sum = 0;
535
  (void) left;
536
537

  for (i = 0; i < bs; i++)
538
539
    sum += above[i];
  expected_dc = (sum + (bs >> 1)) / bs;
540
541

  for (r = 0; r < bs; r++) {
542
543
    vpx_memset(dst, expected_dc, bs);
    dst += stride;
544
545
  }
}
546
intra_pred_allsizes(dc_top)
547

548
549
550
static INLINE void dc_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
                                const uint8_t *above, const uint8_t *left) {
  int i, r, expected_dc, sum = 0;
551
552
  const int count = 2 * bs;

553
554
555
556
557
558
  for (i = 0; i < bs; i++) {
    sum += above[i];
    sum += left[i];
  }

  expected_dc = (sum + (count >> 1)) / count;
559
560

  for (r = 0; r < bs; r++) {
561
562
    vpx_memset(dst, expected_dc, bs);
    dst += stride;
563
564
  }
}
565
566
567
intra_pred_allsizes(dc)
#undef intra_pred_allsizes

568
569
typedef void (*intra_pred_fn)(uint8_t *dst, ptrdiff_t stride,
                              const uint8_t *above, const uint8_t *left);
570

571
572
573
static intra_pred_fn pred[INTRA_MODES][TX_SIZES];
static intra_pred_fn dc_pred[2][2][TX_SIZES];

574
575
576
577
578
579
580
581
#if CONFIG_VP9_HIGHBITDEPTH
typedef void (*intra_high_pred_fn)(uint16_t *dst, ptrdiff_t stride,
                                   const uint16_t *above, const uint16_t *left,
                                   int bd);
static intra_high_pred_fn pred_high[INTRA_MODES][4];
static intra_high_pred_fn dc_pred_high[2][2][4];
#endif  // CONFIG_VP9_HIGHBITDEPTH

582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
void vp9_init_intra_predictors() {
#define INIT_ALL_SIZES(p, type) \
  p[TX_4X4] = vp9_##type##_predictor_4x4; \
  p[TX_8X8] = vp9_##type##_predictor_8x8; \
  p[TX_16X16] = vp9_##type##_predictor_16x16; \
  p[TX_32X32] = vp9_##type##_predictor_32x32

  INIT_ALL_SIZES(pred[V_PRED], v);
  INIT_ALL_SIZES(pred[H_PRED], h);
  INIT_ALL_SIZES(pred[D207_PRED], d207);
  INIT_ALL_SIZES(pred[D45_PRED], d45);
  INIT_ALL_SIZES(pred[D63_PRED], d63);
  INIT_ALL_SIZES(pred[D117_PRED], d117);
  INIT_ALL_SIZES(pred[D135_PRED], d135);
  INIT_ALL_SIZES(pred[D153_PRED], d153);
  INIT_ALL_SIZES(pred[TM_PRED], tm);

  INIT_ALL_SIZES(dc_pred[0][0], dc_128);
  INIT_ALL_SIZES(dc_pred[0][1], dc_top);
  INIT_ALL_SIZES(dc_pred[1][0], dc_left);
  INIT_ALL_SIZES(dc_pred[1][1], dc);

604
#if CONFIG_VP9_HIGHBITDEPTH
605
606
607
608
609
610
611
612
613
614
615
616
617
618
  INIT_ALL_SIZES(pred_high[V_PRED], highbd_v);
  INIT_ALL_SIZES(pred_high[H_PRED], highbd_h);
  INIT_ALL_SIZES(pred_high[D207_PRED], highbd_d207);
  INIT_ALL_SIZES(pred_high[D45_PRED], highbd_d45);
  INIT_ALL_SIZES(pred_high[D63_PRED], highbd_d63);
  INIT_ALL_SIZES(pred_high[D117_PRED], highbd_d117);
  INIT_ALL_SIZES(pred_high[D135_PRED], highbd_d135);
  INIT_ALL_SIZES(pred_high[D153_PRED], highbd_d153);
  INIT_ALL_SIZES(pred_high[TM_PRED], highbd_tm);

  INIT_ALL_SIZES(dc_pred_high[0][0], highbd_dc_128);
  INIT_ALL_SIZES(dc_pred_high[0][1], highbd_dc_top);
  INIT_ALL_SIZES(dc_pred_high[1][0], highbd_dc_left);
  INIT_ALL_SIZES(dc_pred_high[1][1], highbd_dc);
619
620
621
#endif  // CONFIG_VP9_HIGHBITDEPTH

#undef intra_pred_allsizes
622
}
623

624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
#if CONFIG_VP9_HIGHBITDEPTH
static void build_intra_predictors_high(const MACROBLOCKD *xd,
                                        const uint8_t *ref8,
                                        int ref_stride,
                                        uint8_t *dst8,
                                        int dst_stride,
                                        PREDICTION_MODE mode,
                                        TX_SIZE tx_size,
                                        int up_available,
                                        int left_available,
                                        int right_available,
                                        int x, int y,
                                        int plane, int bd) {
  int i;
  uint16_t *dst = CONVERT_TO_SHORTPTR(dst8);
  uint16_t *ref = CONVERT_TO_SHORTPTR(ref8);
  DECLARE_ALIGNED_ARRAY(16, uint16_t, left_col, 64);
  DECLARE_ALIGNED_ARRAY(16, uint16_t, above_data, 128 + 16);
  uint16_t *above_row = above_data + 16;
  const uint16_t *const_above_row = above_row;
  const int bs = 4 << tx_size;
  int frame_width, frame_height;
  int x0, y0;
  const struct macroblockd_plane *const pd = &xd->plane[plane];
  //  int base=128;
  int base = 128 << (bd - 8);
  // 127 127 127 .. 127 127 127 127 127 127
  // 129  A   B  ..  Y   Z
  // 129  C   D  ..  W   X
  // 129  E   F  ..  U   V
  // 129  G   H  ..  S   T   T   T   T   T

  // Get current frame pointer, width and height.
  if (plane == 0) {
    frame_width = xd->cur_buf->y_width;
    frame_height = xd->cur_buf->y_height;
  } else {
    frame_width = xd->cur_buf->uv_width;
    frame_height = xd->cur_buf->uv_height;
  }

  // Get block position in current frame.
  x0 = (-xd->mb_to_left_edge >> (3 + pd->subsampling_x)) + x;
  y0 = (-xd->mb_to_top_edge >> (3 + pd->subsampling_y)) + y;

  // left
  if (left_available) {
    if (xd->mb_to_bottom_edge < 0) {
      /* slower path if the block needs border extension */
      if (y0 + bs <= frame_height) {
        for (i = 0; i < bs; ++i)
          left_col[i] = ref[i * ref_stride - 1];
      } else {
        const int extend_bottom = frame_height - y0;
        for (i = 0; i < extend_bottom; ++i)
          left_col[i] = ref[i * ref_stride - 1];
        for (; i < bs; ++i)
          left_col[i] = ref[(extend_bottom - 1) * ref_stride - 1];
      }
    } else {
      /* faster path if the block does not need extension */
      for (i = 0; i < bs; ++i)
        left_col[i] = ref[i * ref_stride - 1];
    }
  } else {
    // TODO(Peter): this value should probably change for high bitdepth
    vpx_memset16(left_col, base + 1, bs);
  }

  // TODO(hkuang) do not extend 2*bs pixels for all modes.
  // above
  if (up_available) {
    const uint16_t *above_ref = ref - ref_stride;
    if (xd->mb_to_right_edge < 0) {
      /* slower path if the block needs border extension */
      if (x0 + 2 * bs <= frame_width) {
        if (right_available && bs == 4) {
          vpx_memcpy(above_row, above_ref, 2 * bs * sizeof(uint16_t));
        } else {
          vpx_memcpy(above_row, above_ref, bs * sizeof(uint16_t));
          vpx_memset16(above_row + bs, above_row[bs - 1], bs);
        }
      } else if (x0 + bs <= frame_width) {
        const int r = frame_width - x0;
        if (right_available && bs == 4) {
          vpx_memcpy(above_row, above_ref, r * sizeof(uint16_t));
          vpx_memset16(above_row + r, above_row[r - 1],
                       x0 + 2 * bs - frame_width);
        } else {
          vpx_memcpy(above_row, above_ref, bs * sizeof(uint16_t));
          vpx_memset16(above_row + bs, above_row[bs - 1], bs);
        }
      } else if (x0 <= frame_width) {
        const int r = frame_width - x0;
        if (right_available && bs == 4) {
          vpx_memcpy(above_row, above_ref, r * sizeof(uint16_t));
          vpx_memset16(above_row + r, above_row[r - 1],
                       x0 + 2 * bs - frame_width);
        } else {
          vpx_memcpy(above_row, above_ref, r * sizeof(uint16_t));
          vpx_memset16(above_row + r, above_row[r - 1],
                       x0 + 2 * bs - frame_width);
        }
      }
      // TODO(Peter) this value should probably change for high bitdepth
      above_row[-1] = left_available ? above_ref[-1] : (base+1);
    } else {
      /* faster path if the block does not need extension */
      if (bs == 4 && right_available && left_available) {
        const_above_row = above_ref;
      } else {
        vpx_memcpy(above_row, above_ref, bs * sizeof(uint16_t));
        if (bs == 4 && right_available)
          vpx_memcpy(above_row + bs, above_ref + bs, bs * sizeof(uint16_t));
        else
          vpx_memset16(above_row + bs, above_row[bs - 1], bs);
        // TODO(Peter): this value should probably change for high bitdepth
        above_row[-1] = left_available ? above_ref[-1] : (base+1);
      }
    }
  } else {
    vpx_memset16(above_row, base - 1, bs * 2);
    // TODO(Peter): this value should probably change for high bitdepth
    above_row[-1] = base - 1;
  }

  // predict
  if (mode == DC_PRED) {
    dc_pred_high[left_available][up_available][tx_size](dst, dst_stride,
                                                        const_above_row,
                                                        left_col, xd->bd);
  } else {
    pred_high[mode][tx_size](dst, dst_stride, const_above_row, left_col,
                             xd->bd);
  }
}
#endif  // CONFIG_VP9_HIGHBITDEPTH

762
763
static void build_intra_predictors(const MACROBLOCKD *xd, const uint8_t *ref,
                                   int ref_stride, uint8_t *dst, int dst_stride,
764
                                   PREDICTION_MODE mode, TX_SIZE tx_size,
765
                                   int up_available, int left_available,
766
767
                                   int right_available, int x, int y,
                                   int plane) {
768
  int i;
769
  DECLARE_ALIGNED_ARRAY(16, uint8_t, left_col, 64);
770
771
772
773
  DECLARE_ALIGNED_ARRAY(16, uint8_t, above_data, 128 + 16);
  uint8_t *above_row = above_data + 16;
  const uint8_t *const_above_row = above_row;
  const int bs = 4 << tx_size;
774
775
776
  int frame_width, frame_height;
  int x0, y0;
  const struct macroblockd_plane *const pd = &xd->plane[plane];
Dmitry Kovalev's avatar
Dmitry Kovalev committed
777
778
779
780
781
782
783

  // 127 127 127 .. 127 127 127 127 127 127
  // 129  A   B  ..  Y   Z
  // 129  C   D  ..  W   X
  // 129  E   F  ..  U   V
  // 129  G   H  ..  S   T   T   T   T   T
  // ..
John Koleszar's avatar
John Koleszar committed
784

785
786
787
788
789
790
791
792
793
794
795
796
797
  // Get current frame pointer, width and height.
  if (plane == 0) {
    frame_width = xd->cur_buf->y_width;
    frame_height = xd->cur_buf->y_height;
  } else {
    frame_width = xd->cur_buf->uv_width;
    frame_height = xd->cur_buf->uv_height;
  }

  // Get block position in current frame.
  x0 = (-xd->mb_to_left_edge >> (3 + pd->subsampling_x)) + x;
  y0 = (-xd->mb_to_top_edge >> (3 + pd->subsampling_y)) + y;

798
799
  vpx_memset(left_col, 129, 64);

800
  // left
801
  if (left_available) {
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
    if (xd->mb_to_bottom_edge < 0) {
      /* slower path if the block needs border extension */
      if (y0 + bs <= frame_height) {
        for (i = 0; i < bs; ++i)
          left_col[i] = ref[i * ref_stride - 1];
      } else {
        const int extend_bottom = frame_height - y0;
        for (i = 0; i < extend_bottom; ++i)
          left_col[i] = ref[i * ref_stride - 1];
        for (; i < bs; ++i)
          left_col[i] = ref[(extend_bottom - 1) * ref_stride - 1];
      }
    } else {
      /* faster path if the block does not need extension */
      for (i = 0; i < bs; ++i)
        left_col[i] = ref[i * ref_stride - 1];
    }
819
820
  }

821
  // TODO(hkuang) do not extend 2*bs pixels for all modes.
822
  // above
823
  if (up_available) {
824
    const uint8_t *above_ref = ref - ref_stride;
825
826
827
828
    if (xd->mb_to_right_edge < 0) {
      /* slower path if the block needs border extension */
      if (x0 + 2 * bs <= frame_width) {
        if (right_available && bs == 4) {
829
          vpx_memcpy(above_row, above_ref, 2 * bs);
830
        } else {
831
          vpx_memcpy(above_row, above_ref, bs);
832
833
834
835
836
          vpx_memset(above_row + bs, above_row[bs - 1], bs);
        }
      } else if (x0 + bs <= frame_width) {
        const int r = frame_width - x0;
        if (right_available && bs == 4) {
837
          vpx_memcpy(above_row, above_ref, r);
838
839
840
          vpx_memset(above_row + r, above_row[r - 1],
                     x0 + 2 * bs - frame_width);
        } else {
841
          vpx_memcpy(above_row, above_ref, bs);
842
843
844
845
846
          vpx_memset(above_row + bs, above_row[bs - 1], bs);
        }
      } else if (x0 <= frame_width) {
        const int r = frame_width - x0;
        if (right_available && bs == 4) {
847
          vpx_memcpy(above_row, above_ref, r);
848
849
850
          vpx_memset(above_row + r, above_row[r - 1],
                     x0 + 2 * bs - frame_width);
        } else {
851
          vpx_memcpy(above_row, above_ref, r);
852
853
854
855
          vpx_memset(above_row + r, above_row[r - 1],
                     x0 + 2 * bs - frame_width);
        }
      }
856
      above_row[-1] = left_available ? above_ref[-1] : 129;
857
    } else {
858
859
860
861
862
863
864
865
866
867
868
      /* faster path if the block does not need extension */
      if (bs == 4 && right_available && left_available) {
        const_above_row = above_ref;
      } else {
        vpx_memcpy(above_row, above_ref, bs);
        if (bs == 4 && right_available)
          vpx_memcpy(above_row + bs, above_ref + bs, bs);
        else
          vpx_memset(above_row + bs, above_row[bs - 1], bs);
        above_row[-1] = left_available ? above_ref[-1] : 129;
      }
869
    }
870
  } else {
871
872
    vpx_memset(above_row, 127, bs * 2);
    above_row[-1] = 127;
John Koleszar's avatar
John Koleszar committed
873
  }
874

875
  // predict
876
  if (mode == DC_PRED) {
877
878
    dc_pred[left_available][up_available][tx_size](dst, dst_stride,
                                                   const_above_row, left_col);
879
  } else {
880
    pred[mode][tx_size](dst, dst_stride, const_above_row, left_col);
John Koleszar's avatar
John Koleszar committed
881
  }
John Koleszar's avatar
John Koleszar committed
882
883
}

884
void vp9_predict_intra_block(const MACROBLOCKD *xd, int block_idx, int bwl_in,
885
                             TX_SIZE tx_size, PREDICTION_MODE mode,
886
887
888
                             const uint8_t *ref, int ref_stride,
                             uint8_t *dst, int dst_stride,
                             int aoff, int loff, int plane) {
889
  const int bwl = bwl_in - tx_size;
890
  const int wmask = (1 << bwl) - 1;
891
892
893
  const int have_top = (block_idx >> bwl) || xd->up_available;
  const int have_left = (block_idx & wmask) || xd->left_available;
  const int have_right = ((block_idx & wmask) != wmask);
894
895
  const int x = aoff * 4;
  const int y = loff * 4;
Yaowu Xu's avatar
Yaowu Xu committed
896

897
  assert(bwl >= 0);
898
899
900
901
902
903
904
905
#if CONFIG_VP9_HIGHBITDEPTH
  if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
    build_intra_predictors_high(xd, ref, ref_stride, dst, dst_stride, mode,
                                tx_size, have_top, have_left, have_right,
                                x, y, plane, xd->bd);
    return;
  }
#endif
906
907
  build_intra_predictors(xd, ref, ref_stride, dst, dst_stride, mode, tx_size,
                         have_top, have_left, have_right, x, y, plane);
908
}