vp9_postproc.c 13.2 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 <math.h>
#include <stdlib.h>
#include <stdio.h>
John Koleszar's avatar
John Koleszar committed
14

15
#include "./vpx_config.h"
Dmitry Kovalev's avatar
Dmitry Kovalev committed
16
17
18
19
#include "./vpx_scale_rtcd.h"
#include "./vp9_rtcd.h"

#include "vpx_scale/vpx_scale.h"
John Koleszar's avatar
John Koleszar committed
20
#include "vpx_scale/yv12config.h"
Dmitry Kovalev's avatar
Dmitry Kovalev committed
21
22

#include "vp9/common/vp9_onyxc_int.h"
23
24
#include "vp9/common/vp9_postproc.h"
#include "vp9/common/vp9_systemdependent.h"
Dmitry Kovalev's avatar
Dmitry Kovalev committed
25
#include "vp9/common/vp9_textblit.h"
Jim Bankoski's avatar
Jim Bankoski committed
26

27
#if CONFIG_VP9_POSTPROC
John Koleszar's avatar
John Koleszar committed
28
29
static const short kernel5[] = {
  1, 1, 4, 1, 1
John Koleszar's avatar
John Koleszar committed
30
31
};

32
const short vp9_rv[] = {
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
  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
77
78
};

79
void vp9_post_proc_down_and_across_c(const uint8_t *src_ptr,
80
                                     uint8_t *dst_ptr,
81
82
83
84
85
                                     int src_pixels_per_line,
                                     int dst_pixels_per_line,
                                     int rows,
                                     int cols,
                                     int flimit) {
86
87
  uint8_t const *p_src;
  uint8_t *p_dst;
John Koleszar's avatar
John Koleszar committed
88
89
90
91
92
  int row;
  int col;
  int i;
  int v;
  int pitch = src_pixels_per_line;
93
  uint8_t d[8];
John Koleszar's avatar
John Koleszar committed
94
  (void)dst_pixels_per_line;
John Koleszar's avatar
John Koleszar committed
95

John Koleszar's avatar
John Koleszar committed
96
97
98
99
  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
100

John Koleszar's avatar
John Koleszar committed
101
102
103
    for (col = 0; col < cols; col++) {
      int kernel = 4;
      int v = p_src[col];
John Koleszar's avatar
John Koleszar committed
104

John Koleszar's avatar
John Koleszar committed
105
106
107
      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
108

John Koleszar's avatar
John Koleszar committed
109
110
        kernel += kernel5[2 + i] * p_src[col + i * pitch];
      }
John Koleszar's avatar
John Koleszar committed
111

John Koleszar's avatar
John Koleszar committed
112
113
114
115
      v = (kernel >> 3);
    down_skip_convolve:
      p_dst[col] = v;
    }
John Koleszar's avatar
John Koleszar committed
116

John Koleszar's avatar
John Koleszar committed
117
118
119
    /* now post_proc_across */
    p_src = dst_ptr;
    p_dst = dst_ptr;
John Koleszar's avatar
John Koleszar committed
120

John Koleszar's avatar
John Koleszar committed
121
122
    for (i = 0; i < 8; i++)
      d[i] = p_src[i];
John Koleszar's avatar
John Koleszar committed
123

John Koleszar's avatar
John Koleszar committed
124
125
126
127
128
129
130
131
132
    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
133

John Koleszar's avatar
John Koleszar committed
134
135
        kernel += kernel5[2 + i] * p_src[col + i];
      }
John Koleszar's avatar
John Koleszar committed
136

John Koleszar's avatar
John Koleszar committed
137
138
      d[col & 7] = (kernel >> 3);
    across_skip_convolve:
John Koleszar's avatar
John Koleszar committed
139

John Koleszar's avatar
John Koleszar committed
140
141
      if (col >= 2)
        p_dst[col - 2] = d[(col - 2) & 7];
John Koleszar's avatar
John Koleszar committed
142
143
    }

John Koleszar's avatar
John Koleszar committed
144
145
146
147
    /* 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
148

John Koleszar's avatar
John Koleszar committed
149
150
151
152
    /* next row */
    src_ptr += pitch;
    dst_ptr += pitch;
  }
John Koleszar's avatar
John Koleszar committed
153
154
}

John Koleszar's avatar
John Koleszar committed
155
156
static int q2mbl(int x) {
  if (x < 20) x = 20;
John Koleszar's avatar
John Koleszar committed
157

John Koleszar's avatar
John Koleszar committed
158
159
160
  x = 50 + (x - 50) * 10 / 8;
  return x * x / 3;
}
161

162
void vp9_mbpost_proc_across_ip_c(uint8_t *src, int pitch,
163
                                 int rows, int cols, int flimit) {
John Koleszar's avatar
John Koleszar committed
164
  int r, c, i;
John Koleszar's avatar
John Koleszar committed
165

166
167
  uint8_t *s = src;
  uint8_t d[16];
John Koleszar's avatar
John Koleszar committed
168
169


John Koleszar's avatar
John Koleszar committed
170
171
172
  for (r = 0; r < rows; r++) {
    int sumsq = 0;
    int sum   = 0;
John Koleszar's avatar
John Koleszar committed
173

John Koleszar's avatar
John Koleszar committed
174
175
176
177
178
    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
179

John Koleszar's avatar
John Koleszar committed
180
181
182
    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
183

John Koleszar's avatar
John Koleszar committed
184
185
      sum  += x;
      sumsq += x * y;
John Koleszar's avatar
John Koleszar committed
186

John Koleszar's avatar
John Koleszar committed
187
188
189
190
191
      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
192

John Koleszar's avatar
John Koleszar committed
193
      s[c - 8] = d[(c - 8) & 15];
John Koleszar's avatar
John Koleszar committed
194
    }
John Koleszar's avatar
John Koleszar committed
195
196
197

    s += pitch;
  }
John Koleszar's avatar
John Koleszar committed
198
199
}

200
void vp9_mbpost_proc_down_c(uint8_t *dst, int pitch,
201
                            int rows, int cols, int flimit) {
John Koleszar's avatar
John Koleszar committed
202
  int r, c, i;
203
  const short *rv3 = &vp9_rv[63 & rand()]; // NOLINT
John Koleszar's avatar
John Koleszar committed
204

John Koleszar's avatar
John Koleszar committed
205
  for (c = 0; c < cols; c++) {
206
    uint8_t *s = &dst[c];
John Koleszar's avatar
John Koleszar committed
207
208
    int sumsq = 0;
    int sum   = 0;
209
    uint8_t d[16];
John Koleszar's avatar
John Koleszar committed
210
    const short *rv2 = rv3 + ((c * 17) & 127);
John Koleszar's avatar
John Koleszar committed
211

John Koleszar's avatar
John Koleszar committed
212
213
214
215
    for (i = -8; i <= 6; i++) {
      sumsq += s[i * pitch] * s[i * pitch];
      sum   += s[i * pitch];
    }
John Koleszar's avatar
John Koleszar committed
216

John Koleszar's avatar
John Koleszar committed
217
218
219
220
    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
221

John Koleszar's avatar
John Koleszar committed
222
223
224
      if (sumsq * 15 - sum * sum < flimit) {
        d[r & 15] = (rv2[r & 127] + sum + s[0]) >> 4;
      }
John Koleszar's avatar
John Koleszar committed
225

John Koleszar's avatar
John Koleszar committed
226
227
      s[-8 * pitch] = d[(r - 8) & 15];
      s += pitch;
John Koleszar's avatar
John Koleszar committed
228
    }
John Koleszar's avatar
John Koleszar committed
229
  }
John Koleszar's avatar
John Koleszar committed
230
231
}

232
233
234
235
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
236
                                       int                   flag) {
John Koleszar's avatar
John Koleszar committed
237
238
239
240
241
  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
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
  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
258
259
}

260
261
262
263
264
void vp9_deblock(const YV12_BUFFER_CONFIG *src, YV12_BUFFER_CONFIG *dst,
                 int q) {
  const int ppl = (int)(6.0e-05 * q * q * q - 0.0067 * q * q + 0.306 * q
                        + 0.0065 + 0.5);
  int i;
John Koleszar's avatar
John Koleszar committed
265

266
267
268
269
270
271
272
273
274
275
276
277
278
  const uint8_t *const srcs[4] = {src->y_buffer, src->u_buffer, src->v_buffer,
                                  src->alpha_buffer};
  const int src_strides[4] = {src->y_stride, src->uv_stride, src->uv_stride,
                              src->alpha_stride};
  const int src_widths[4] = {src->y_width, src->uv_width, src->uv_width,
                             src->alpha_width};
  const int src_heights[4] = {src->y_height, src->uv_height, src->uv_height,
                              src->alpha_height};

  uint8_t *const dsts[4] = {dst->y_buffer, dst->u_buffer, dst->v_buffer,
                            dst->alpha_buffer};
  const int dst_strides[4] = {dst->y_stride, dst->uv_stride, dst->uv_stride,
                              dst->alpha_stride};
Jim Bankoski's avatar
Jim Bankoski committed
279

280
281
282
283
  for (i = 0; i < MAX_MB_PLANE; ++i)
    vp9_post_proc_down_and_across(srcs[i], dsts[i],
                                  src_strides[i], dst_strides[i],
                                  src_heights[i], src_widths[i], ppl);
John Koleszar's avatar
John Koleszar committed
284
285
}

286
287
288
289
290
291
void vp9_denoise(const YV12_BUFFER_CONFIG *src, YV12_BUFFER_CONFIG *dst,
                 int q) {
  const int ppl = (int)(6.0e-05 * q * q * q - 0.0067 * q * q + 0.306 * q
                        + 0.0065 + 0.5);
  int i;

292
293
294
295
296
297
298
299
300
301
302
303
304
  const uint8_t *const srcs[4] = {src->y_buffer, src->u_buffer, src->v_buffer,
                                  src->alpha_buffer};
  const int src_strides[4] = {src->y_stride, src->uv_stride, src->uv_stride,
                              src->alpha_stride};
  const int src_widths[4] = {src->y_width, src->uv_width, src->uv_width,
                             src->alpha_width};
  const int src_heights[4] = {src->y_height, src->uv_height, src->uv_height,
                              src->alpha_height};

  uint8_t *const dsts[4] = {dst->y_buffer, dst->u_buffer, dst->v_buffer,
                            dst->alpha_buffer};
  const int dst_strides[4] = {dst->y_stride, dst->uv_stride, dst->uv_stride,
                              dst->alpha_stride};
Jim Bankoski's avatar
Jim Bankoski committed
305

306
307
308
309
310
  for (i = 0; i < MAX_MB_PLANE; ++i) {
    const int src_stride = src_strides[i];
    const uint8_t *const src = srcs[i] + 2 * src_stride + 2;
    const int src_width = src_widths[i] - 4;
    const int src_height = src_heights[i] - 4;
Jim Bankoski's avatar
Jim Bankoski committed
311

312
313
314
315
316
317
    const int dst_stride = dst_strides[i];
    uint8_t *const dst = dsts[i] + 2 * dst_stride + 2;

    vp9_post_proc_down_and_across(src, dst, src_stride, dst_stride,
                                  src_height, src_width, ppl);
  }
John Koleszar's avatar
John Koleszar committed
318
319
}

Dmitry Kovalev's avatar
Dmitry Kovalev committed
320
static double gaussian(double sigma, double mu, double x) {
John Koleszar's avatar
John Koleszar committed
321
322
  return 1 / (sigma * sqrt(2.0 * 3.14159265)) *
         (exp(-(x - mu) * (x - mu) / (2 * sigma * sigma)));
John Koleszar's avatar
John Koleszar committed
323
324
}

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

John Koleszar's avatar
John Koleszar committed
328
329
  double sigma;
  int ai = a, qi = q, i;
John Koleszar's avatar
John Koleszar committed
330

331
  vp9_clear_system_state();
John Koleszar's avatar
John Koleszar committed
332

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

John Koleszar's avatar
John Koleszar committed
335
336
337
338
339
340
  /* 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
341

John Koleszar's avatar
John Koleszar committed
342
    next = 0;
John Koleszar's avatar
John Koleszar committed
343

John Koleszar's avatar
John Koleszar committed
344
    for (i = -32; i < 32; i++) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
345
      int a = (int)(0.5 + 256 * gaussian(sigma, 0, i));
John Koleszar's avatar
John Koleszar committed
346

John Koleszar's avatar
John Koleszar committed
347
348
349
      if (a) {
        for (j = 0; j < a; j++) {
          char_dist[next + j] = (char) i;
John Koleszar's avatar
John Koleszar committed
350
351
        }

John Koleszar's avatar
John Koleszar committed
352
353
        next = next + j;
      }
John Koleszar's avatar
John Koleszar committed
354
355
    }

356
    for (; next < 256; next++)
John Koleszar's avatar
John Koleszar committed
357
358
359
360
      char_dist[next] = 0;
  }

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

John Koleszar's avatar
John Koleszar committed
364
365
366
367
368
369
370
371
  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
372
373
}

374
void vp9_plane_add_noise_c(uint8_t *start, char *noise,
John Koleszar's avatar
John Koleszar committed
375
376
377
                           char blackclamp[16],
                           char whiteclamp[16],
                           char bothclamp[16],
378
                           unsigned int width, unsigned int height, int pitch) {
John Koleszar's avatar
John Koleszar committed
379
  unsigned int i, j;
John Koleszar's avatar
John Koleszar committed
380

381
382
383
  for (i = 0; i < height; i++) {
    uint8_t *pos = start + i * pitch;
    char  *ref = (char *)(noise + (rand() & 0xff));  // NOLINT
John Koleszar's avatar
John Koleszar committed
384

385
386
387
    for (j = 0; j < width; j++) {
      if (pos[j] < blackclamp[0])
        pos[j] = blackclamp[0];
John Koleszar's avatar
John Koleszar committed
388

389
390
      if (pos[j] > 255 + whiteclamp[0])
        pos[j] = 255 + whiteclamp[0];
John Koleszar's avatar
John Koleszar committed
391

392
      pos[j] += ref[j];
John Koleszar's avatar
John Koleszar committed
393
    }
John Koleszar's avatar
John Koleszar committed
394
  }
John Koleszar's avatar
John Koleszar committed
395
396
}

397
int vp9_post_proc_frame(struct VP9Common *cm,
398
                        YV12_BUFFER_CONFIG *dest, vp9_ppflags_t *ppflags) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
399
400
401
402
  const int q = MIN(63, cm->lf.filter_level * 10 / 6);
  const int flags = ppflags->post_proc_flag;
  YV12_BUFFER_CONFIG *const ppbuf = &cm->post_proc_buffer;
  struct postproc_state *const ppstate = &cm->postproc_state;
John Koleszar's avatar
John Koleszar committed
403

404
  if (!cm->frame_to_show)
John Koleszar's avatar
John Koleszar committed
405
    return -1;
John Koleszar's avatar
John Koleszar committed
406

John Koleszar's avatar
John Koleszar committed
407
  if (!flags) {
408
    *dest = *cm->frame_to_show;
John Koleszar's avatar
John Koleszar committed
409
410
    return 0;
  }
John Koleszar's avatar
John Koleszar committed
411

Dmitry Kovalev's avatar
Dmitry Kovalev committed
412
  vp9_clear_system_state();
John Koleszar's avatar
John Koleszar committed
413

Adrian Grange's avatar
Adrian Grange committed
414
415
416
417
418
419
420
421
#if CONFIG_VP9_POSTPROC || CONFIG_INTERNAL_STATS
  if (vp9_realloc_frame_buffer(&cm->post_proc_buffer, cm->width, cm->height,
                               cm->subsampling_x, cm->subsampling_y,
                               VP9_DEC_BORDER_IN_PIXELS, NULL, NULL, NULL) < 0)
    vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
                       "Failed to allocate post-processing buffer");
#endif

422
  if (flags & VP9D_DEMACROBLOCK) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
423
424
    deblock_and_de_macro_block(cm->frame_to_show, ppbuf,
                               q + (ppflags->deblocking_level - 5) * 10, 1, 0);
425
  } else if (flags & VP9D_DEBLOCK) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
426
    vp9_deblock(cm->frame_to_show, ppbuf, q);
John Koleszar's avatar
John Koleszar committed
427
  } else {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
428
    vp8_yv12_copy_frame(cm->frame_to_show, ppbuf);
John Koleszar's avatar
John Koleszar committed
429
430
  }

431
  if (flags & VP9D_ADDNOISE) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
432
433
434
435
    const int noise_level = ppflags->noise_level;
    if (ppstate->last_q != q ||
        ppstate->last_noise != noise_level) {
      fillrd(ppstate, 63 - q, noise_level);
John Koleszar's avatar
John Koleszar committed
436
437
    }

Dmitry Kovalev's avatar
Dmitry Kovalev committed
438
439
440
    vp9_plane_add_noise(ppbuf->y_buffer, ppstate->noise, ppstate->blackclamp,
                        ppstate->whiteclamp, ppstate->bothclamp,
                        ppbuf->y_width, ppbuf->y_height, ppbuf->y_stride);
John Koleszar's avatar
John Koleszar committed
441
  }
John Koleszar's avatar
John Koleszar committed
442

Dmitry Kovalev's avatar
Dmitry Kovalev committed
443
  *dest = *ppbuf;
John Koleszar's avatar
John Koleszar committed
444

John Koleszar's avatar
John Koleszar committed
445
  /* handle problem with extending borders */
446
447
  dest->y_width = cm->width;
  dest->y_height = cm->height;
448
449
  dest->uv_width = dest->y_width >> cm->subsampling_x;
  dest->uv_height = dest->y_height >> cm->subsampling_y;
450

John Koleszar's avatar
John Koleszar committed
451
  return 0;
John Koleszar's avatar
John Koleszar committed
452
}
453
#endif