vp9_postproc.c 31.3 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
12
13
 */


#include "vpx_ports/config.h"
#include "vpx_scale/yv12config.h"
14
15
#include "vp9_postproc.h"
#include "vp9/common/vp9_textblit.h"
John Koleszar's avatar
John Koleszar committed
16
#include "vpx_scale/vpxscale.h"
17
#include "vp9_systemdependent.h"
John Koleszar's avatar
John Koleszar committed
18
19
20
21

#include <math.h>
#include <stdlib.h>
#include <stdio.h>
22

23
24
25
26
27
28
29
#define RGB_TO_YUV(t)                                            \
  ( (0.257*(float)(t >> 16))  + (0.504*(float)(t >> 8 & 0xff)) + \
    (0.098*(float)(t & 0xff)) + 16),                             \
  (-(0.148*(float)(t >> 16))  - (0.291*(float)(t >> 8 & 0xff)) + \
    (0.439*(float)(t & 0xff)) + 128),                            \
  ( (0.439*(float)(t >> 16))  - (0.368*(float)(t >> 8 & 0xff)) - \
    (0.071*(float)(t & 0xff)) + 128)
30

31
/* global constants */
32
#if CONFIG_POSTPROC_VISUALIZER
John Koleszar's avatar
John Koleszar committed
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
static const unsigned char MB_PREDICTION_MODE_colors[MB_MODE_COUNT][3] = {
  { RGB_TO_YUV(0x98FB98) },   /* PaleGreen */
  { RGB_TO_YUV(0x00FF00) },   /* Green */
  { RGB_TO_YUV(0xADFF2F) },   /* GreenYellow */
  { RGB_TO_YUV(0x8F0000) },   /* Dark Red */
  { RGB_TO_YUV(0x008F8F) },   /* Dark Cyan */
  { RGB_TO_YUV(0x008F8F) },   /* Dark Cyan */
  { RGB_TO_YUV(0x008F8F) },   /* Dark Cyan */
  { RGB_TO_YUV(0x8F0000) },   /* Dark Red */
  { RGB_TO_YUV(0x8F0000) },   /* Dark Red */
  { RGB_TO_YUV(0x228B22) },   /* ForestGreen */
  { RGB_TO_YUV(0x006400) },   /* DarkGreen */
  { RGB_TO_YUV(0x98F5FF) },   /* Cadet Blue */
  { RGB_TO_YUV(0x6CA6CD) },   /* Sky Blue */
  { RGB_TO_YUV(0x00008B) },   /* Dark blue */
  { RGB_TO_YUV(0x551A8B) },   /* Purple */
  { RGB_TO_YUV(0xFF0000) }    /* Red */
  { RGB_TO_YUV(0xCC33FF) },   /* Magenta */
51
52
};

John Koleszar's avatar
John Koleszar committed
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
static const unsigned char B_PREDICTION_MODE_colors[B_MODE_COUNT][3] = {
  { RGB_TO_YUV(0x6633ff) },   /* Purple */
  { RGB_TO_YUV(0xcc33ff) },   /* Magenta */
  { RGB_TO_YUV(0xff33cc) },   /* Pink */
  { RGB_TO_YUV(0xff3366) },   /* Coral */
  { RGB_TO_YUV(0x3366ff) },   /* Blue */
  { RGB_TO_YUV(0xed00f5) },   /* Dark Blue */
  { RGB_TO_YUV(0x2e00b8) },   /* Dark Purple */
  { RGB_TO_YUV(0xff6633) },   /* Orange */
  { RGB_TO_YUV(0x33ccff) },   /* Light Blue */
  { RGB_TO_YUV(0x8ab800) },   /* Green */
  { RGB_TO_YUV(0xffcc33) },   /* Light Orange */
  { RGB_TO_YUV(0x33ffcc) },   /* Aqua */
  { RGB_TO_YUV(0x66ff33) },   /* Light Green */
  { RGB_TO_YUV(0xccff33) },   /* Yellow */
68
69
};

John Koleszar's avatar
John Koleszar committed
70
71
72
73
74
static const unsigned char MV_REFERENCE_FRAME_colors[MAX_REF_FRAMES][3] = {
  { RGB_TO_YUV(0x00ff00) },   /* Blue */
  { RGB_TO_YUV(0x0000ff) },   /* Green */
  { RGB_TO_YUV(0xffff00) },   /* Yellow */
  { RGB_TO_YUV(0xff0000) },   /* Red */
75
};
76
#endif
77

John Koleszar's avatar
John Koleszar committed
78
79
static const short kernel5[] = {
  1, 1, 4, 1, 1
John Koleszar's avatar
John Koleszar committed
80
81
};

82
const short vp9_rv[] = {
John Koleszar's avatar
John Koleszar committed
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
114
115
116
117
118
119
120
121
122
123
124
125
126
  8, 5, 2, 2, 8, 12, 4, 9, 8, 3,
  0, 3, 9, 0, 0, 0, 8, 3, 14, 4,
  10, 1, 11, 14, 1, 14, 9, 6, 12, 11,
  8, 6, 10, 0, 0, 8, 9, 0, 3, 14,
  8, 11, 13, 4, 2, 9, 0, 3, 9, 6,
  1, 2, 3, 14, 13, 1, 8, 2, 9, 7,
  3, 3, 1, 13, 13, 6, 6, 5, 2, 7,
  11, 9, 11, 8, 7, 3, 2, 0, 13, 13,
  14, 4, 12, 5, 12, 10, 8, 10, 13, 10,
  4, 14, 4, 10, 0, 8, 11, 1, 13, 7,
  7, 14, 6, 14, 13, 2, 13, 5, 4, 4,
  0, 10, 0, 5, 13, 2, 12, 7, 11, 13,
  8, 0, 4, 10, 7, 2, 7, 2, 2, 5,
  3, 4, 7, 3, 3, 14, 14, 5, 9, 13,
  3, 14, 3, 6, 3, 0, 11, 8, 13, 1,
  13, 1, 12, 0, 10, 9, 7, 6, 2, 8,
  5, 2, 13, 7, 1, 13, 14, 7, 6, 7,
  9, 6, 10, 11, 7, 8, 7, 5, 14, 8,
  4, 4, 0, 8, 7, 10, 0, 8, 14, 11,
  3, 12, 5, 7, 14, 3, 14, 5, 2, 6,
  11, 12, 12, 8, 0, 11, 13, 1, 2, 0,
  5, 10, 14, 7, 8, 0, 4, 11, 0, 8,
  0, 3, 10, 5, 8, 0, 11, 6, 7, 8,
  10, 7, 13, 9, 2, 5, 1, 5, 10, 2,
  4, 3, 5, 6, 10, 8, 9, 4, 11, 14,
  0, 10, 0, 5, 13, 2, 12, 7, 11, 13,
  8, 0, 4, 10, 7, 2, 7, 2, 2, 5,
  3, 4, 7, 3, 3, 14, 14, 5, 9, 13,
  3, 14, 3, 6, 3, 0, 11, 8, 13, 1,
  13, 1, 12, 0, 10, 9, 7, 6, 2, 8,
  5, 2, 13, 7, 1, 13, 14, 7, 6, 7,
  9, 6, 10, 11, 7, 8, 7, 5, 14, 8,
  4, 4, 0, 8, 7, 10, 0, 8, 14, 11,
  3, 12, 5, 7, 14, 3, 14, 5, 2, 6,
  11, 12, 12, 8, 0, 11, 13, 1, 2, 0,
  5, 10, 14, 7, 8, 0, 4, 11, 0, 8,
  0, 3, 10, 5, 8, 0, 11, 6, 7, 8,
  10, 7, 13, 9, 2, 5, 1, 5, 10, 2,
  4, 3, 5, 6, 10, 8, 9, 4, 11, 14,
  3, 8, 3, 7, 8, 5, 11, 4, 12, 3,
  11, 9, 14, 8, 14, 13, 4, 3, 1, 2,
  14, 6, 5, 4, 4, 11, 4, 6, 2, 1,
  5, 8, 8, 12, 13, 5, 14, 10, 12, 13,
  0, 9, 5, 5, 11, 10, 13, 9, 10, 13,
John Koleszar's avatar
John Koleszar committed
127
128
129
};


130
/****************************************************************************
John Koleszar's avatar
John Koleszar committed
131
 */
132
133
134
135
136
137
138
void vp9_post_proc_down_and_across_c(unsigned char *src_ptr,
                                     unsigned char *dst_ptr,
                                     int src_pixels_per_line,
                                     int dst_pixels_per_line,
                                     int rows,
                                     int cols,
                                     int flimit) {
John Koleszar's avatar
John Koleszar committed
139
140
141
142
143
144
145
146
  unsigned char *p_src, *p_dst;
  int row;
  int col;
  int i;
  int v;
  int pitch = src_pixels_per_line;
  unsigned char d[8];
  (void)dst_pixels_per_line;
John Koleszar's avatar
John Koleszar committed
147

John Koleszar's avatar
John Koleszar committed
148
149
150
151
  for (row = 0; row < rows; row++) {
    /* post_proc_down for one row */
    p_src = src_ptr;
    p_dst = dst_ptr;
John Koleszar's avatar
John Koleszar committed
152

John Koleszar's avatar
John Koleszar committed
153
    for (col = 0; col < cols; col++) {
John Koleszar's avatar
John Koleszar committed
154

John Koleszar's avatar
John Koleszar committed
155
156
      int kernel = 4;
      int v = p_src[col];
John Koleszar's avatar
John Koleszar committed
157

John Koleszar's avatar
John Koleszar committed
158
159
160
      for (i = -2; i <= 2; i++) {
        if (abs(v - p_src[col + i * pitch]) > flimit)
          goto down_skip_convolve;
John Koleszar's avatar
John Koleszar committed
161

John Koleszar's avatar
John Koleszar committed
162
163
        kernel += kernel5[2 + i] * p_src[col + i * pitch];
      }
John Koleszar's avatar
John Koleszar committed
164

John Koleszar's avatar
John Koleszar committed
165
166
167
168
      v = (kernel >> 3);
    down_skip_convolve:
      p_dst[col] = v;
    }
John Koleszar's avatar
John Koleszar committed
169

John Koleszar's avatar
John Koleszar committed
170
171
172
    /* now post_proc_across */
    p_src = dst_ptr;
    p_dst = dst_ptr;
John Koleszar's avatar
John Koleszar committed
173

John Koleszar's avatar
John Koleszar committed
174
175
    for (i = 0; i < 8; i++)
      d[i] = p_src[i];
John Koleszar's avatar
John Koleszar committed
176

John Koleszar's avatar
John Koleszar committed
177
178
179
180
181
182
183
184
185
    for (col = 0; col < cols; col++) {
      int kernel = 4;
      v = p_src[col];

      d[col & 7] = v;

      for (i = -2; i <= 2; i++) {
        if (abs(v - p_src[col + i]) > flimit)
          goto across_skip_convolve;
John Koleszar's avatar
John Koleszar committed
186

John Koleszar's avatar
John Koleszar committed
187
188
        kernel += kernel5[2 + i] * p_src[col + i];
      }
John Koleszar's avatar
John Koleszar committed
189

John Koleszar's avatar
John Koleszar committed
190
191
      d[col & 7] = (kernel >> 3);
    across_skip_convolve:
John Koleszar's avatar
John Koleszar committed
192

John Koleszar's avatar
John Koleszar committed
193
194
      if (col >= 2)
        p_dst[col - 2] = d[(col - 2) & 7];
John Koleszar's avatar
John Koleszar committed
195
196
    }

John Koleszar's avatar
John Koleszar committed
197
198
199
200
    /* handle the last two pixels */
    p_dst[col - 2] = d[(col - 2) & 7];
    p_dst[col - 1] = d[(col - 1) & 7];

John Koleszar's avatar
John Koleszar committed
201

John Koleszar's avatar
John Koleszar committed
202
203
204
205
    /* next row */
    src_ptr += pitch;
    dst_ptr += pitch;
  }
John Koleszar's avatar
John Koleszar committed
206
207
}

John Koleszar's avatar
John Koleszar committed
208
209
static int q2mbl(int x) {
  if (x < 20) x = 20;
John Koleszar's avatar
John Koleszar committed
210

John Koleszar's avatar
John Koleszar committed
211
212
213
  x = 50 + (x - 50) * 10 / 8;
  return x * x / 3;
}
214
215
216

void vp9_mbpost_proc_across_ip_c(unsigned char *src, int pitch,
                                 int rows, int cols, int flimit) {
John Koleszar's avatar
John Koleszar committed
217
  int r, c, i;
John Koleszar's avatar
John Koleszar committed
218

John Koleszar's avatar
John Koleszar committed
219
220
  unsigned char *s = src;
  unsigned char d[16];
John Koleszar's avatar
John Koleszar committed
221
222


John Koleszar's avatar
John Koleszar committed
223
224
225
  for (r = 0; r < rows; r++) {
    int sumsq = 0;
    int sum   = 0;
John Koleszar's avatar
John Koleszar committed
226

John Koleszar's avatar
John Koleszar committed
227
228
229
230
231
    for (i = -8; i <= 6; i++) {
      sumsq += s[i] * s[i];
      sum   += s[i];
      d[i + 8] = 0;
    }
John Koleszar's avatar
John Koleszar committed
232

John Koleszar's avatar
John Koleszar committed
233
234
235
    for (c = 0; c < cols + 8; c++) {
      int x = s[c + 7] - s[c - 8];
      int y = s[c + 7] + s[c - 8];
John Koleszar's avatar
John Koleszar committed
236

John Koleszar's avatar
John Koleszar committed
237
238
      sum  += x;
      sumsq += x * y;
John Koleszar's avatar
John Koleszar committed
239

John Koleszar's avatar
John Koleszar committed
240
241
242
243
244
      d[c & 15] = s[c];

      if (sumsq * 15 - sum * sum < flimit) {
        d[c & 15] = (8 + sum + s[c]) >> 4;
      }
John Koleszar's avatar
John Koleszar committed
245

John Koleszar's avatar
John Koleszar committed
246
      s[c - 8] = d[(c - 8) & 15];
John Koleszar's avatar
John Koleszar committed
247
    }
John Koleszar's avatar
John Koleszar committed
248
249
250

    s += pitch;
  }
John Koleszar's avatar
John Koleszar committed
251
252
}

253
254
void vp9_mbpost_proc_down_c(unsigned char *dst, int pitch,
                            int rows, int cols, int flimit) {
John Koleszar's avatar
John Koleszar committed
255
  int r, c, i;
256
  const short *rv3 = &vp9_rv[63 & rand()];
John Koleszar's avatar
John Koleszar committed
257

John Koleszar's avatar
John Koleszar committed
258
259
260
261
262
263
  for (c = 0; c < cols; c++) {
    unsigned char *s = &dst[c];
    int sumsq = 0;
    int sum   = 0;
    unsigned char d[16];
    const short *rv2 = rv3 + ((c * 17) & 127);
John Koleszar's avatar
John Koleszar committed
264

John Koleszar's avatar
John Koleszar committed
265
266
267
268
    for (i = -8; i <= 6; i++) {
      sumsq += s[i * pitch] * s[i * pitch];
      sum   += s[i * pitch];
    }
John Koleszar's avatar
John Koleszar committed
269

John Koleszar's avatar
John Koleszar committed
270
271
272
273
    for (r = 0; r < rows + 8; r++) {
      sumsq += s[7 * pitch] * s[ 7 * pitch] - s[-8 * pitch] * s[-8 * pitch];
      sum  += s[7 * pitch] - s[-8 * pitch];
      d[r & 15] = s[0];
John Koleszar's avatar
John Koleszar committed
274

John Koleszar's avatar
John Koleszar committed
275
276
277
      if (sumsq * 15 - sum * sum < flimit) {
        d[r & 15] = (rv2[r & 127] + sum + s[0]) >> 4;
      }
John Koleszar's avatar
John Koleszar committed
278

John Koleszar's avatar
John Koleszar committed
279
280
      s[-8 * pitch] = d[(r - 8) & 15];
      s += pitch;
John Koleszar's avatar
John Koleszar committed
281
    }
John Koleszar's avatar
John Koleszar committed
282
  }
John Koleszar's avatar
John Koleszar committed
283
284
}

285
286
287
288
289
290
static void deblock_and_de_macro_block(YV12_BUFFER_CONFIG   *source,
                                       YV12_BUFFER_CONFIG   *post,
                                       int                   q,
                                       int                   low_var_thresh,
                                       int                   flag,
                                       vp9_postproc_rtcd_vtable_t *rtcd) {
John Koleszar's avatar
John Koleszar committed
291
292
293
294
295
  double level = 6.0e-05 * q * q * q - .0067 * q * q + .306 * q + .0065;
  int ppl = (int)(level + .5);
  (void) low_var_thresh;
  (void) flag;

296
297
298
299
300
301
302
303
304
305
306
307
308
309
  POSTPROC_INVOKE(rtcd, downacross)(source->y_buffer, post->y_buffer,
                                    source->y_stride,  post->y_stride,
                                    source->y_height, source->y_width,  ppl);
  POSTPROC_INVOKE(rtcd, across)(post->y_buffer, post->y_stride,
                                post->y_height, post->y_width, q2mbl(q));
  POSTPROC_INVOKE(rtcd, down)(post->y_buffer, post->y_stride,
                              post->y_height, post->y_width, q2mbl(q));

  POSTPROC_INVOKE(rtcd, downacross)(source->u_buffer, post->u_buffer,
                                    source->uv_stride, post->uv_stride,
                                    source->uv_height, source->uv_width, ppl);
  POSTPROC_INVOKE(rtcd, downacross)(source->v_buffer, post->v_buffer,
                                    source->uv_stride, post->uv_stride,
                                    source->uv_height, source->uv_width, ppl);
John Koleszar's avatar
John Koleszar committed
310
311
}

312
void vp9_deblock(YV12_BUFFER_CONFIG         *source,
John Koleszar's avatar
John Koleszar committed
313
314
315
316
                 YV12_BUFFER_CONFIG         *post,
                 int                         q,
                 int                         low_var_thresh,
                 int                         flag,
317
                 vp9_postproc_rtcd_vtable_t *rtcd) {
John Koleszar's avatar
John Koleszar committed
318
319
320
321
322
  double level = 6.0e-05 * q * q * q - .0067 * q * q + .306 * q + .0065;
  int ppl = (int)(level + .5);
  (void) low_var_thresh;
  (void) flag;

323
324
325
326
327
328
329
330
331
  POSTPROC_INVOKE(rtcd, downacross)(source->y_buffer, post->y_buffer,
                                    source->y_stride,  post->y_stride,
                                    source->y_height, source->y_width,   ppl);
  POSTPROC_INVOKE(rtcd, downacross)(source->u_buffer, post->u_buffer,
                                    source->uv_stride, post->uv_stride,
                                    source->uv_height, source->uv_width, ppl);
  POSTPROC_INVOKE(rtcd, downacross)(source->v_buffer, post->v_buffer,
                                    source->uv_stride, post->uv_stride,
                                    source->uv_height, source->uv_width, ppl);
John Koleszar's avatar
John Koleszar committed
332
333
}

334
void vp9_de_noise(YV12_BUFFER_CONFIG         *src,
John Koleszar's avatar
John Koleszar committed
335
336
337
338
                  YV12_BUFFER_CONFIG         *post,
                  int                         q,
                  int                         low_var_thresh,
                  int                         flag,
339
                  vp9_postproc_rtcd_vtable_t *rtcd) {
John Koleszar's avatar
John Koleszar committed
340
341
342
343
344
345
  double level = 6.0e-05 * q * q * q - .0067 * q * q + .306 * q + .0065;
  int ppl = (int)(level + .5);
  (void) post;
  (void) low_var_thresh;
  (void) flag;

346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
  POSTPROC_INVOKE(rtcd, downacross)(src->y_buffer + 2 * src->y_stride + 2,
                                    src->y_buffer + 2 * src->y_stride + 2,
                                    src->y_stride,
                                    src->y_stride,
                                    src->y_height - 4,
                                    src->y_width - 4,
                                    ppl);
  POSTPROC_INVOKE(rtcd, downacross)(src->u_buffer + 2 * src->uv_stride + 2,
                                    src->u_buffer + 2 * src->uv_stride + 2,
                                    src->uv_stride,
                                    src->uv_stride,
                                    src->uv_height - 4,
                                    src->uv_width - 4, ppl);
  POSTPROC_INVOKE(rtcd, downacross)(src->v_buffer + 2 * src->uv_stride + 2,
                                    src->v_buffer + 2 * src->uv_stride + 2,
                                    src->uv_stride,
                                    src->uv_stride,
                                    src->uv_height - 4,
                                    src->uv_width - 4, ppl);
John Koleszar's avatar
John Koleszar committed
365
366
}

367
double vp9_gaussian(double sigma, double mu, double x) {
John Koleszar's avatar
John Koleszar committed
368
369
  return 1 / (sigma * sqrt(2.0 * 3.14159265)) *
         (exp(-(x - mu) * (x - mu) / (2 * sigma * sigma)));
John Koleszar's avatar
John Koleszar committed
370
371
}

John Koleszar's avatar
John Koleszar committed
372
373
static void fillrd(struct postproc_state *state, int q, int a) {
  char char_dist[300];
John Koleszar's avatar
John Koleszar committed
374

John Koleszar's avatar
John Koleszar committed
375
376
  double sigma;
  int ai = a, qi = q, i;
John Koleszar's avatar
John Koleszar committed
377

378
  vp9_clear_system_state();
John Koleszar's avatar
John Koleszar committed
379

John Koleszar's avatar
John Koleszar committed
380
  sigma = ai + .5 + .6 * (63 - qi) / 63.0;
John Koleszar's avatar
John Koleszar committed
381

John Koleszar's avatar
John Koleszar committed
382
383
384
385
386
387
  /* set up a lookup table of 256 entries that matches
   * a gaussian distribution with sigma determined by q.
   */
  {
    double i;
    int next, j;
John Koleszar's avatar
John Koleszar committed
388

John Koleszar's avatar
John Koleszar committed
389
    next = 0;
John Koleszar's avatar
John Koleszar committed
390

John Koleszar's avatar
John Koleszar committed
391
    for (i = -32; i < 32; i++) {
392
      int a = (int)(.5 + 256 * vp9_gaussian(sigma, 0, i));
John Koleszar's avatar
John Koleszar committed
393

John Koleszar's avatar
John Koleszar committed
394
395
396
      if (a) {
        for (j = 0; j < a; j++) {
          char_dist[next + j] = (char) i;
John Koleszar's avatar
John Koleszar committed
397
398
        }

John Koleszar's avatar
John Koleszar committed
399
400
        next = next + j;
      }
John Koleszar's avatar
John Koleszar committed
401
402
403

    }

John Koleszar's avatar
John Koleszar committed
404
405
406
407
408
409
410
    for (next = next; next < 256; next++)
      char_dist[next] = 0;
  }

  for (i = 0; i < 3072; i++) {
    state->noise[i] = char_dist[rand() & 0xff];
  }
John Koleszar's avatar
John Koleszar committed
411

John Koleszar's avatar
John Koleszar committed
412
413
414
415
416
417
418
419
  for (i = 0; i < 16; i++) {
    state->blackclamp[i] = -char_dist[0];
    state->whiteclamp[i] = -char_dist[0];
    state->bothclamp[i] = -2 * char_dist[0];
  }

  state->last_q = q;
  state->last_noise = a;
John Koleszar's avatar
John Koleszar committed
420
421
422
423
424
425
}

/****************************************************************************
 *
 *  ROUTINE       : plane_add_noise_c
 *
426
427
 *  INPUTS        : unsigned char *Start  starting address of buffer to
 *                                        add gaussian noise to
John Koleszar's avatar
John Koleszar committed
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
 *                  unsigned int Width    width of plane
 *                  unsigned int Height   height of plane
 *                  int  Pitch    distance between subsequent lines of frame
 *                  int  q        quantizer used to determine amount of noise
 *                                  to add
 *
 *  OUTPUTS       : None.
 *
 *  RETURNS       : void.
 *
 *  FUNCTION      : adds gaussian noise to a plane of pixels
 *
 *  SPECIAL NOTES : None.
 *
 ****************************************************************************/
443
void vp9_plane_add_noise_c(unsigned char *Start, char *noise,
John Koleszar's avatar
John Koleszar committed
444
445
446
                           char blackclamp[16],
                           char whiteclamp[16],
                           char bothclamp[16],
John Koleszar's avatar
John Koleszar committed
447
448
                           unsigned int Width, unsigned int Height, int Pitch) {
  unsigned int i, j;
John Koleszar's avatar
John Koleszar committed
449

John Koleszar's avatar
John Koleszar committed
450
451
452
  for (i = 0; i < Height; i++) {
    unsigned char *Pos = Start + i * Pitch;
    char  *Ref = (char *)(noise + (rand() & 0xff));
John Koleszar's avatar
John Koleszar committed
453

John Koleszar's avatar
John Koleszar committed
454
455
456
    for (j = 0; j < Width; j++) {
      if (Pos[j] < blackclamp[0])
        Pos[j] = blackclamp[0];
John Koleszar's avatar
John Koleszar committed
457

John Koleszar's avatar
John Koleszar committed
458
459
      if (Pos[j] > 255 + whiteclamp[0])
        Pos[j] = 255 + whiteclamp[0];
John Koleszar's avatar
John Koleszar committed
460

John Koleszar's avatar
John Koleszar committed
461
      Pos[j] += Ref[j];
John Koleszar's avatar
John Koleszar committed
462
    }
John Koleszar's avatar
John Koleszar committed
463
  }
John Koleszar's avatar
John Koleszar committed
464
465
}

466
467
468
469
/* Blend the macro block with a solid colored square.  Leave the
 * edges unblended to give distinction to macro blocks in areas
 * filled with the same color block.
 */
470
void vp9_blend_mb_inner_c(unsigned char *y, unsigned char *u, unsigned char *v,
John Koleszar's avatar
John Koleszar committed
471
472
473
474
475
476
477
478
479
480
                          int y1, int u1, int v1, int alpha, int stride) {
  int i, j;
  int y1_const = y1 * ((1 << 16) - alpha);
  int u1_const = u1 * ((1 << 16) - alpha);
  int v1_const = v1 * ((1 << 16) - alpha);

  y += 2 * stride + 2;
  for (i = 0; i < 12; i++) {
    for (j = 0; j < 12; j++) {
      y[j] = (y[j] * alpha + y1_const) >> 16;
481
    }
John Koleszar's avatar
John Koleszar committed
482
483
    y += stride;
  }
484

John Koleszar's avatar
John Koleszar committed
485
  stride >>= 1;
486

John Koleszar's avatar
John Koleszar committed
487
488
  u += stride + 1;
  v += stride + 1;
489

John Koleszar's avatar
John Koleszar committed
490
491
492
493
  for (i = 0; i < 6; i++) {
    for (j = 0; j < 6; j++) {
      u[j] = (u[j] * alpha + u1_const) >> 16;
      v[j] = (v[j] * alpha + v1_const) >> 16;
494
    }
John Koleszar's avatar
John Koleszar committed
495
496
497
    u += stride;
    v += stride;
  }
498
}
John Koleszar's avatar
John Koleszar committed
499

500
501
502
/* Blend only the edge of the macro block.  Leave center
 * unblended to allow for other visualizations to be layered.
 */
503
void vp9_blend_mb_outer_c(unsigned char *y, unsigned char *u, unsigned char *v,
John Koleszar's avatar
John Koleszar committed
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
                          int y1, int u1, int v1, int alpha, int stride) {
  int i, j;
  int y1_const = y1 * ((1 << 16) - alpha);
  int u1_const = u1 * ((1 << 16) - alpha);
  int v1_const = v1 * ((1 << 16) - alpha);

  for (i = 0; i < 2; i++) {
    for (j = 0; j < 16; j++) {
      y[j] = (y[j] * alpha + y1_const) >> 16;
    }
    y += stride;
  }

  for (i = 0; i < 12; i++) {
    y[0]  = (y[0] * alpha  + y1_const) >> 16;
    y[1]  = (y[1] * alpha  + y1_const) >> 16;
    y[14] = (y[14] * alpha + y1_const) >> 16;
    y[15] = (y[15] * alpha + y1_const) >> 16;
    y += stride;
  }

  for (i = 0; i < 2; i++) {
    for (j = 0; j < 16; j++) {
      y[j] = (y[j] * alpha + y1_const) >> 16;
    }
    y += stride;
  }

  stride >>= 1;

  for (j = 0; j < 8; j++) {
    u[j] = (u[j] * alpha + u1_const) >> 16;
    v[j] = (v[j] * alpha + v1_const) >> 16;
  }
  u += stride;
  v += stride;

  for (i = 0; i < 6; i++) {
    u[0] = (u[0] * alpha + u1_const) >> 16;
    v[0] = (v[0] * alpha + v1_const) >> 16;

    u[7] = (u[7] * alpha + u1_const) >> 16;
    v[7] = (v[7] * alpha + v1_const) >> 16;
547
548
549

    u += stride;
    v += stride;
John Koleszar's avatar
John Koleszar committed
550
  }
551

John Koleszar's avatar
John Koleszar committed
552
553
554
555
  for (j = 0; j < 8; j++) {
    u[j] = (u[j] * alpha + u1_const) >> 16;
    v[j] = (v[j] * alpha + v1_const) >> 16;
  }
556
557
}

558
void vp9_blend_b_c(unsigned char *y, unsigned char *u, unsigned char *v,
John Koleszar's avatar
John Koleszar committed
559
560
561
562
563
564
565
566
567
                   int y1, int u1, int v1, int alpha, int stride) {
  int i, j;
  int y1_const = y1 * ((1 << 16) - alpha);
  int u1_const = u1 * ((1 << 16) - alpha);
  int v1_const = v1 * ((1 << 16) - alpha);

  for (i = 0; i < 4; i++) {
    for (j = 0; j < 4; j++) {
      y[j] = (y[j] * alpha + y1_const) >> 16;
568
    }
John Koleszar's avatar
John Koleszar committed
569
570
    y += stride;
  }
571

John Koleszar's avatar
John Koleszar committed
572
  stride >>= 1;
573

John Koleszar's avatar
John Koleszar committed
574
575
576
577
  for (i = 0; i < 2; i++) {
    for (j = 0; j < 2; j++) {
      u[j] = (u[j] * alpha + u1_const) >> 16;
      v[j] = (v[j] * alpha + v1_const) >> 16;
578
    }
John Koleszar's avatar
John Koleszar committed
579
580
581
    u += stride;
    v += stride;
  }
582
583
}

584
585
static void constrain_line(int x0, int *x1, int y0, int *y1,
                           int width, int height) {
John Koleszar's avatar
John Koleszar committed
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
  int dx;
  int dy;

  if (*x1 > width) {
    dx = *x1 - x0;
    dy = *y1 - y0;

    *x1 = width;
    if (dx)
      *y1 = ((width - x0) * dy) / dx + y0;
  }
  if (*x1 < 0) {
    dx = *x1 - x0;
    dy = *y1 - y0;

    *x1 = 0;
    if (dx)
      *y1 = ((0 - x0) * dy) / dx + y0;
  }
  if (*y1 > height) {
    dx = *x1 - x0;
    dy = *y1 - y0;

    *y1 = height;
    if (dy)
      *x1 = ((height - y0) * dx) / dy + x0;
  }
  if (*y1 < 0) {
    dx = *x1 - x0;
    dy = *y1 - y0;

    *y1 = 0;
    if (dy)
      *x1 = ((0 - y0) * dx) / dy + x0;
  }
621
622
}

623
624
625
626
627
628
629

#if CONFIG_RUNTIME_CPU_DETECT
#define RTCD_VTABLE(oci) (&(oci)->rtcd.postproc)
#else
#define RTCD_VTABLE(oci) NULL
#endif

630
631
int vp9_post_proc_frame(VP9_COMMON *oci, YV12_BUFFER_CONFIG *dest,
                        vp9_ppflags_t *ppflags) {
John Koleszar's avatar
John Koleszar committed
632
633
634
635
  int q = oci->filter_level * 10 / 6;
  int flags = ppflags->post_proc_flag;
  int deblock_level = ppflags->deblocking_level;
  int noise_level = ppflags->noise_level;
John Koleszar's avatar
John Koleszar committed
636

John Koleszar's avatar
John Koleszar committed
637
638
  if (!oci->frame_to_show)
    return -1;
John Koleszar's avatar
John Koleszar committed
639

John Koleszar's avatar
John Koleszar committed
640
641
  if (q > 63)
    q = 63;
John Koleszar's avatar
John Koleszar committed
642

John Koleszar's avatar
John Koleszar committed
643
644
  if (!flags) {
    *dest = *oci->frame_to_show;
John Koleszar's avatar
John Koleszar committed
645

John Koleszar's avatar
John Koleszar committed
646
647
648
649
650
    /* handle problem with extending borders */
    dest->y_width = oci->Width;
    dest->y_height = oci->Height;
    dest->uv_height = dest->y_height / 2;
    return 0;
John Koleszar's avatar
John Koleszar committed
651

John Koleszar's avatar
John Koleszar committed
652
  }
John Koleszar's avatar
John Koleszar committed
653
654

#if ARCH_X86||ARCH_X86_64
John Koleszar's avatar
John Koleszar committed
655
  vpx_reset_mmx_state();
John Koleszar's avatar
John Koleszar committed
656
657
#endif

658
659
660
661
662
  if (flags & VP9D_DEMACROBLOCK) {
    deblock_and_de_macro_block(oci->frame_to_show, &oci->post_proc_buffer,
                               q + (deblock_level - 5) * 10, 1, 0,
                               RTCD_VTABLE(oci));
  } else if (flags & VP9D_DEBLOCK) {
663
    vp9_deblock(oci->frame_to_show, &oci->post_proc_buffer,
John Koleszar's avatar
John Koleszar committed
664
665
                q, 1, 0, RTCD_VTABLE(oci));
  } else {
John Koleszar's avatar
John Koleszar committed
666
    vp8_yv12_copy_frame(oci->frame_to_show, &oci->post_proc_buffer);
John Koleszar's avatar
John Koleszar committed
667
668
  }

669
  if (flags & VP9D_ADDNOISE) {
John Koleszar's avatar
John Koleszar committed
670
671
672
673
674
    if (oci->postproc_state.last_q != q
        || oci->postproc_state.last_noise != noise_level) {
      fillrd(&oci->postproc_state, 63 - q, noise_level);
    }

675
676
677
678
679
680
681
682
    POSTPROC_INVOKE(RTCD_VTABLE(oci), addnoise)(oci->post_proc_buffer.y_buffer,
                                                oci->postproc_state.noise,
                                                oci->postproc_state.blackclamp,
                                                oci->postproc_state.whiteclamp,
                                                oci->postproc_state.bothclamp,
                                                oci->post_proc_buffer.y_width,
                                                oci->post_proc_buffer.y_height,
                                                oci->post_proc_buffer.y_stride);
John Koleszar's avatar
John Koleszar committed
683
  }
John Koleszar's avatar
John Koleszar committed
684

685
#if CONFIG_POSTPROC_VISUALIZER
686
  if (flags & VP9D_DEBUG_TXT_FRAME_INFO) {
John Koleszar's avatar
John Koleszar committed
687
688
689
690
691
692
693
694
    char message[512];
    sprintf(message, "F%1dG%1dQ%3dF%3dP%d_s%dx%d",
            (oci->frame_type == KEY_FRAME),
            oci->refresh_golden_frame,
            oci->base_qindex,
            oci->filter_level,
            flags,
            oci->mb_cols, oci->mb_rows);
695
696
    vp9_blit_text(message, oci->post_proc_buffer.y_buffer,
                  oci->post_proc_buffer.y_stride);
John Koleszar's avatar
John Koleszar committed
697
698
  }

699
  if (flags & VP9D_DEBUG_TXT_MBLK_MODES) {
John Koleszar's avatar
John Koleszar committed
700
701
702
703
704
705
706
    int i, j;
    unsigned char *y_ptr;
    YV12_BUFFER_CONFIG *post = &oci->post_proc_buffer;
    int mb_rows = post->y_height >> 4;
    int mb_cols = post->y_width  >> 4;
    int mb_index = 0;
    MODE_INFO *mi = oci->mi;
John Koleszar's avatar
John Koleszar committed
707

John Koleszar's avatar
John Koleszar committed
708
    y_ptr = post->y_buffer + 4 * post->y_stride + 4;
John Koleszar's avatar
John Koleszar committed
709

710
    /* vp9_filter each macro block */
John Koleszar's avatar
John Koleszar committed
711
712
713
    for (i = 0; i < mb_rows; i++) {
      for (j = 0; j < mb_cols; j++) {
        char zz[4];
714

John Koleszar's avatar
John Koleszar committed
715
        sprintf(zz, "%c", mi[mb_index].mbmi.mode + 'a');
John Koleszar's avatar
John Koleszar committed
716

717
        vp9_blit_text(zz, y_ptr, post->y_stride);
John Koleszar's avatar
John Koleszar committed
718
719
720
        mb_index++;
        y_ptr += 16;
      }
John Koleszar's avatar
John Koleszar committed
721

John Koleszar's avatar
John Koleszar committed
722
723
      mb_index++; /* border */
      y_ptr += post->y_stride  * 16 - post->y_width;
724

John Koleszar's avatar
John Koleszar committed
725
    }
John Koleszar's avatar
John Koleszar committed
726
  }
727

728
  if (flags & VP9D_DEBUG_TXT_DC_DIFF) {
John Koleszar's avatar
John Koleszar committed
729
730
731
732
733
734
735
736
737
738
    int i, j;
    unsigned char *y_ptr;
    YV12_BUFFER_CONFIG *post = &oci->post_proc_buffer;
    int mb_rows = post->y_height >> 4;
    int mb_cols = post->y_width  >> 4;
    int mb_index = 0;
    MODE_INFO *mi = oci->mi;

    y_ptr = post->y_buffer + 4 * post->y_stride + 4;

739
    /* vp9_filter each macro block */
John Koleszar's avatar
John Koleszar committed
740
741
742
743
744
745
746
747
748
749
750
751
    for (i = 0; i < mb_rows; i++) {
      for (j = 0; j < mb_cols; j++) {
        char zz[4];
        int dc_diff = !(mi[mb_index].mbmi.mode != B_PRED &&
                        mi[mb_index].mbmi.mode != SPLITMV &&
                        mi[mb_index].mbmi.mb_skip_coeff);

        if (oci->frame_type == KEY_FRAME)
          sprintf(zz, "a");
        else
          sprintf(zz, "%c", dc_diff + '0');

752
        vp9_blit_text(zz, y_ptr, post->y_stride);
John Koleszar's avatar
John Koleszar committed
753
754
755
756
757
758
759
760
761
762
        mb_index++;
        y_ptr += 16;
      }

      mb_index++; /* border */
      y_ptr += post->y_stride  * 16 - post->y_width;

    }
  }

763
  if (flags & VP9D_DEBUG_TXT_RATE_INFO) {
John Koleszar's avatar
John Koleszar committed
764
    char message[512];
765
766
767
768
769
    snprintf(message, sizeof(message),
             "Bitrate: %10.2f frame_rate: %10.2f ",
             oci->bitrate, oci->framerate);
    vp9_blit_text(message, oci->post_proc_buffer.y_buffer,
                  oci->post_proc_buffer.y_stride);
John Koleszar's avatar
John Koleszar committed
770
771
772
  }

  /* Draw motion vectors */
773
  if ((flags & VP9D_DEBUG_DRAW_MV) && ppflags->display_mv_flag) {
John Koleszar's avatar
John Koleszar committed
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
    YV12_BUFFER_CONFIG *post = &oci->post_proc_buffer;
    int width  = post->y_width;
    int height = post->y_height;
    unsigned char *y_buffer = oci->post_proc_buffer.y_buffer;
    int y_stride = oci->post_proc_buffer.y_stride;
    MODE_INFO *mi = oci->mi;
    int x0, y0;

    for (y0 = 0; y0 < height; y0 += 16) {
      for (x0 = 0; x0 < width; x0 += 16) {
        int x1, y1;

        if (!(ppflags->display_mv_flag & (1 << mi->mbmi.mode))) {
          mi++;
          continue;
        }
790

John Koleszar's avatar
John Koleszar committed
791
792
        if (mi->mbmi.mode == SPLITMV) {
          switch (mi->mbmi.partitioning) {
793
            case PARTITIONING_16X8 : {  /* mv_top_bottom */
John Koleszar's avatar
John Koleszar committed
794
795
              union b_mode_info *bmi = &mi->bmi[0];
              MV *mv = &bmi->mv.as_mv;
796

John Koleszar's avatar
John Koleszar committed
797
798
              x1 = x0 + 8 + (mv->col >> 3);
              y1 = y0 + 4 + (mv->row >> 3);
799

John Koleszar's avatar
John Koleszar committed
800
              constrain_line(x0 + 8, &x1, y0 + 4, &y1, width, height);
801
              vp9_blit_line(x0 + 8,  x1, y0 + 4,  y1, y_buffer, y_stride);
802

John Koleszar's avatar
John Koleszar committed
803
              bmi = &mi->bmi[8];
804

John Koleszar's avatar
John Koleszar committed
805
806
              x1 = x0 + 8 + (mv->col >> 3);
              y1 = y0 + 12 + (mv->row >> 3);
807

John Koleszar's avatar
John Koleszar committed
808
              constrain_line(x0 + 8, &x1, y0 + 12, &y1, width, height);
809
              vp9_blit_line(x0 + 8,  x1, y0 + 12,  y1, y_buffer, y_stride);
810

John Koleszar's avatar
John Koleszar committed
811
812
              break;
            }
813
            case PARTITIONING_8X16 : {  /* mv_left_right */
John Koleszar's avatar
John Koleszar committed
814
815
              union b_mode_info *bmi = &mi->bmi[0];
              MV *mv = &bmi->mv.as_mv;
816

John Koleszar's avatar
John Koleszar committed
817
818
              x1 = x0 + 4 + (mv->col >> 3);
              y1 = y0 + 8 + (mv->row >> 3);
819

John Koleszar's avatar
John Koleszar committed
820
              constrain_line(x0 + 4, &x1, y0 + 8, &y1, width, height);
821
              vp9_blit_line(x0 + 4,  x1, y0 + 8,  y1, y_buffer, y_stride);
822

John Koleszar's avatar
John Koleszar committed
823
              bmi = &mi->bmi[2];
824

John Koleszar's avatar
John Koleszar committed
825
826
              x1 = x0 + 12 + (mv->col >> 3);
              y1 = y0 + 8 + (mv->row >> 3);
827

John Koleszar's avatar
John Koleszar committed
828
              constrain_line(x0 + 12, &x1, y0 + 8, &y1, width, height);
829
              vp9_blit_line(x0 + 12,  x1, y0 + 8,  y1, y_buffer, y_stride);
830

John Koleszar's avatar
John Koleszar committed
831
832
              break;
            }
833
            case PARTITIONING_8X8 : {  /* mv_quarters   */
John Koleszar's avatar
John Koleszar committed
834
835
              union b_mode_info *bmi = &mi->bmi[0];
              MV *mv = &bmi->mv.as_mv;
836

John Koleszar's avatar
John Koleszar committed
837
838
              x1 = x0 + 4 + (mv->col >> 3);
              y1 = y0 + 4 + (mv->row >> 3);
839

John Koleszar's avatar
John Koleszar committed
840
              constrain_line(x0 + 4, &x1, y0 + 4, &y1, width, height);
841
              vp9_blit_line(x0 + 4,  x1, y0 + 4,  y1, y_buffer, y_stride);
842

John Koleszar's avatar
John Koleszar committed
843
              bmi = &mi->bmi[2];
844

John Koleszar's avatar
John Koleszar committed
845
846
              x1 = x0 + 12 + (mv->col >> 3);
              y1 = y0 + 4 + (mv->row >> 3);
847

John Koleszar's avatar
John Koleszar committed
848
              constrain_line(x0 + 12, &x1, y0 + 4, &y1, width, height);
849
              vp9_blit_line(x0 + 12,  x1, y0 + 4,  y1, y_buffer, y_stride);
850

John Koleszar's avatar
John Koleszar committed
851
              bmi = &mi->bmi[8];
852

John Koleszar's avatar
John Koleszar committed
853
854
              x1 = x0 + 4 + (mv->col >> 3);
              y1 = y0 + 12 + (mv->row >> 3);
855

John Koleszar's avatar
John Koleszar committed
856
              constrain_line(x0 + 4, &x1, y0 + 12, &y1, width, height);
857
              vp9_blit_line(x0 + 4,  x1, y0 + 12,  y1, y_buffer, y_stride);
858

John Koleszar's avatar
John Koleszar committed
859
              bmi = &mi->bmi[10];
860

John Koleszar's avatar
John Koleszar committed
861
862
              x1 = x0 + 12 + (mv->col >> 3);
              y1 = y0 + 12 + (mv->row >> 3);
863

John Koleszar's avatar
John Koleszar committed
864
              constrain_line(x0 + 12, &x1, y0 + 12, &y1, width, height);
865
              vp9_blit_line(x0 + 12,  x1, y0 + 12,  y1, y_buffer, y_stride);
John Koleszar's avatar
John Koleszar committed
866
867
              break;
            }
868
            case PARTITIONING_4X4:
John Koleszar's avatar
John Koleszar committed
869
870
871
            default : {
              union b_mode_info *bmi = mi->bmi;
              int bx0, by0;
872

John Koleszar's avatar
John Koleszar committed
873
874
875
              for (by0 = y0; by0 < (y0 + 16); by0 += 4) {
                for (bx0 = x0; bx0 < (x0 + 16); bx0 += 4) {
                  MV *mv = &bmi->mv.as_mv;
876

John Koleszar's avatar
John Koleszar committed
877
878
                  x1 = bx0 + 2 + (mv->col >> 3);
                  y1 = by0 + 2 + (mv->row >> 3);
879

John Koleszar's avatar
John Koleszar committed
880
                  constrain_line(bx0 + 2, &x1, by0 + 2, &y1, width, height);
881
                  vp9_blit_line(bx0 + 2,  x1, by0 + 2,  y1, y_buffer, y_stride);
882

John Koleszar's avatar
John Koleszar committed
883
                  bmi++;
884
                }
John Koleszar's avatar
John Koleszar committed
885
              }
886
            }
John Koleszar's avatar
John Koleszar committed
887
888
889
890
891
892
893
894
895
896
897
          }
        } else if (mi->mbmi.mode >= NEARESTMV) {
          MV *mv = &mi->mbmi.mv.as_mv;
          const int lx0 = x0 + 8;
          const int ly0 = y0 + 8;

          x1 = lx0 + (mv->col >> 3);
          y1 = ly0 + (mv->row >> 3);

          if (x1 != lx0 && y1 != ly0) {
            constrain_line(lx0, &x1, ly0 - 1, &y1, width, height);
898
            vp9_blit_line(lx0,  x1, ly0 - 1,  y1, y_buffer, y_stride);
John Koleszar's avatar
John Koleszar committed
899
900

            constrain_line(lx0, &x1, ly0 + 1, &y1, width, height);
901
            vp9_blit_line(lx0,  x1, ly0 + 1,  y1, y_buffer, y_stride);
John Koleszar's avatar
John Koleszar committed
902
          } else
903
            vp9_blit_line(lx0,  x1, ly0,  y1, y_buffer, y_stride);
904
        }
John Koleszar's avatar
John Koleszar committed
905

John Koleszar's avatar
John Koleszar committed
906
907
908
909
910
911
912
        mi++;
      }
      mi++;
    }
  }

  /* Color in block modes */
913
  if ((flags & VP9D_DEBUG_CLR_BLK_MODES)
John Koleszar's avatar
John Koleszar committed
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
      && (ppflags->display_mb_modes_flag || ppflags->display_b_modes_flag)) {
    int y, x;
    YV12_BUFFER_CONFIG *post = &oci->post_proc_buffer;
    int width  = post->y_width;
    int height = post->y_height;
    unsigned char *y_ptr = oci->post_proc_buffer.y_buffer;
    unsigned char *u_ptr = oci->post_proc_buffer.u_buffer;
    unsigned char *v_ptr = oci->post_proc_buffer.v_buffer;
    int y_stride = oci->post_proc_buffer.y_stride;
    MODE_INFO *mi = oci->mi;

    for (y = 0; y < height; y += 16) {
      for (x = 0; x < width; x += 16) {
        int Y = 0, U = 0, V = 0;

        if (mi->mbmi.mode == B_PRED &&
930
931
            ((ppflags->display_mb_modes_flag & B_PRED) ||
             ppflags->display_b_modes_flag)) {
John Koleszar's avatar
John Koleszar committed
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
          int by, bx;
          unsigned char *yl, *ul, *vl;
          union b_mode_info *bmi = mi->bmi;

          yl = y_ptr + x;
          ul = u_ptr + (x >> 1);
          vl = v_ptr + (x >> 1);

          for (by = 0; by < 16; by += 4) {
            for (bx = 0; bx < 16; bx += 4) {
              if ((ppflags->display_b_modes_flag & (1 << mi->mbmi.mode))
                  || (ppflags->display_mb_modes_flag & B_PRED)) {
                Y = B_PREDICTION_MODE_colors[bmi->as_mode.first][0];
                U = B_PREDICTION_MODE_colors[bmi->as_mode.first][1];
                V = B_PREDICTION_MODE_colors[bmi->as_mode.first][2];

948
949
950
951
952
                POSTPROC_INVOKE(RTCD_VTABLE(oci), blend_b)(yl + bx,
                                                           ul + (bx >> 1),
                                                           vl + (bx >> 1),
                                                           Y, U, V,
                                                           0xc000, y_stride);
John Koleszar's avatar
John Koleszar committed
953
954
              }
              bmi++;
955
956
            }

John Koleszar's avatar
John Koleszar committed
957
958
959
960
961
962
963
964
965
            yl += y_stride * 4;
            ul += y_stride * 1;
            vl += y_stride * 1;
          }
        } else if (ppflags->display_mb_modes_flag & (1 << mi->mbmi.mode)) {
          Y = MB_PREDICTION_MODE_colors[mi->mbmi.mode][0];
          U = MB_PREDICTION_MODE_colors[mi->mbmi.mode][1];
          V = MB_PREDICTION_MODE_colors[mi->mbmi.mode][2];

966
967
968
969
970
          POSTPROC_INVOKE(RTCD_VTABLE(oci), blend_mb_inner)(y_ptr + x,
                                                            u_ptr + (x >> 1),
                                                            v_ptr + (x >> 1),
                                                            Y, U, V,
                                                            0xc000, y_stride);
971
972
        }

John Koleszar's avatar
John Koleszar committed
973
974
975
976
977
978
979
980
981
982
983
        mi++;
      }
      y_ptr += y_stride * 16;
      u_ptr += y_stride * 4;
      v_ptr += y_stride * 4;

      mi++;
    }
  }

  /* Color in frame reference blocks */
984
985
  if ((flags & VP9D_DEBUG_CLR_FRM_REF_BLKS) &&
      ppflags->display_ref_frame_flag) {
John Koleszar's avatar
John Koleszar committed
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
    int y, x;
    YV12_BUFFER_CONFIG *post = &oci->post_proc_buffer;
    int width  = post->y_width;
    int height = post->y_height;
    unsigned char *y_ptr = oci->post_proc_buffer.y_buffer;
    unsigned char *u_ptr = oci->post_proc_buffer.u_buffer;
    unsigned char *v_ptr = oci->post_proc_buffer.v_buffer;
    int y_stride = oci->post_proc_buffer.y_stride;
    MODE_INFO *mi = oci->mi;

    for (y = 0; y < height; y += 16) {
      for (x = 0; x < width; x += 16) {
        int Y = 0, U = 0, V = 0;

        if (ppflags->display_ref_frame_flag & (1 << mi->mbmi.ref_frame)) {
          Y = MV_REFERENCE_FRAME_colors[mi->mbmi.ref_frame][0];
          U = MV_REFERENCE_FRAME_colors[mi->mbmi.ref_frame][1];
          V = MV_REFERENCE_FRAME_colors[mi->mbmi.ref_frame][2];

1005
1006
1007
1008
1009
          POSTPROC_INVOKE(RTCD_VTABLE(oci), blend_mb_outer)(y_ptr + x,
                                                            u_ptr + (x >> 1),
                                                            v_ptr + (x >> 1),
                                                            Y, U, V,
                                                            0xc000, y_stride);
John Koleszar's avatar
John Koleszar committed
1010
        }
1011

John Koleszar's avatar
John Koleszar committed
1012
1013
1014
1015
1016
        mi++;
      }
      y_ptr += y_stride * 16;
      u_ptr += y_stride * 4;
      v_ptr += y_stride * 4;
1017

John Koleszar's avatar
John Koleszar committed
1018
      mi++;
1019
    }
John Koleszar's avatar
John Koleszar committed
1020
  }
1021
#endif
1022

John Koleszar's avatar
John Koleszar committed
1023
  *dest = oci->post_proc_buffer;
John Koleszar's avatar
John Koleszar committed
1024

John Koleszar's avatar
John Koleszar committed
1025
1026
1027
1028
  /* handle problem with extending borders */
  dest->y_width = oci->Width;
  dest->y_height = oci->Height;
  dest->uv_height = dest->y_height / 2;
1029

John Koleszar's avatar
John Koleszar committed
1030
  return 0;
John Koleszar's avatar
John Koleszar committed
1031
}