vp9_postproc.c 29.7 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"
Jim Bankoski's avatar
Jim Bankoski committed
18
19
#include "./vp9_rtcd.h"

John Koleszar's avatar
John Koleszar committed
20
21
22
23

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

25
26
27
28
29
30
31
#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)
32

33
/* global constants */
34
#if CONFIG_POSTPROC_VISUALIZER
John Koleszar's avatar
John Koleszar committed
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
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 */
53
54
};

John Koleszar's avatar
John Koleszar committed
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
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 */
70
71
};

John Koleszar's avatar
John Koleszar committed
72
73
74
75
76
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 */
77
};
78
#endif
79

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

84
const short vp9_rv[] = {
John Koleszar's avatar
John Koleszar committed
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
127
128
  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
129
130
131
};


132
/****************************************************************************
John Koleszar's avatar
John Koleszar committed
133
 */
134
135
136
137
138
139
140
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
141
142
143
144
145
146
147
148
  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
149

John Koleszar's avatar
John Koleszar committed
150
151
152
153
  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
154

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

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

John Koleszar's avatar
John Koleszar committed
160
161
162
      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
163

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

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

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

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

John Koleszar's avatar
John Koleszar committed
179
180
181
182
183
184
185
186
187
    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
188

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

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

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

John Koleszar's avatar
John Koleszar committed
199
200
201
202
    /* 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
203

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

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

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

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
219
  int r, c, i;
John Koleszar's avatar
John Koleszar committed
220

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


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

John Koleszar's avatar
John Koleszar committed
229
230
231
232
233
    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
234

John Koleszar's avatar
John Koleszar committed
235
236
237
    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
238

John Koleszar's avatar
John Koleszar committed
239
240
      sum  += x;
      sumsq += x * y;
John Koleszar's avatar
John Koleszar committed
241

John Koleszar's avatar
John Koleszar committed
242
243
244
245
246
      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
247

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

    s += pitch;
  }
John Koleszar's avatar
John Koleszar committed
253
254
}

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

John Koleszar's avatar
John Koleszar committed
260
261
262
263
264
265
  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
266

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

John Koleszar's avatar
John Koleszar committed
272
273
274
275
    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
276

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

John Koleszar's avatar
John Koleszar committed
281
282
      s[-8 * pitch] = d[(r - 8) & 15];
      s += pitch;
John Koleszar's avatar
John Koleszar committed
283
    }
John Koleszar's avatar
John Koleszar committed
284
  }
John Koleszar's avatar
John Koleszar committed
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,
Jim Bankoski's avatar
Jim Bankoski committed
291
                                       int                   flag) {
John Koleszar's avatar
John Koleszar committed
292
293
294
295
296
  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;

Jim Bankoski's avatar
Jim Bankoski committed
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
  vp9_post_proc_down_and_across(source->y_buffer, post->y_buffer,
                                source->y_stride, post->y_stride,
                                source->y_height, source->y_width, ppl);

  vp9_mbpost_proc_across_ip(post->y_buffer, post->y_stride, post->y_height,
                            post->y_width, q2mbl(q));

  vp9_mbpost_proc_down(post->y_buffer, post->y_stride, post->y_height,
                       post->y_width, q2mbl(q));

  vp9_post_proc_down_and_across(source->u_buffer, post->u_buffer,
                                source->uv_stride, post->uv_stride,
                                source->uv_height, source->uv_width, ppl);
  vp9_post_proc_down_and_across(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
313
314
}

315
void vp9_deblock(YV12_BUFFER_CONFIG         *source,
John Koleszar's avatar
John Koleszar committed
316
317
318
                 YV12_BUFFER_CONFIG         *post,
                 int                         q,
                 int                         low_var_thresh,
Jim Bankoski's avatar
Jim Bankoski committed
319
                 int                         flag) {
John Koleszar's avatar
John Koleszar committed
320
321
322
323
324
  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;

Jim Bankoski's avatar
Jim Bankoski committed
325
326
327
328
329
330
331
332
333
334
335
  vp9_post_proc_down_and_across(source->y_buffer, post->y_buffer,
                                source->y_stride, post->y_stride,
                                source->y_height, source->y_width, ppl);

  vp9_post_proc_down_and_across(source->u_buffer, post->u_buffer,
                                source->uv_stride, post->uv_stride,
                                source->uv_height, source->uv_width, ppl);

  vp9_post_proc_down_and_across(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
336
337
}

338
void vp9_de_noise(YV12_BUFFER_CONFIG         *src,
John Koleszar's avatar
John Koleszar committed
339
340
341
                  YV12_BUFFER_CONFIG         *post,
                  int                         q,
                  int                         low_var_thresh,
Jim Bankoski's avatar
Jim Bankoski committed
342
                  int                         flag) {
John Koleszar's avatar
John Koleszar committed
343
344
345
346
347
348
  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;

Jim Bankoski's avatar
Jim Bankoski committed
349
350
351
352
353
354
355
356
357
358
359
360
361
362
  vp9_post_proc_down_and_across(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);

  vp9_post_proc_down_and_across(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);

  vp9_post_proc_down_and_across(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
363
364
}

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

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

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

376
  vp9_clear_system_state();
John Koleszar's avatar
John Koleszar committed
377

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

John Koleszar's avatar
John Koleszar committed
380
381
382
383
384
385
  /* 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
386

John Koleszar's avatar
John Koleszar committed
387
    next = 0;
John Koleszar's avatar
John Koleszar committed
388

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

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

John Koleszar's avatar
John Koleszar committed
397
398
        next = next + j;
      }
John Koleszar's avatar
John Koleszar committed
399
400
401

    }

John Koleszar's avatar
John Koleszar committed
402
403
404
405
406
407
408
    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
409

John Koleszar's avatar
John Koleszar committed
410
411
412
413
414
415
416
417
  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
418
419
420
421
422
423
}

/****************************************************************************
 *
 *  ROUTINE       : plane_add_noise_c
 *
424
425
 *  INPUTS        : unsigned char *Start  starting address of buffer to
 *                                        add gaussian noise to
John Koleszar's avatar
John Koleszar committed
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
 *                  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.
 *
 ****************************************************************************/
441
void vp9_plane_add_noise_c(unsigned char *Start, char *noise,
John Koleszar's avatar
John Koleszar committed
442
443
444
                           char blackclamp[16],
                           char whiteclamp[16],
                           char bothclamp[16],
John Koleszar's avatar
John Koleszar committed
445
446
                           unsigned int Width, unsigned int Height, int Pitch) {
  unsigned int i, j;
John Koleszar's avatar
John Koleszar committed
447

John Koleszar's avatar
John Koleszar committed
448
449
450
  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
451

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

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

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

464
465
466
467
/* 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.
 */
468
void vp9_blend_mb_inner_c(unsigned char *y, unsigned char *u, unsigned char *v,
John Koleszar's avatar
John Koleszar committed
469
470
471
472
473
474
475
476
477
478
                          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;
479
    }
John Koleszar's avatar
John Koleszar committed
480
481
    y += stride;
  }
482

John Koleszar's avatar
John Koleszar committed
483
  stride >>= 1;
484

John Koleszar's avatar
John Koleszar committed
485
486
  u += stride + 1;
  v += stride + 1;
487

John Koleszar's avatar
John Koleszar committed
488
489
490
491
  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;
492
    }
John Koleszar's avatar
John Koleszar committed
493
494
495
    u += stride;
    v += stride;
  }
496
}
John Koleszar's avatar
John Koleszar committed
497

498
499
500
/* Blend only the edge of the macro block.  Leave center
 * unblended to allow for other visualizations to be layered.
 */
501
void vp9_blend_mb_outer_c(unsigned char *y, unsigned char *u, unsigned char *v,
John Koleszar's avatar
John Koleszar committed
502
503
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
                          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;
545
546
547

    u += stride;
    v += stride;
John Koleszar's avatar
John Koleszar committed
548
  }
549

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

556
void vp9_blend_b_c(unsigned char *y, unsigned char *u, unsigned char *v,
John Koleszar's avatar
John Koleszar committed
557
558
559
560
561
562
563
564
565
                   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;
566
    }
John Koleszar's avatar
John Koleszar committed
567
568
    y += stride;
  }
569

John Koleszar's avatar
John Koleszar committed
570
  stride >>= 1;
571

John Koleszar's avatar
John Koleszar committed
572
573
574
575
  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;
576
    }
John Koleszar's avatar
John Koleszar committed
577
578
579
    u += stride;
    v += stride;
  }
580
581
}

582
583
static void constrain_line(int x0, int *x1, int y0, int *y1,
                           int width, int height) {
John Koleszar's avatar
John Koleszar committed
584
585
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
  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;
  }
619
620
}

621
622
int vp9_post_proc_frame(VP9_COMMON *oci, YV12_BUFFER_CONFIG *dest,
                        vp9_ppflags_t *ppflags) {
John Koleszar's avatar
John Koleszar committed
623
624
625
626
  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
627

John Koleszar's avatar
John Koleszar committed
628
629
  if (!oci->frame_to_show)
    return -1;
John Koleszar's avatar
John Koleszar committed
630

John Koleszar's avatar
John Koleszar committed
631
632
  if (q > 63)
    q = 63;
John Koleszar's avatar
John Koleszar committed
633

John Koleszar's avatar
John Koleszar committed
634
635
  if (!flags) {
    *dest = *oci->frame_to_show;
John Koleszar's avatar
John Koleszar committed
636

John Koleszar's avatar
John Koleszar committed
637
638
639
640
641
    /* 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
642

John Koleszar's avatar
John Koleszar committed
643
  }
John Koleszar's avatar
John Koleszar committed
644
645

#if ARCH_X86||ARCH_X86_64
John Koleszar's avatar
John Koleszar committed
646
  vpx_reset_mmx_state();
John Koleszar's avatar
John Koleszar committed
647
648
#endif

649
650
  if (flags & VP9D_DEMACROBLOCK) {
    deblock_and_de_macro_block(oci->frame_to_show, &oci->post_proc_buffer,
Jim Bankoski's avatar
Jim Bankoski committed
651
                               q + (deblock_level - 5) * 10, 1, 0);
652
  } else if (flags & VP9D_DEBLOCK) {
Jim Bankoski's avatar
Jim Bankoski committed
653
    vp9_deblock(oci->frame_to_show, &oci->post_proc_buffer, q, 1, 0);
John Koleszar's avatar
John Koleszar committed
654
  } else {
John Koleszar's avatar
John Koleszar committed
655
    vp8_yv12_copy_frame(oci->frame_to_show, &oci->post_proc_buffer);
John Koleszar's avatar
John Koleszar committed
656
657
  }

658
  if (flags & VP9D_ADDNOISE) {
John Koleszar's avatar
John Koleszar committed
659
660
661
662
663
    if (oci->postproc_state.last_q != q
        || oci->postproc_state.last_noise != noise_level) {
      fillrd(&oci->postproc_state, 63 - q, noise_level);
    }

Jim Bankoski's avatar
Jim Bankoski committed
664
665
666
667
668
669
670
671
    vp9_plane_add_noise(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
672
  }
John Koleszar's avatar
John Koleszar committed
673

674
#if CONFIG_POSTPROC_VISUALIZER
675
  if (flags & VP9D_DEBUG_TXT_FRAME_INFO) {
John Koleszar's avatar
John Koleszar committed
676
677
678
679
680
681
682
683
    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);
684
685
    vp9_blit_text(message, oci->post_proc_buffer.y_buffer,
                  oci->post_proc_buffer.y_stride);
John Koleszar's avatar
John Koleszar committed
686
687
  }

688
  if (flags & VP9D_DEBUG_TXT_MBLK_MODES) {
John Koleszar's avatar
John Koleszar committed
689
690
691
692
693
694
695
    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
696

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

699
    /* vp9_filter each macro block */
John Koleszar's avatar
John Koleszar committed
700
701
702
    for (i = 0; i < mb_rows; i++) {
      for (j = 0; j < mb_cols; j++) {
        char zz[4];
703

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

706
        vp9_blit_text(zz, y_ptr, post->y_stride);
John Koleszar's avatar
John Koleszar committed
707
708
709
        mb_index++;
        y_ptr += 16;
      }
John Koleszar's avatar
John Koleszar committed
710

John Koleszar's avatar
John Koleszar committed
711
712
      mb_index++; /* border */
      y_ptr += post->y_stride  * 16 - post->y_width;
713

John Koleszar's avatar
John Koleszar committed
714
    }
John Koleszar's avatar
John Koleszar committed
715
  }
716

717
  if (flags & VP9D_DEBUG_TXT_DC_DIFF) {
John Koleszar's avatar
John Koleszar committed
718
719
720
721
722
723
724
725
726
727
    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;

728
    /* vp9_filter each macro block */
John Koleszar's avatar
John Koleszar committed
729
730
731
732
733
734
735
736
737
738
739
740
    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');

741
        vp9_blit_text(zz, y_ptr, post->y_stride);
John Koleszar's avatar
John Koleszar committed
742
743
744
745
746
747
748
749
750
751
        mb_index++;
        y_ptr += 16;
      }

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

    }
  }

752
  if (flags & VP9D_DEBUG_TXT_RATE_INFO) {
John Koleszar's avatar
John Koleszar committed
753
    char message[512];
754
755
756
757
758
    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
759
760
761
  }

  /* Draw motion vectors */
762
  if ((flags & VP9D_DEBUG_DRAW_MV) && ppflags->display_mv_flag) {
John Koleszar's avatar
John Koleszar committed
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
    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;
        }
779

John Koleszar's avatar
John Koleszar committed
780
781
        if (mi->mbmi.mode == SPLITMV) {
          switch (mi->mbmi.partitioning) {
782
            case PARTITIONING_16X8 : {  /* mv_top_bottom */
John Koleszar's avatar
John Koleszar committed
783
784
              union b_mode_info *bmi = &mi->bmi[0];
              MV *mv = &bmi->mv.as_mv;
785

John Koleszar's avatar
John Koleszar committed
786
787
              x1 = x0 + 8 + (mv->col >> 3);
              y1 = y0 + 4 + (mv->row >> 3);
788

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

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

John Koleszar's avatar
John Koleszar committed
794
795
              x1 = x0 + 8 + (mv->col >> 3);
              y1 = y0 + 12 + (mv->row >> 3);
796

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

John Koleszar's avatar
John Koleszar committed
800
801
              break;
            }
802
            case PARTITIONING_8X16 : {  /* mv_left_right */
John Koleszar's avatar
John Koleszar committed
803
804
              union b_mode_info *bmi = &mi->bmi[0];
              MV *mv = &bmi->mv.as_mv;
805

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

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

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

John Koleszar's avatar
John Koleszar committed
814
815
              x1 = x0 + 12 + (mv->col >> 3);
              y1 = y0 + 8 + (mv->row >> 3);
816

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

John Koleszar's avatar
John Koleszar committed
820
821
              break;
            }
822
            case PARTITIONING_8X8 : {  /* mv_quarters   */
John Koleszar's avatar
John Koleszar committed
823
824
              union b_mode_info *bmi = &mi->bmi[0];
              MV *mv = &bmi->mv.as_mv;
825

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

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

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

John Koleszar's avatar
John Koleszar committed
834
835
              x1 = x0 + 12 + (mv->col >> 3);
              y1 = y0 + 4 + (mv->row >> 3);
836

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

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

John Koleszar's avatar
John Koleszar committed
842
843
              x1 = x0 + 4 + (mv->col >> 3);
              y1 = y0 + 12 + (mv->row >> 3);
844

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

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

John Koleszar's avatar
John Koleszar committed
850
851
              x1 = x0 + 12 + (mv->col >> 3);
              y1 = y0 + 12 + (mv->row >> 3);
852

John Koleszar's avatar
John Koleszar committed
853
              constrain_line(x0 + 12, &x1, y0 + 12, &y1, width, height);
854
              vp9_blit_line(x0 + 12,  x1, y0 + 12,  y1, y_buffer, y_stride);
John Koleszar's avatar
John Koleszar committed
855
856
              break;
            }
857
            case PARTITIONING_4X4:
John Koleszar's avatar
John Koleszar committed
858
859
860
            default : {
              union b_mode_info *bmi = mi->bmi;
              int bx0, by0;
861

John Koleszar's avatar
John Koleszar committed
862
863
864
              for (by0 = y0; by0 < (y0 + 16); by0 += 4) {
                for (bx0 = x0; bx0 < (x0 + 16); bx0 += 4) {
                  MV *mv = &bmi->mv.as_mv;
865

John Koleszar's avatar
John Koleszar committed
866
867
                  x1 = bx0 + 2 + (mv->col >> 3);
                  y1 = by0 + 2 + (mv->row >> 3);
868

John Koleszar's avatar
John Koleszar committed
869
                  constrain_line(bx0 + 2, &x1, by0 + 2, &y1, width, height);
870
                  vp9_blit_line(bx0 + 2,  x1, by0 + 2,  y1, y_buffer, y_stride);
871

John Koleszar's avatar
John Koleszar committed
872
                  bmi++;
873
                }
John Koleszar's avatar
John Koleszar committed
874
              }
875
            }
John Koleszar's avatar
John Koleszar committed
876
877
878
879
880
881
882
883
884
885
886
          }
        } 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);
887
            vp9_blit_line(lx0,  x1, ly0 - 1,  y1, y_buffer, y_stride);
John Koleszar's avatar
John Koleszar committed
888
889

            constrain_line(lx0, &x1, ly0 + 1, &y1, width, height);
890
            vp9_blit_line(lx0,  x1, ly0 + 1,  y1, y_buffer, y_stride);
John Koleszar's avatar
John Koleszar committed
891
          } else
892
            vp9_blit_line(lx0,  x1, ly0,  y1, y_buffer, y_stride);
893
        }
John Koleszar's avatar
John Koleszar committed
894

John Koleszar's avatar
John Koleszar committed
895
896
897
898
899
900
901
        mi++;
      }
      mi++;
    }
  }

  /* Color in block modes */
902
  if ((flags & VP9D_DEBUG_CLR_BLK_MODES)
John Koleszar's avatar
John Koleszar committed
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
      && (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 &&
919
920
            ((ppflags->display_mb_modes_flag & B_PRED) ||
             ppflags->display_b_modes_flag)) {
John Koleszar's avatar
John Koleszar committed
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
          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];

Jim Bankoski's avatar
Jim Bankoski committed
937
938
                vp9_blend_b(yl + bx, ul + (bx >> 1), vl + (bx >> 1), Y, U, V,
                    0xc000, y_stride);
John Koleszar's avatar
John Koleszar committed
939
940
              }
              bmi++;
941
942
            }

John Koleszar's avatar
John Koleszar committed
943
944
945
946
947
948
949
950
951
            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];

Jim Bankoski's avatar
Jim Bankoski committed
952
953
          vp9_blend_mb_inner(y_ptr + x, u_ptr + (x >> 1), v_ptr + (x >> 1),
                             Y, U, V, 0xc000, y_stride);
954
955
        }

John Koleszar's avatar
John Koleszar committed
956
957
958
959
960
961
962
963
964
965
966
        mi++;
      }
      y_ptr += y_stride * 16;
      u_ptr += y_stride * 4;
      v_ptr += y_stride * 4;

      mi++;
    }
  }

  /* Color in frame reference blocks */
967
968
  if ((flags & VP9D_DEBUG_CLR_FRM_REF_BLKS) &&
      ppflags->display_ref_frame_flag) {
John Koleszar's avatar
John Koleszar committed
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
    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];

Jim Bankoski's avatar
Jim Bankoski committed
988
989
          vp9_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
990
        }
991

John Koleszar's avatar
John Koleszar committed
992
993
994
995
996
        mi++;
      }
      y_ptr += y_stride * 16;
      u_ptr += y_stride * 4;
      v_ptr += y_stride * 4;
997

John Koleszar's avatar
John Koleszar committed
998
      mi++;
999
    }
John Koleszar's avatar
John Koleszar committed
1000
  }
1001
#endif
1002

John Koleszar's avatar
John Koleszar committed
1003
  *dest = oci->post_proc_buffer;
John Koleszar's avatar
John Koleszar committed
1004

John Koleszar's avatar
John Koleszar committed
1005
1006
1007
1008
  /* handle problem with extending borders */
  dest->y_width = oci->Width;
  dest->y_height = oci->Height;
  dest->uv_height = dest->y_height / 2;
1009

John Koleszar's avatar
John Koleszar committed
1010
  return 0;
John Koleszar's avatar
John Koleszar committed
1011
}