reconintra.c 21 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 <stdio.h>
John Koleszar's avatar
John Koleszar committed
12
13
14
15
16
#include "vpx_ports/config.h"
#include "recon.h"
#include "reconintra.h"
#include "vpx_mem/vpx_mem.h"

17
18
19
/* For skip_recon_mb(), add vp8_build_intra_predictors_mby_s(MACROBLOCKD *x) and
 * vp8_build_intra_predictors_mbuv_s(MACROBLOCKD *x).
 */
20
21

void d27_predictor(unsigned char *ypred_ptr, int y_stride, int n,
John Koleszar's avatar
John Koleszar committed
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
                   unsigned char *yabove_row, unsigned char *yleft_col) {
  int r, c, h, w, v;
  int a, b;
  r = 0;
  for (c = 0; c < n - 2; c++) {
    if (c & 1)
      a = yleft_col[r + 1];
    else
      a = (yleft_col[r] + yleft_col[r + 1] + 1) >> 1;
    b = yabove_row[c + 2];
    ypred_ptr[c] = (2 * a + (c + 1) * b + (c + 3) / 2) / (c + 3);
  }
  for (r = 1; r < n / 2 - 1; r++) {
    for (c = 0; c < n - 2 - 2 * r; c++) {
      if (c & 1)
        a = yleft_col[r + 1];
      else
        a = (yleft_col[r] + yleft_col[r + 1] + 1) >> 1;
      b = ypred_ptr[(r - 1) * y_stride + c + 2];
      ypred_ptr[r * y_stride + c] = (2 * a + (c + 1) * b + (c + 3) / 2) / (c + 3);
    }
  }
  for (; r < n - 1; ++r) {
    for (c = 0; c < n; c++) {
      v = (c & 1 ? yleft_col[r + 1] : (yleft_col[r] + yleft_col[r + 1] + 1) >> 1);
      h = r - c / 2;
      ypred_ptr[h * y_stride + c] = v;
    }
  }
  c = 0;
  r = n - 1;
  ypred_ptr[r * y_stride] = (ypred_ptr[(r - 1) * y_stride] +
                             yleft_col[r] + 1) >> 1;
  for (r = n - 2; r >= n / 2; --r) {
    w = c + (n - 1 - r) * 2;
    ypred_ptr[r * y_stride + w] = (ypred_ptr[(r - 1) * y_stride + w] +
                                   ypred_ptr[r * y_stride + w - 1] + 1) >> 1;
  }
  for (c = 1; c < n; c++) {
    for (r = n - 1; r >= n / 2 + c / 2; --r) {
      w = c + (n - 1 - r) * 2;
      ypred_ptr[r * y_stride + w] = (ypred_ptr[(r - 1) * y_stride + w] +
                                     ypred_ptr[r * y_stride + w - 1] + 1) >> 1;
    }
  }
67
68
69
}

void d63_predictor(unsigned char *ypred_ptr, int y_stride, int n,
John Koleszar's avatar
John Koleszar committed
70
71
72
73
74
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
105
106
107
108
109
110
111
112
113
                   unsigned char *yabove_row, unsigned char *yleft_col) {
  int r, c, h, w, v;
  int a, b;
  c = 0;
  for (r = 0; r < n - 2; r++) {
    if (r & 1)
      a = yabove_row[c + 1];
    else
      a = (yabove_row[c] + yabove_row[c + 1] + 1) >> 1;
    b = yleft_col[r + 2];
    ypred_ptr[r * y_stride] = (2 * a + (r + 1) * b + (r + 3) / 2) / (r + 3);
  }
  for (c = 1; c < n / 2 - 1; c++) {
    for (r = 0; r < n - 2 - 2 * c; r++) {
      if (r & 1)
        a = yabove_row[c + 1];
      else
        a = (yabove_row[c] + yabove_row[c + 1] + 1) >> 1;
      b = ypred_ptr[(r + 2) * y_stride + c - 1];
      ypred_ptr[r * y_stride + c] = (2 * a + (c + 1) * b + (c + 3) / 2) / (c + 3);
    }
  }
  for (; c < n - 1; ++c) {
    for (r = 0; r < n; r++) {
      v = (r & 1 ? yabove_row[c + 1] : (yabove_row[c] + yabove_row[c + 1] + 1) >> 1);
      w = c - r / 2;
      ypred_ptr[r * y_stride + w] = v;
    }
  }
  r = 0;
  c = n - 1;
  ypred_ptr[c] = (ypred_ptr[(c - 1)] + yabove_row[c] + 1) >> 1;
  for (c = n - 2; c >= n / 2; --c) {
    h = r + (n - 1 - c) * 2;
    ypred_ptr[h * y_stride + c] = (ypred_ptr[h * y_stride + c - 1] +
                                   ypred_ptr[(h - 1) * y_stride + c] + 1) >> 1;
  }
  for (r = 1; r < n; r++) {
    for (c = n - 1; c >= n / 2 + r / 2; --c) {
      h = r + (n - 1 - c) * 2;
      ypred_ptr[h * y_stride + c] = (ypred_ptr[h * y_stride + c - 1] +
                                     ypred_ptr[(h - 1) * y_stride + c] + 1) >> 1;
    }
  }
114
115
116
}

void d45_predictor(unsigned char *ypred_ptr, int y_stride, int n,
John Koleszar's avatar
John Koleszar committed
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
                   unsigned char *yabove_row, unsigned char *yleft_col) {
  int r, c;
  for (r = 0; r < n - 1; ++r) {
    for (c = 0; c <= r; ++c) {
      ypred_ptr[(r - c) * y_stride + c] =
        (yabove_row[r + 1] * (c + 1) +
         yleft_col[r + 1] * (r - c + 1) + r / 2 + 1) / (r + 2);
    }
  }
  for (c = 0; c <= r; ++c) {
    int yabove_ext = yabove_row[r]; // 2*yabove_row[r] - yabove_row[r-1];
    int yleft_ext = yleft_col[r]; // 2*yleft_col[r] - yleft_col[r-1];
    yabove_ext = (yabove_ext > 255 ? 255 : (yabove_ext < 0 ? 0 : yabove_ext));
    yleft_ext = (yleft_ext > 255 ? 255 : (yleft_ext < 0 ? 0 : yleft_ext));
    ypred_ptr[(r - c) * y_stride + c] =
      (yabove_ext * (c + 1) +
       yleft_ext * (r - c + 1) + r / 2 + 1) / (r + 2);
  }
  for (r = 1; r < n; ++r) {
    for (c = n - r; c < n; ++c)
      ypred_ptr[r * y_stride + c] = (ypred_ptr[(r - 1) * y_stride + c] +
                                     ypred_ptr[r * y_stride + c - 1] + 1) >> 1;
  }
140
141
142
}

void d117_predictor(unsigned char *ypred_ptr, int y_stride, int n,
John Koleszar's avatar
John Koleszar committed
143
144
145
146
147
148
149
150
151
152
153
154
                    unsigned char *yabove_row, unsigned char *yleft_col) {
  int r, c;
  for (c = 0; c < n; c++)
    ypred_ptr[c] = (yabove_row[c - 1] + yabove_row[c] + 1) >> 1;
  ypred_ptr += y_stride;
  for (c = 0; c < n; c++)
    ypred_ptr[c] = yabove_row[c - 1];
  ypred_ptr += y_stride;
  for (r = 2; r < n; ++r) {
    ypred_ptr[0] = yleft_col[r - 2];
    for (c = 1; c < n; c++)
      ypred_ptr[c] = ypred_ptr[-2 * y_stride + c - 1];
155
    ypred_ptr += y_stride;
John Koleszar's avatar
John Koleszar committed
156
  }
157
158
159
}

void d135_predictor(unsigned char *ypred_ptr, int y_stride, int n,
John Koleszar's avatar
John Koleszar committed
160
161
162
163
164
165
166
167
168
169
170
171
                    unsigned char *yabove_row, unsigned char *yleft_col) {
  int r, c;
  ypred_ptr[0] = yabove_row[-1];
  for (c = 1; c < n; c++)
    ypred_ptr[c] = yabove_row[c - 1];
  for (r = 1; r < n; ++r)
    ypred_ptr[r * y_stride] = yleft_col[r - 1];

  ypred_ptr += y_stride;
  for (r = 1; r < n; ++r) {
    for (c = 1; c < n; c++) {
      ypred_ptr[c] = ypred_ptr[-y_stride + c - 1];
172
    }
John Koleszar's avatar
John Koleszar committed
173
174
    ypred_ptr += y_stride;
  }
175
176
177
}

void d153_predictor(unsigned char *ypred_ptr, int y_stride, int n,
John Koleszar's avatar
John Koleszar committed
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
                    unsigned char *yabove_row, unsigned char *yleft_col) {
  int r, c;
  ypred_ptr[0] = (yabove_row[-1] + yleft_col[0] + 1) >> 1;
  for (r = 1; r < n; r++)
    ypred_ptr[r * y_stride] = (yleft_col[r - 1] + yleft_col[r] + 1) >> 1;
  ypred_ptr++;
  ypred_ptr[0] = yabove_row[-1];
  for (r = 1; r < n; r++)
    ypred_ptr[r * y_stride] = yleft_col[r - 1];
  ypred_ptr++;

  for (c = 0; c < n - 2; c++)
    ypred_ptr[c] = yabove_row[c];
  ypred_ptr += y_stride;
  for (r = 1; r < n; ++r) {
193
    for (c = 0; c < n - 2; c++)
John Koleszar's avatar
John Koleszar committed
194
      ypred_ptr[c] = ypred_ptr[-y_stride + c - 2];
195
    ypred_ptr += y_stride;
John Koleszar's avatar
John Koleszar committed
196
  }
197
198
}

Paul Wilkins's avatar
Paul Wilkins committed
199
200
void vp8_recon_intra_mbuv(const vp8_recon_rtcd_vtable_t *rtcd,
                          MACROBLOCKD *xd) {
John Koleszar's avatar
John Koleszar committed
201
  int i;
John Koleszar's avatar
John Koleszar committed
202

John Koleszar's avatar
John Koleszar committed
203
  for (i = 16; i < 24; i += 2) {
Paul Wilkins's avatar
Paul Wilkins committed
204
205
206
    BLOCKD *b = &xd->block[i];
    RECON_INVOKE(rtcd, recon2)(b->predictor, b->diff,
                 *(b->base_dst) + b->dst, b->dst_stride);
John Koleszar's avatar
John Koleszar committed
207
  }
John Koleszar's avatar
John Koleszar committed
208
209
}

Paul Wilkins's avatar
Paul Wilkins committed
210
211
212
void vp8_build_intra_predictors_mby_internal(MACROBLOCKD *xd,
                                             unsigned char *ypred_ptr,
                                             int y_stride, int mode) {
John Koleszar's avatar
John Koleszar committed
213

Paul Wilkins's avatar
Paul Wilkins committed
214
  unsigned char *yabove_row = xd->dst.y_buffer - xd->dst.y_stride;
John Koleszar's avatar
John Koleszar committed
215
216
217
218
219
  unsigned char yleft_col[16];
  unsigned char ytop_left = yabove_row[-1];
  int r, c, i;

  for (i = 0; i < 16; i++) {
Paul Wilkins's avatar
Paul Wilkins committed
220
    yleft_col[i] = xd->dst.y_buffer [i * xd->dst.y_stride - 1];
John Koleszar's avatar
John Koleszar committed
221
222
223
224
225
226
227
228
229
230
231
  }

  /* for Y */
  switch (mode) {
    case DC_PRED: {
      int expected_dc;
      int i;
      int shift;
      int average = 0;


Paul Wilkins's avatar
Paul Wilkins committed
232
233
      if (xd->up_available || xd->left_available) {
        if (xd->up_available) {
John Koleszar's avatar
John Koleszar committed
234
235
236
          for (i = 0; i < 16; i++) {
            average += yabove_row[i];
          }
John Koleszar's avatar
John Koleszar committed
237
238
        }

Paul Wilkins's avatar
Paul Wilkins committed
239
        if (xd->left_available) {
John Koleszar's avatar
John Koleszar committed
240
241
242
          for (i = 0; i < 16; i++) {
            average += yleft_col[i];
          }
John Koleszar's avatar
John Koleszar committed
243
        }
Paul Wilkins's avatar
Paul Wilkins committed
244
        shift = 3 + xd->up_available + xd->left_available;
John Koleszar's avatar
John Koleszar committed
245
246
247
248
249
250
251
252
253
        expected_dc = (average + (1 << (shift - 1))) >> shift;
      } else {
        expected_dc = 128;
      }

      for (r = 0; r < 16; r++) {
        vpx_memset(ypred_ptr, expected_dc, 16);
        ypred_ptr += y_stride; /*16;*/
      }
John Koleszar's avatar
John Koleszar committed
254
255
    }
    break;
John Koleszar's avatar
John Koleszar committed
256
    case V_PRED: {
John Koleszar's avatar
John Koleszar committed
257

John Koleszar's avatar
John Koleszar committed
258
      for (r = 0; r < 16; r++) {
John Koleszar's avatar
John Koleszar committed
259

John Koleszar's avatar
John Koleszar committed
260
261
262
263
264
265
        ((int *)ypred_ptr)[0] = ((int *)yabove_row)[0];
        ((int *)ypred_ptr)[1] = ((int *)yabove_row)[1];
        ((int *)ypred_ptr)[2] = ((int *)yabove_row)[2];
        ((int *)ypred_ptr)[3] = ((int *)yabove_row)[3];
        ypred_ptr += y_stride;
      }
John Koleszar's avatar
John Koleszar committed
266
267
    }
    break;
John Koleszar's avatar
John Koleszar committed
268
    case H_PRED: {
John Koleszar's avatar
John Koleszar committed
269

John Koleszar's avatar
John Koleszar committed
270
      for (r = 0; r < 16; r++) {
John Koleszar's avatar
John Koleszar committed
271

John Koleszar's avatar
John Koleszar committed
272
273
274
        vpx_memset(ypred_ptr, yleft_col[r], 16);
        ypred_ptr += y_stride;
      }
John Koleszar's avatar
John Koleszar committed
275
276
277

    }
    break;
John Koleszar's avatar
John Koleszar committed
278
    case TM_PRED: {
John Koleszar's avatar
John Koleszar committed
279

John Koleszar's avatar
John Koleszar committed
280
281
282
      for (r = 0; r < 16; r++) {
        for (c = 0; c < 16; c++) {
          int pred =  yleft_col[r] + yabove_row[ c] - ytop_left;
John Koleszar's avatar
John Koleszar committed
283

John Koleszar's avatar
John Koleszar committed
284
285
          if (pred < 0)
            pred = 0;
John Koleszar's avatar
John Koleszar committed
286

John Koleszar's avatar
John Koleszar committed
287
288
          if (pred > 255)
            pred = 255;
John Koleszar's avatar
John Koleszar committed
289

John Koleszar's avatar
John Koleszar committed
290
          ypred_ptr[c] = pred;
John Koleszar's avatar
John Koleszar committed
291
292
        }

John Koleszar's avatar
John Koleszar committed
293
294
295
        ypred_ptr += y_stride;
      }

John Koleszar's avatar
John Koleszar committed
296
297
    }
    break;
John Koleszar's avatar
John Koleszar committed
298
299
    case D45_PRED: {
      d45_predictor(ypred_ptr, y_stride, 16,  yabove_row, yleft_col);
300
301
    }
    break;
John Koleszar's avatar
John Koleszar committed
302
303
    case D135_PRED: {
      d135_predictor(ypred_ptr, y_stride, 16,  yabove_row, yleft_col);
304
305
    }
    break;
John Koleszar's avatar
John Koleszar committed
306
307
    case D117_PRED: {
      d117_predictor(ypred_ptr, y_stride, 16,  yabove_row, yleft_col);
308
309
    }
    break;
John Koleszar's avatar
John Koleszar committed
310
311
    case D153_PRED: {
      d153_predictor(ypred_ptr, y_stride, 16,  yabove_row, yleft_col);
312
313
    }
    break;
John Koleszar's avatar
John Koleszar committed
314
315
    case D27_PRED: {
      d27_predictor(ypred_ptr, y_stride, 16,  yabove_row, yleft_col);
316
317
    }
    break;
John Koleszar's avatar
John Koleszar committed
318
319
    case D63_PRED: {
      d63_predictor(ypred_ptr, y_stride, 16,  yabove_row, yleft_col);
320
321
    }
    break;
322
    case I8X8_PRED:
John Koleszar's avatar
John Koleszar committed
323
324
325
326
327
328
329
    case B_PRED:
    case NEARESTMV:
    case NEARMV:
    case ZEROMV:
    case NEWMV:
    case SPLITMV:
    case MB_MODE_COUNT:
John Koleszar's avatar
John Koleszar committed
330
331
      break;
  }
John Koleszar's avatar
John Koleszar committed
332
333
}

Paul Wilkins's avatar
Paul Wilkins committed
334
335
336
void vp8_build_intra_predictors_mby(MACROBLOCKD *xd) {
  vp8_build_intra_predictors_mby_internal(xd, xd->predictor, 16,
                                          xd->mode_info_context->mbmi.mode);
337
}
John Koleszar's avatar
John Koleszar committed
338

Paul Wilkins's avatar
Paul Wilkins committed
339
340
341
342
void vp8_build_intra_predictors_mby_s(MACROBLOCKD *xd) {
  vp8_build_intra_predictors_mby_internal(xd, xd->dst.y_buffer,
                                          xd->dst.y_stride,
                                          xd->mode_info_context->mbmi.mode);
343
}
John Koleszar's avatar
John Koleszar committed
344

345
#if CONFIG_COMP_INTRA_PRED
Paul Wilkins's avatar
Paul Wilkins committed
346
void vp8_build_comp_intra_predictors_mby(MACROBLOCKD *xd) {
John Koleszar's avatar
John Koleszar committed
347
348
349
  unsigned char predictor[2][256];
  int i;

Paul Wilkins's avatar
Paul Wilkins committed
350
351
352
353
  vp8_build_intra_predictors_mby_internal(
    xd, predictor[0], 16, xd->mode_info_context->mbmi.mode);
  vp8_build_intra_predictors_mby_internal(
    xd, predictor[1], 16, xd->mode_info_context->mbmi.second_mode);
John Koleszar's avatar
John Koleszar committed
354
355

  for (i = 0; i < 256; i++) {
Paul Wilkins's avatar
Paul Wilkins committed
356
    xd->predictor[i] = (predictor[0][i] + predictor[1][i] + 1) >> 1;
John Koleszar's avatar
John Koleszar committed
357
  }
John Koleszar's avatar
John Koleszar committed
358
}
359
#endif
John Koleszar's avatar
John Koleszar committed
360

Paul Wilkins's avatar
Paul Wilkins committed
361
void vp8_build_intra_predictors_mbuv_internal(MACROBLOCKD *xd,
362
363
364
                                              unsigned char *upred_ptr,
                                              unsigned char *vpred_ptr,
                                              int uv_stride,
John Koleszar's avatar
John Koleszar committed
365
                                              int mode) {
Paul Wilkins's avatar
Paul Wilkins committed
366
367
  YV12_BUFFER_CONFIG * dst = &xd->dst;
  unsigned char *uabove_row = dst->u_buffer - dst->uv_stride;
John Koleszar's avatar
John Koleszar committed
368
369
  unsigned char uleft_col[16];
  unsigned char utop_left = uabove_row[-1];
Paul Wilkins's avatar
Paul Wilkins committed
370
  unsigned char *vabove_row = dst->v_buffer - dst->uv_stride;
John Koleszar's avatar
John Koleszar committed
371
372
373
374
375
376
  unsigned char vleft_col[20];
  unsigned char vtop_left = vabove_row[-1];

  int i, j;

  for (i = 0; i < 8; i++) {
Paul Wilkins's avatar
Paul Wilkins committed
377
378
    uleft_col[i] = dst->u_buffer [i * dst->uv_stride - 1];
    vleft_col[i] = dst->v_buffer [i * dst->uv_stride - 1];
John Koleszar's avatar
John Koleszar committed
379
380
381
382
383
384
385
386
387
388
389
  }

  switch (mode) {
    case DC_PRED: {
      int expected_udc;
      int expected_vdc;
      int i;
      int shift;
      int Uaverage = 0;
      int Vaverage = 0;

Paul Wilkins's avatar
Paul Wilkins committed
390
      if (xd->up_available) {
John Koleszar's avatar
John Koleszar committed
391
392
393
394
395
396
        for (i = 0; i < 8; i++) {
          Uaverage += uabove_row[i];
          Vaverage += vabove_row[i];
        }
      }

Paul Wilkins's avatar
Paul Wilkins committed
397
      if (xd->left_available) {
John Koleszar's avatar
John Koleszar committed
398
399
400
401
402
403
        for (i = 0; i < 8; i++) {
          Uaverage += uleft_col[i];
          Vaverage += vleft_col[i];
        }
      }

Paul Wilkins's avatar
Paul Wilkins committed
404
      if (!xd->up_available && !xd->left_available) {
John Koleszar's avatar
John Koleszar committed
405
406
407
        expected_udc = 128;
        expected_vdc = 128;
      } else {
Paul Wilkins's avatar
Paul Wilkins committed
408
        shift = 2 + xd->up_available + xd->left_available;
John Koleszar's avatar
John Koleszar committed
409
410
411
412
413
414
415
416
417
418
419
420
421
        expected_udc = (Uaverage + (1 << (shift - 1))) >> shift;
        expected_vdc = (Vaverage + (1 << (shift - 1))) >> shift;
      }


      /*vpx_memset(upred_ptr,expected_udc,64);*/
      /*vpx_memset(vpred_ptr,expected_vdc,64);*/
      for (i = 0; i < 8; i++) {
        vpx_memset(upred_ptr, expected_udc, 8);
        vpx_memset(vpred_ptr, expected_vdc, 8);
        upred_ptr += uv_stride; /*8;*/
        vpred_ptr += uv_stride; /*8;*/
      }
John Koleszar's avatar
John Koleszar committed
422
423
    }
    break;
John Koleszar's avatar
John Koleszar committed
424
425
    case V_PRED: {
      int i;
John Koleszar's avatar
John Koleszar committed
426

John Koleszar's avatar
John Koleszar committed
427
428
429
430
431
432
      for (i = 0; i < 8; i++) {
        vpx_memcpy(upred_ptr, uabove_row, 8);
        vpx_memcpy(vpred_ptr, vabove_row, 8);
        upred_ptr += uv_stride; /*8;*/
        vpred_ptr += uv_stride; /*8;*/
      }
John Koleszar's avatar
John Koleszar committed
433
434
435

    }
    break;
John Koleszar's avatar
John Koleszar committed
436
437
    case H_PRED: {
      int i;
John Koleszar's avatar
John Koleszar committed
438

John Koleszar's avatar
John Koleszar committed
439
440
441
442
443
444
      for (i = 0; i < 8; i++) {
        vpx_memset(upred_ptr, uleft_col[i], 8);
        vpx_memset(vpred_ptr, vleft_col[i], 8);
        upred_ptr += uv_stride; /*8;*/
        vpred_ptr += uv_stride; /*8;*/
      }
John Koleszar's avatar
John Koleszar committed
445
446
447
    }

    break;
John Koleszar's avatar
John Koleszar committed
448
449
    case TM_PRED: {
      int i;
John Koleszar's avatar
John Koleszar committed
450

John Koleszar's avatar
John Koleszar committed
451
452
453
454
      for (i = 0; i < 8; i++) {
        for (j = 0; j < 8; j++) {
          int predu = uleft_col[i] + uabove_row[j] - utop_left;
          int predv = vleft_col[i] + vabove_row[j] - vtop_left;
John Koleszar's avatar
John Koleszar committed
455

John Koleszar's avatar
John Koleszar committed
456
457
          if (predu < 0)
            predu = 0;
John Koleszar's avatar
John Koleszar committed
458

John Koleszar's avatar
John Koleszar committed
459
460
          if (predu > 255)
            predu = 255;
John Koleszar's avatar
John Koleszar committed
461

John Koleszar's avatar
John Koleszar committed
462
463
          if (predv < 0)
            predv = 0;
John Koleszar's avatar
John Koleszar committed
464

John Koleszar's avatar
John Koleszar committed
465
466
          if (predv > 255)
            predv = 255;
John Koleszar's avatar
John Koleszar committed
467

John Koleszar's avatar
John Koleszar committed
468
469
          upred_ptr[j] = predu;
          vpred_ptr[j] = predv;
John Koleszar's avatar
John Koleszar committed
470
471
        }

John Koleszar's avatar
John Koleszar committed
472
473
474
475
        upred_ptr += uv_stride; /*8;*/
        vpred_ptr += uv_stride; /*8;*/
      }

John Koleszar's avatar
John Koleszar committed
476
477
    }
    break;
John Koleszar's avatar
John Koleszar committed
478
479
480
    case D45_PRED: {
      d45_predictor(upred_ptr, uv_stride, 8,  uabove_row, uleft_col);
      d45_predictor(vpred_ptr, uv_stride, 8,  vabove_row, vleft_col);
481
482
    }
    break;
John Koleszar's avatar
John Koleszar committed
483
484
485
    case D135_PRED: {
      d135_predictor(upred_ptr, uv_stride, 8,  uabove_row, uleft_col);
      d135_predictor(vpred_ptr, uv_stride, 8,  vabove_row, vleft_col);
486
487
    }
    break;
John Koleszar's avatar
John Koleszar committed
488
489
490
    case D117_PRED: {
      d117_predictor(upred_ptr, uv_stride, 8,  uabove_row, uleft_col);
      d117_predictor(vpred_ptr, uv_stride, 8,  vabove_row, vleft_col);
491
492
    }
    break;
John Koleszar's avatar
John Koleszar committed
493
494
495
    case D153_PRED: {
      d153_predictor(upred_ptr, uv_stride, 8,  uabove_row, uleft_col);
      d153_predictor(vpred_ptr, uv_stride, 8,  vabove_row, vleft_col);
496
497
    }
    break;
John Koleszar's avatar
John Koleszar committed
498
499
500
    case D27_PRED: {
      d27_predictor(upred_ptr, uv_stride, 8,  uabove_row, uleft_col);
      d27_predictor(vpred_ptr, uv_stride, 8,  vabove_row, vleft_col);
501
502
    }
    break;
John Koleszar's avatar
John Koleszar committed
503
504
505
    case D63_PRED: {
      d63_predictor(upred_ptr, uv_stride, 8,  uabove_row, uleft_col);
      d63_predictor(vpred_ptr, uv_stride, 8,  vabove_row, vleft_col);
506
507
    }
    break;
John Koleszar's avatar
John Koleszar committed
508
509
510
511
512
513
514
    case B_PRED:
    case NEARESTMV:
    case NEARMV:
    case ZEROMV:
    case NEWMV:
    case SPLITMV:
    case MB_MODE_COUNT:
John Koleszar's avatar
John Koleszar committed
515
516
      break;
  }
John Koleszar's avatar
John Koleszar committed
517
}
518

Paul Wilkins's avatar
Paul Wilkins committed
519
520
521
522
void vp8_build_intra_predictors_mbuv(MACROBLOCKD *xd) {
  vp8_build_intra_predictors_mbuv_internal(
    xd, &xd->predictor[256], &xd->predictor[320],
    8, xd->mode_info_context->mbmi.uv_mode);
523
524
}

Paul Wilkins's avatar
Paul Wilkins committed
525
526
527
528
void vp8_build_intra_predictors_mbuv_s(MACROBLOCKD *xd) {
  vp8_build_intra_predictors_mbuv_internal(
    xd, xd->dst.u_buffer, xd->dst.v_buffer,
    xd->dst.uv_stride, xd->mode_info_context->mbmi.uv_mode);
529
530
531
}

#if CONFIG_COMP_INTRA_PRED
Paul Wilkins's avatar
Paul Wilkins committed
532
void vp8_build_comp_intra_predictors_mbuv(MACROBLOCKD *xd) {
John Koleszar's avatar
John Koleszar committed
533
534
535
  unsigned char predictor[2][2][64];
  int i;

Paul Wilkins's avatar
Paul Wilkins committed
536
537
538
539
540
541
  vp8_build_intra_predictors_mbuv_internal(
    xd, predictor[0][0], predictor[1][0], 8,
    xd->mode_info_context->mbmi.uv_mode);
  vp8_build_intra_predictors_mbuv_internal(
    xd, predictor[0][1], predictor[1][1], 8,
    xd->mode_info_context->mbmi.second_uv_mode);
John Koleszar's avatar
John Koleszar committed
542
  for (i = 0; i < 64; i++) {
Paul Wilkins's avatar
Paul Wilkins committed
543
544
    xd->predictor[256 + i] = (predictor[0][0][i] + predictor[0][1][i] + 1) >> 1;
    xd->predictor[256 + 64 + i] = (predictor[1][0][i] + predictor[1][1][i] + 1) >> 1;
John Koleszar's avatar
John Koleszar committed
545
  }
546
547
548
}
#endif

Paul Wilkins's avatar
Paul Wilkins committed
549
void vp8_intra8x8_predict(BLOCKD *xd,
Yaowu Xu's avatar
Yaowu Xu committed
550
                          int mode,
John Koleszar's avatar
John Koleszar committed
551
                          unsigned char *predictor) {
Yaowu Xu's avatar
Yaowu Xu committed
552

Paul Wilkins's avatar
Paul Wilkins committed
553
  unsigned char *yabove_row = *(xd->base_dst) + xd->dst - xd->dst_stride;
John Koleszar's avatar
John Koleszar committed
554
555
556
557
558
  unsigned char yleft_col[8];
  unsigned char ytop_left = yabove_row[-1];
  int r, c, i;

  for (i = 0; i < 8; i++) {
Paul Wilkins's avatar
Paul Wilkins committed
559
    yleft_col[i] = (*(xd->base_dst))[xd->dst - 1 + i * xd->dst_stride];
John Koleszar's avatar
John Koleszar committed
560
561
562
563
564
565
566
567
568
569
570
571
572
573
  }
  switch (mode) {
    case DC_PRED: {
      int expected_dc = 0;

      for (i = 0; i < 8; i++) {
        expected_dc += yabove_row[i];
        expected_dc += yleft_col[i];
      }
      expected_dc = (expected_dc + 8) >> 4;

      for (r = 0; r < 8; r++) {
        for (c = 0; c < 8; c++) {
          predictor[c] = expected_dc;
Yaowu Xu's avatar
Yaowu Xu committed
574
        }
John Koleszar's avatar
John Koleszar committed
575
576
577
578
579
580
581
582
        predictor += 16;
      }
    }
    break;
    case V_PRED: {
      for (r = 0; r < 8; r++) {
        for (c = 0; c < 8; c++) {
          predictor[c] = yabove_row[c];
583
        }
John Koleszar's avatar
John Koleszar committed
584
585
586
587
588
589
590
591
592
593
        predictor += 16;
      }

    }
    break;
    case H_PRED: {

      for (r = 0; r < 8; r++) {
        for (c = 0; c < 8; c++) {
          predictor[c] = yleft_col[r];
594
        }
John Koleszar's avatar
John Koleszar committed
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
        predictor += 16;
      }
    }
    break;
    case TM_PRED: {
      /* prediction similar to true_motion prediction */
      for (r = 0; r < 8; r++) {
        for (c = 0; c < 8; c++) {
          int pred = yabove_row[c] - ytop_left + yleft_col[r];
          if (pred < 0)
            pred = 0;

          if (pred > 255)
            pred = 255;
          predictor[c] = pred;
610
        }
John Koleszar's avatar
John Koleszar committed
611
612
613

        predictor += 16;
      }
Yaowu Xu's avatar
Yaowu Xu committed
614
    }
John Koleszar's avatar
John Koleszar committed
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
    break;
    case D45_PRED: {
      d45_predictor(predictor, 16, 8,  yabove_row, yleft_col);
    }
    break;
    case D135_PRED: {
      d135_predictor(predictor, 16, 8,  yabove_row, yleft_col);
    }
    break;
    case D117_PRED: {
      d117_predictor(predictor, 16, 8,  yabove_row, yleft_col);
    }
    break;
    case D153_PRED: {
      d153_predictor(predictor, 16, 8,  yabove_row, yleft_col);
    }
    break;
    case D27_PRED: {
      d27_predictor(predictor, 16, 8,  yabove_row, yleft_col);
    }
    break;
    case D63_PRED: {
      d63_predictor(predictor, 16, 8,  yabove_row, yleft_col);
    }
    break;
  }
Yaowu Xu's avatar
Yaowu Xu committed
641
642
}

643
#if CONFIG_COMP_INTRA_PRED
Paul Wilkins's avatar
Paul Wilkins committed
644
void vp8_comp_intra8x8_predict(BLOCKD *xd,
645
                               int mode, int second_mode,
John Koleszar's avatar
John Koleszar committed
646
647
648
649
                               unsigned char *out_predictor) {
  unsigned char predictor[2][8 * 16];
  int i, j;

Paul Wilkins's avatar
Paul Wilkins committed
650
651
  vp8_intra8x8_predict(xd, mode, predictor[0]);
  vp8_intra8x8_predict(xd, second_mode, predictor[1]);
John Koleszar's avatar
John Koleszar committed
652
653
654
655

  for (i = 0; i < 8 * 16; i += 16) {
    for (j = i; j < i + 8; j++) {
      out_predictor[j] = (predictor[0][j] + predictor[1][j] + 1) >> 1;
656
    }
John Koleszar's avatar
John Koleszar committed
657
  }
658
659
660
}
#endif

Paul Wilkins's avatar
Paul Wilkins committed
661
void vp8_intra_uv4x4_predict(BLOCKD *xd,
Yaowu Xu's avatar
Yaowu Xu committed
662
                             int mode,
John Koleszar's avatar
John Koleszar committed
663
664
                             unsigned char *predictor) {

Paul Wilkins's avatar
Paul Wilkins committed
665
  unsigned char *above_row = *(xd->base_dst) + xd->dst - xd->dst_stride;
John Koleszar's avatar
John Koleszar committed
666
667
668
669
670
  unsigned char left_col[4];
  unsigned char top_left = above_row[-1];
  int r, c, i;

  for (i = 0; i < 4; i++) {
Paul Wilkins's avatar
Paul Wilkins committed
671
    left_col[i] = (*(xd->base_dst))[xd->dst - 1 + i * xd->dst_stride];
John Koleszar's avatar
John Koleszar committed
672
673
674
675
676
677
678
679
680
681
682
683
684
685
  }
  switch (mode) {
    case DC_PRED: {
      int expected_dc = 0;

      for (i = 0; i < 4; i++) {
        expected_dc += above_row[i];
        expected_dc += left_col[i];
      }
      expected_dc = (expected_dc + 4) >> 3;

      for (r = 0; r < 4; r++) {
        for (c = 0; c < 4; c++) {
          predictor[c] = expected_dc;
Yaowu Xu's avatar
Yaowu Xu committed
686
        }
John Koleszar's avatar
John Koleszar committed
687
688
689
690
691
692
693
        predictor += 8;
      }
    }
    break;
    case V_PRED: {
      for (r = 0; r < 4; r++) {
        for (c = 0; c < 4; c++) {
Yaowu Xu's avatar
Yaowu Xu committed
694

John Koleszar's avatar
John Koleszar committed
695
          predictor[c] = above_row[c];
Yaowu Xu's avatar
Yaowu Xu committed
696
        }
John Koleszar's avatar
John Koleszar committed
697
698
699
700
701
702
703
704
705
706
        predictor += 8;
      }

    }
    break;
    case H_PRED: {

      for (r = 0; r < 4; r++) {
        for (c = 0; c < 4; c++) {
          predictor[c] = left_col[r];
Yaowu Xu's avatar
Yaowu Xu committed
707
        }
John Koleszar's avatar
John Koleszar committed
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
        predictor += 8;
      }
    }
    break;
    case TM_PRED: {
      /* prediction similar to true_motion prediction */
      for (r = 0; r < 4; r++) {
        for (c = 0; c < 4; c++) {
          int pred = above_row[c] - top_left + left_col[r];
          if (pred < 0)
            pred = 0;

          if (pred > 255)
            pred = 255;
          predictor[c] = pred;
Yaowu Xu's avatar
Yaowu Xu committed
723
        }
John Koleszar's avatar
John Koleszar committed
724
725
726
727
728
729
730

        predictor += 8;
      }
    }
    break;
    case D45_PRED: {
      d45_predictor(predictor, 8, 4,  above_row, left_col);
Yaowu Xu's avatar
Yaowu Xu committed
731
    }
John Koleszar's avatar
John Koleszar committed
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
    break;
    case D135_PRED: {
      d135_predictor(predictor, 8, 4,  above_row, left_col);
    }
    break;
    case D117_PRED: {
      d117_predictor(predictor, 8, 4,  above_row, left_col);
    }
    break;
    case D153_PRED: {
      d153_predictor(predictor, 8, 4,  above_row, left_col);
    }
    break;
    case D27_PRED: {
      d27_predictor(predictor, 8, 4,  above_row, left_col);
    }
    break;
    case D63_PRED: {
      d63_predictor(predictor, 8, 4,  above_row, left_col);
    }
    break;
  }
Yaowu Xu's avatar
Yaowu Xu committed
754
755
}

756
#if CONFIG_COMP_INTRA_PRED
Paul Wilkins's avatar
Paul Wilkins committed
757
void vp8_comp_intra_uv4x4_predict(BLOCKD *xd,
758
                                  int mode, int mode2,
John Koleszar's avatar
John Koleszar committed
759
760
761
762
                                  unsigned char *out_predictor) {
  unsigned char predictor[2][8 * 4];
  int i, j;

Paul Wilkins's avatar
Paul Wilkins committed
763
764
  vp8_intra_uv4x4_predict(xd, mode, predictor[0]);
  vp8_intra_uv4x4_predict(xd, mode2, predictor[1]);
John Koleszar's avatar
John Koleszar committed
765
766
767
768

  for (i = 0; i < 4 * 8; i += 8) {
    for (j = i; j < i + 4; j++) {
      out_predictor[j] = (predictor[0][j] + predictor[1][j] + 1) >> 1;
769
    }
John Koleszar's avatar
John Koleszar committed
770
  }
771
772
}
#endif
Yaowu Xu's avatar
Yaowu Xu committed
773
774
775
776
777

/* TODO: try different ways of use Y-UV mode correlation
 Current code assumes that a uv 4x4 block use same mode
 as corresponding Y 8x8 area
 */