Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 /*
2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * 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.
9 */
11 #include <math.h>
12 #include <stdlib.h>
13 #include <stdio.h>
15 #include "./vpx_config.h"
16 #include "vpx_scale/yv12config.h"
17 #include "vp9/common/vp9_postproc.h"
18 #include "vp9/common/vp9_textblit.h"
19 #include "vpx_scale/vpx_scale.h"
20 #include "vp9/common/vp9_systemdependent.h"
21 #include "./vp9_rtcd.h"
22 #include "./vpx_scale_rtcd.h"
24 #define RGB_TO_YUV(t) \
25 ( (0.257*(float)(t >> 16)) + (0.504*(float)(t >> 8 & 0xff)) + \
26 (0.098*(float)(t & 0xff)) + 16), \
27 (-(0.148*(float)(t >> 16)) - (0.291*(float)(t >> 8 & 0xff)) + \
28 (0.439*(float)(t & 0xff)) + 128), \
29 ( (0.439*(float)(t >> 16)) - (0.368*(float)(t >> 8 & 0xff)) - \
30 (0.071*(float)(t & 0xff)) + 128)
32 /* global constants */
33 #if 0 && CONFIG_POSTPROC_VISUALIZER
34 static const unsigned char MB_PREDICTION_MODE_colors[MB_MODE_COUNT][3] = {
35 { RGB_TO_YUV(0x98FB98) }, /* PaleGreen */
36 { RGB_TO_YUV(0x00FF00) }, /* Green */
37 { RGB_TO_YUV(0xADFF2F) }, /* GreenYellow */
38 { RGB_TO_YUV(0x8F0000) }, /* Dark Red */
39 { RGB_TO_YUV(0x008F8F) }, /* Dark Cyan */
40 { RGB_TO_YUV(0x008F8F) }, /* Dark Cyan */
41 { RGB_TO_YUV(0x008F8F) }, /* Dark Cyan */
42 { RGB_TO_YUV(0x8F0000) }, /* Dark Red */
43 { RGB_TO_YUV(0x8F0000) }, /* Dark Red */
44 { RGB_TO_YUV(0x228B22) }, /* ForestGreen */
45 { RGB_TO_YUV(0x006400) }, /* DarkGreen */
46 { RGB_TO_YUV(0x98F5FF) }, /* Cadet Blue */
47 { RGB_TO_YUV(0x6CA6CD) }, /* Sky Blue */
48 { RGB_TO_YUV(0x00008B) }, /* Dark blue */
49 { RGB_TO_YUV(0x551A8B) }, /* Purple */
50 { RGB_TO_YUV(0xFF0000) } /* Red */
51 { RGB_TO_YUV(0xCC33FF) }, /* Magenta */
52 };
54 static const unsigned char B_PREDICTION_MODE_colors[INTRA_MODES][3] = {
55 { RGB_TO_YUV(0x6633ff) }, /* Purple */
56 { RGB_TO_YUV(0xcc33ff) }, /* Magenta */
57 { RGB_TO_YUV(0xff33cc) }, /* Pink */
58 { RGB_TO_YUV(0xff3366) }, /* Coral */
59 { RGB_TO_YUV(0x3366ff) }, /* Blue */
60 { RGB_TO_YUV(0xed00f5) }, /* Dark Blue */
61 { RGB_TO_YUV(0x2e00b8) }, /* Dark Purple */
62 { RGB_TO_YUV(0xff6633) }, /* Orange */
63 { RGB_TO_YUV(0x33ccff) }, /* Light Blue */
64 { RGB_TO_YUV(0x8ab800) }, /* Green */
65 { RGB_TO_YUV(0xffcc33) }, /* Light Orange */
66 { RGB_TO_YUV(0x33ffcc) }, /* Aqua */
67 { RGB_TO_YUV(0x66ff33) }, /* Light Green */
68 { RGB_TO_YUV(0xccff33) }, /* Yellow */
69 };
71 static const unsigned char MV_REFERENCE_FRAME_colors[MAX_REF_FRAMES][3] = {
72 { RGB_TO_YUV(0x00ff00) }, /* Blue */
73 { RGB_TO_YUV(0x0000ff) }, /* Green */
74 { RGB_TO_YUV(0xffff00) }, /* Yellow */
75 { RGB_TO_YUV(0xff0000) }, /* Red */
76 };
77 #endif
79 static const short kernel5[] = {
80 1, 1, 4, 1, 1
81 };
83 const short vp9_rv[] = {
84 8, 5, 2, 2, 8, 12, 4, 9, 8, 3,
85 0, 3, 9, 0, 0, 0, 8, 3, 14, 4,
86 10, 1, 11, 14, 1, 14, 9, 6, 12, 11,
87 8, 6, 10, 0, 0, 8, 9, 0, 3, 14,
88 8, 11, 13, 4, 2, 9, 0, 3, 9, 6,
89 1, 2, 3, 14, 13, 1, 8, 2, 9, 7,
90 3, 3, 1, 13, 13, 6, 6, 5, 2, 7,
91 11, 9, 11, 8, 7, 3, 2, 0, 13, 13,
92 14, 4, 12, 5, 12, 10, 8, 10, 13, 10,
93 4, 14, 4, 10, 0, 8, 11, 1, 13, 7,
94 7, 14, 6, 14, 13, 2, 13, 5, 4, 4,
95 0, 10, 0, 5, 13, 2, 12, 7, 11, 13,
96 8, 0, 4, 10, 7, 2, 7, 2, 2, 5,
97 3, 4, 7, 3, 3, 14, 14, 5, 9, 13,
98 3, 14, 3, 6, 3, 0, 11, 8, 13, 1,
99 13, 1, 12, 0, 10, 9, 7, 6, 2, 8,
100 5, 2, 13, 7, 1, 13, 14, 7, 6, 7,
101 9, 6, 10, 11, 7, 8, 7, 5, 14, 8,
102 4, 4, 0, 8, 7, 10, 0, 8, 14, 11,
103 3, 12, 5, 7, 14, 3, 14, 5, 2, 6,
104 11, 12, 12, 8, 0, 11, 13, 1, 2, 0,
105 5, 10, 14, 7, 8, 0, 4, 11, 0, 8,
106 0, 3, 10, 5, 8, 0, 11, 6, 7, 8,
107 10, 7, 13, 9, 2, 5, 1, 5, 10, 2,
108 4, 3, 5, 6, 10, 8, 9, 4, 11, 14,
109 0, 10, 0, 5, 13, 2, 12, 7, 11, 13,
110 8, 0, 4, 10, 7, 2, 7, 2, 2, 5,
111 3, 4, 7, 3, 3, 14, 14, 5, 9, 13,
112 3, 14, 3, 6, 3, 0, 11, 8, 13, 1,
113 13, 1, 12, 0, 10, 9, 7, 6, 2, 8,
114 5, 2, 13, 7, 1, 13, 14, 7, 6, 7,
115 9, 6, 10, 11, 7, 8, 7, 5, 14, 8,
116 4, 4, 0, 8, 7, 10, 0, 8, 14, 11,
117 3, 12, 5, 7, 14, 3, 14, 5, 2, 6,
118 11, 12, 12, 8, 0, 11, 13, 1, 2, 0,
119 5, 10, 14, 7, 8, 0, 4, 11, 0, 8,
120 0, 3, 10, 5, 8, 0, 11, 6, 7, 8,
121 10, 7, 13, 9, 2, 5, 1, 5, 10, 2,
122 4, 3, 5, 6, 10, 8, 9, 4, 11, 14,
123 3, 8, 3, 7, 8, 5, 11, 4, 12, 3,
124 11, 9, 14, 8, 14, 13, 4, 3, 1, 2,
125 14, 6, 5, 4, 4, 11, 4, 6, 2, 1,
126 5, 8, 8, 12, 13, 5, 14, 10, 12, 13,
127 0, 9, 5, 5, 11, 10, 13, 9, 10, 13,
128 };
131 /****************************************************************************
132 */
133 void vp9_post_proc_down_and_across_c(const uint8_t *src_ptr,
134 uint8_t *dst_ptr,
135 int src_pixels_per_line,
136 int dst_pixels_per_line,
137 int rows,
138 int cols,
139 int flimit) {
140 uint8_t const *p_src;
141 uint8_t *p_dst;
142 int row;
143 int col;
144 int i;
145 int v;
146 int pitch = src_pixels_per_line;
147 uint8_t d[8];
148 (void)dst_pixels_per_line;
150 for (row = 0; row < rows; row++) {
151 /* post_proc_down for one row */
152 p_src = src_ptr;
153 p_dst = dst_ptr;
155 for (col = 0; col < cols; col++) {
156 int kernel = 4;
157 int v = p_src[col];
159 for (i = -2; i <= 2; i++) {
160 if (abs(v - p_src[col + i * pitch]) > flimit)
161 goto down_skip_convolve;
163 kernel += kernel5[2 + i] * p_src[col + i * pitch];
164 }
166 v = (kernel >> 3);
167 down_skip_convolve:
168 p_dst[col] = v;
169 }
171 /* now post_proc_across */
172 p_src = dst_ptr;
173 p_dst = dst_ptr;
175 for (i = 0; i < 8; i++)
176 d[i] = p_src[i];
178 for (col = 0; col < cols; col++) {
179 int kernel = 4;
180 v = p_src[col];
182 d[col & 7] = v;
184 for (i = -2; i <= 2; i++) {
185 if (abs(v - p_src[col + i]) > flimit)
186 goto across_skip_convolve;
188 kernel += kernel5[2 + i] * p_src[col + i];
189 }
191 d[col & 7] = (kernel >> 3);
192 across_skip_convolve:
194 if (col >= 2)
195 p_dst[col - 2] = d[(col - 2) & 7];
196 }
198 /* handle the last two pixels */
199 p_dst[col - 2] = d[(col - 2) & 7];
200 p_dst[col - 1] = d[(col - 1) & 7];
203 /* next row */
204 src_ptr += pitch;
205 dst_ptr += pitch;
206 }
207 }
209 static int q2mbl(int x) {
210 if (x < 20) x = 20;
212 x = 50 + (x - 50) * 10 / 8;
213 return x * x / 3;
214 }
216 void vp9_mbpost_proc_across_ip_c(uint8_t *src, int pitch,
217 int rows, int cols, int flimit) {
218 int r, c, i;
220 uint8_t *s = src;
221 uint8_t d[16];
224 for (r = 0; r < rows; r++) {
225 int sumsq = 0;
226 int sum = 0;
228 for (i = -8; i <= 6; i++) {
229 sumsq += s[i] * s[i];
230 sum += s[i];
231 d[i + 8] = 0;
232 }
234 for (c = 0; c < cols + 8; c++) {
235 int x = s[c + 7] - s[c - 8];
236 int y = s[c + 7] + s[c - 8];
238 sum += x;
239 sumsq += x * y;
241 d[c & 15] = s[c];
243 if (sumsq * 15 - sum * sum < flimit) {
244 d[c & 15] = (8 + sum + s[c]) >> 4;
245 }
247 s[c - 8] = d[(c - 8) & 15];
248 }
250 s += pitch;
251 }
252 }
254 void vp9_mbpost_proc_down_c(uint8_t *dst, int pitch,
255 int rows, int cols, int flimit) {
256 int r, c, i;
257 const short *rv3 = &vp9_rv[63 & rand()]; // NOLINT
259 for (c = 0; c < cols; c++) {
260 uint8_t *s = &dst[c];
261 int sumsq = 0;
262 int sum = 0;
263 uint8_t d[16];
264 const short *rv2 = rv3 + ((c * 17) & 127);
266 for (i = -8; i <= 6; i++) {
267 sumsq += s[i * pitch] * s[i * pitch];
268 sum += s[i * pitch];
269 }
271 for (r = 0; r < rows + 8; r++) {
272 sumsq += s[7 * pitch] * s[ 7 * pitch] - s[-8 * pitch] * s[-8 * pitch];
273 sum += s[7 * pitch] - s[-8 * pitch];
274 d[r & 15] = s[0];
276 if (sumsq * 15 - sum * sum < flimit) {
277 d[r & 15] = (rv2[r & 127] + sum + s[0]) >> 4;
278 }
280 s[-8 * pitch] = d[(r - 8) & 15];
281 s += pitch;
282 }
283 }
284 }
286 static void deblock_and_de_macro_block(YV12_BUFFER_CONFIG *source,
287 YV12_BUFFER_CONFIG *post,
288 int q,
289 int low_var_thresh,
290 int flag) {
291 double level = 6.0e-05 * q * q * q - .0067 * q * q + .306 * q + .0065;
292 int ppl = (int)(level + .5);
293 (void) low_var_thresh;
294 (void) flag;
296 vp9_post_proc_down_and_across(source->y_buffer, post->y_buffer,
297 source->y_stride, post->y_stride,
298 source->y_height, source->y_width, ppl);
300 vp9_mbpost_proc_across_ip(post->y_buffer, post->y_stride, post->y_height,
301 post->y_width, q2mbl(q));
303 vp9_mbpost_proc_down(post->y_buffer, post->y_stride, post->y_height,
304 post->y_width, q2mbl(q));
306 vp9_post_proc_down_and_across(source->u_buffer, post->u_buffer,
307 source->uv_stride, post->uv_stride,
308 source->uv_height, source->uv_width, ppl);
309 vp9_post_proc_down_and_across(source->v_buffer, post->v_buffer,
310 source->uv_stride, post->uv_stride,
311 source->uv_height, source->uv_width, ppl);
312 }
314 void vp9_deblock(const YV12_BUFFER_CONFIG *src, YV12_BUFFER_CONFIG *dst,
315 int q) {
316 const int ppl = (int)(6.0e-05 * q * q * q - 0.0067 * q * q + 0.306 * q
317 + 0.0065 + 0.5);
318 int i;
320 const uint8_t *const srcs[4] = {src->y_buffer, src->u_buffer, src->v_buffer,
321 src->alpha_buffer};
322 const int src_strides[4] = {src->y_stride, src->uv_stride, src->uv_stride,
323 src->alpha_stride};
324 const int src_widths[4] = {src->y_width, src->uv_width, src->uv_width,
325 src->alpha_width};
326 const int src_heights[4] = {src->y_height, src->uv_height, src->uv_height,
327 src->alpha_height};
329 uint8_t *const dsts[4] = {dst->y_buffer, dst->u_buffer, dst->v_buffer,
330 dst->alpha_buffer};
331 const int dst_strides[4] = {dst->y_stride, dst->uv_stride, dst->uv_stride,
332 dst->alpha_stride};
334 for (i = 0; i < MAX_MB_PLANE; ++i)
335 vp9_post_proc_down_and_across(srcs[i], dsts[i],
336 src_strides[i], dst_strides[i],
337 src_heights[i], src_widths[i], ppl);
338 }
340 void vp9_denoise(const YV12_BUFFER_CONFIG *src, YV12_BUFFER_CONFIG *dst,
341 int q) {
342 const int ppl = (int)(6.0e-05 * q * q * q - 0.0067 * q * q + 0.306 * q
343 + 0.0065 + 0.5);
344 int i;
346 const uint8_t *const srcs[4] = {src->y_buffer, src->u_buffer, src->v_buffer,
347 src->alpha_buffer};
348 const int src_strides[4] = {src->y_stride, src->uv_stride, src->uv_stride,
349 src->alpha_stride};
350 const int src_widths[4] = {src->y_width, src->uv_width, src->uv_width,
351 src->alpha_width};
352 const int src_heights[4] = {src->y_height, src->uv_height, src->uv_height,
353 src->alpha_height};
355 uint8_t *const dsts[4] = {dst->y_buffer, dst->u_buffer, dst->v_buffer,
356 dst->alpha_buffer};
357 const int dst_strides[4] = {dst->y_stride, dst->uv_stride, dst->uv_stride,
358 dst->alpha_stride};
360 for (i = 0; i < MAX_MB_PLANE; ++i) {
361 const int src_stride = src_strides[i];
362 const uint8_t *const src = srcs[i] + 2 * src_stride + 2;
363 const int src_width = src_widths[i] - 4;
364 const int src_height = src_heights[i] - 4;
366 const int dst_stride = dst_strides[i];
367 uint8_t *const dst = dsts[i] + 2 * dst_stride + 2;
369 vp9_post_proc_down_and_across(src, dst, src_stride, dst_stride,
370 src_height, src_width, ppl);
371 }
372 }
374 double vp9_gaussian(double sigma, double mu, double x) {
375 return 1 / (sigma * sqrt(2.0 * 3.14159265)) *
376 (exp(-(x - mu) * (x - mu) / (2 * sigma * sigma)));
377 }
379 static void fillrd(struct postproc_state *state, int q, int a) {
380 char char_dist[300];
382 double sigma;
383 int ai = a, qi = q, i;
385 vp9_clear_system_state();
387 sigma = ai + .5 + .6 * (63 - qi) / 63.0;
389 /* set up a lookup table of 256 entries that matches
390 * a gaussian distribution with sigma determined by q.
391 */
392 {
393 double i;
394 int next, j;
396 next = 0;
398 for (i = -32; i < 32; i++) {
399 int a = (int)(.5 + 256 * vp9_gaussian(sigma, 0, i));
401 if (a) {
402 for (j = 0; j < a; j++) {
403 char_dist[next + j] = (char) i;
404 }
406 next = next + j;
407 }
408 }
410 for (; next < 256; next++)
411 char_dist[next] = 0;
412 }
414 for (i = 0; i < 3072; i++) {
415 state->noise[i] = char_dist[rand() & 0xff]; // NOLINT
416 }
418 for (i = 0; i < 16; i++) {
419 state->blackclamp[i] = -char_dist[0];
420 state->whiteclamp[i] = -char_dist[0];
421 state->bothclamp[i] = -2 * char_dist[0];
422 }
424 state->last_q = q;
425 state->last_noise = a;
426 }
428 /****************************************************************************
429 *
430 * ROUTINE : plane_add_noise_c
431 *
432 * INPUTS : unsigned char *Start starting address of buffer to
433 * add gaussian noise to
434 * unsigned int width width of plane
435 * unsigned int height height of plane
436 * int pitch distance between subsequent lines of frame
437 * int q quantizer used to determine amount of noise
438 * to add
439 *
440 * OUTPUTS : None.
441 *
442 * RETURNS : void.
443 *
444 * FUNCTION : adds gaussian noise to a plane of pixels
445 *
446 * SPECIAL NOTES : None.
447 *
448 ****************************************************************************/
449 void vp9_plane_add_noise_c(uint8_t *start, char *noise,
450 char blackclamp[16],
451 char whiteclamp[16],
452 char bothclamp[16],
453 unsigned int width, unsigned int height, int pitch) {
454 unsigned int i, j;
456 for (i = 0; i < height; i++) {
457 uint8_t *pos = start + i * pitch;
458 char *ref = (char *)(noise + (rand() & 0xff)); // NOLINT
460 for (j = 0; j < width; j++) {
461 if (pos[j] < blackclamp[0])
462 pos[j] = blackclamp[0];
464 if (pos[j] > 255 + whiteclamp[0])
465 pos[j] = 255 + whiteclamp[0];
467 pos[j] += ref[j];
468 }
469 }
470 }
472 /* Blend the macro block with a solid colored square. Leave the
473 * edges unblended to give distinction to macro blocks in areas
474 * filled with the same color block.
475 */
476 void vp9_blend_mb_inner_c(uint8_t *y, uint8_t *u, uint8_t *v,
477 int y1, int u1, int v1, int alpha, int stride) {
478 int i, j;
479 int y1_const = y1 * ((1 << 16) - alpha);
480 int u1_const = u1 * ((1 << 16) - alpha);
481 int v1_const = v1 * ((1 << 16) - alpha);
483 y += 2 * stride + 2;
484 for (i = 0; i < 12; i++) {
485 for (j = 0; j < 12; j++) {
486 y[j] = (y[j] * alpha + y1_const) >> 16;
487 }
488 y += stride;
489 }
491 stride >>= 1;
493 u += stride + 1;
494 v += stride + 1;
496 for (i = 0; i < 6; i++) {
497 for (j = 0; j < 6; j++) {
498 u[j] = (u[j] * alpha + u1_const) >> 16;
499 v[j] = (v[j] * alpha + v1_const) >> 16;
500 }
501 u += stride;
502 v += stride;
503 }
504 }
506 /* Blend only the edge of the macro block. Leave center
507 * unblended to allow for other visualizations to be layered.
508 */
509 void vp9_blend_mb_outer_c(uint8_t *y, uint8_t *u, uint8_t *v,
510 int y1, int u1, int v1, int alpha, int stride) {
511 int i, j;
512 int y1_const = y1 * ((1 << 16) - alpha);
513 int u1_const = u1 * ((1 << 16) - alpha);
514 int v1_const = v1 * ((1 << 16) - alpha);
516 for (i = 0; i < 2; i++) {
517 for (j = 0; j < 16; j++) {
518 y[j] = (y[j] * alpha + y1_const) >> 16;
519 }
520 y += stride;
521 }
523 for (i = 0; i < 12; i++) {
524 y[0] = (y[0] * alpha + y1_const) >> 16;
525 y[1] = (y[1] * alpha + y1_const) >> 16;
526 y[14] = (y[14] * alpha + y1_const) >> 16;
527 y[15] = (y[15] * alpha + y1_const) >> 16;
528 y += stride;
529 }
531 for (i = 0; i < 2; i++) {
532 for (j = 0; j < 16; j++) {
533 y[j] = (y[j] * alpha + y1_const) >> 16;
534 }
535 y += stride;
536 }
538 stride >>= 1;
540 for (j = 0; j < 8; j++) {
541 u[j] = (u[j] * alpha + u1_const) >> 16;
542 v[j] = (v[j] * alpha + v1_const) >> 16;
543 }
544 u += stride;
545 v += stride;
547 for (i = 0; i < 6; i++) {
548 u[0] = (u[0] * alpha + u1_const) >> 16;
549 v[0] = (v[0] * alpha + v1_const) >> 16;
551 u[7] = (u[7] * alpha + u1_const) >> 16;
552 v[7] = (v[7] * alpha + v1_const) >> 16;
554 u += stride;
555 v += stride;
556 }
558 for (j = 0; j < 8; j++) {
559 u[j] = (u[j] * alpha + u1_const) >> 16;
560 v[j] = (v[j] * alpha + v1_const) >> 16;
561 }
562 }
564 void vp9_blend_b_c(uint8_t *y, uint8_t *u, uint8_t *v,
565 int y1, int u1, int v1, int alpha, int stride) {
566 int i, j;
567 int y1_const = y1 * ((1 << 16) - alpha);
568 int u1_const = u1 * ((1 << 16) - alpha);
569 int v1_const = v1 * ((1 << 16) - alpha);
571 for (i = 0; i < 4; i++) {
572 for (j = 0; j < 4; j++) {
573 y[j] = (y[j] * alpha + y1_const) >> 16;
574 }
575 y += stride;
576 }
578 stride >>= 1;
580 for (i = 0; i < 2; i++) {
581 for (j = 0; j < 2; j++) {
582 u[j] = (u[j] * alpha + u1_const) >> 16;
583 v[j] = (v[j] * alpha + v1_const) >> 16;
584 }
585 u += stride;
586 v += stride;
587 }
588 }
590 static void constrain_line(int x0, int *x1, int y0, int *y1,
591 int width, int height) {
592 int dx;
593 int dy;
595 if (*x1 > width) {
596 dx = *x1 - x0;
597 dy = *y1 - y0;
599 *x1 = width;
600 if (dx)
601 *y1 = ((width - x0) * dy) / dx + y0;
602 }
603 if (*x1 < 0) {
604 dx = *x1 - x0;
605 dy = *y1 - y0;
607 *x1 = 0;
608 if (dx)
609 *y1 = ((0 - x0) * dy) / dx + y0;
610 }
611 if (*y1 > height) {
612 dx = *x1 - x0;
613 dy = *y1 - y0;
615 *y1 = height;
616 if (dy)
617 *x1 = ((height - y0) * dx) / dy + x0;
618 }
619 if (*y1 < 0) {
620 dx = *x1 - x0;
621 dy = *y1 - y0;
623 *y1 = 0;
624 if (dy)
625 *x1 = ((0 - y0) * dx) / dy + x0;
626 }
627 }
629 int vp9_post_proc_frame(struct VP9Common *cm,
630 YV12_BUFFER_CONFIG *dest, vp9_ppflags_t *ppflags) {
631 int q = cm->lf.filter_level * 10 / 6;
632 int flags = ppflags->post_proc_flag;
633 int deblock_level = ppflags->deblocking_level;
634 int noise_level = ppflags->noise_level;
636 if (!cm->frame_to_show)
637 return -1;
639 if (q > 63)
640 q = 63;
642 if (!flags) {
643 *dest = *cm->frame_to_show;
644 return 0;
645 }
647 #if ARCH_X86||ARCH_X86_64
648 vpx_reset_mmx_state();
649 #endif
651 if (flags & VP9D_DEMACROBLOCK) {
652 deblock_and_de_macro_block(cm->frame_to_show, &cm->post_proc_buffer,
653 q + (deblock_level - 5) * 10, 1, 0);
654 } else if (flags & VP9D_DEBLOCK) {
655 vp9_deblock(cm->frame_to_show, &cm->post_proc_buffer, q);
656 } else {
657 vp8_yv12_copy_frame(cm->frame_to_show, &cm->post_proc_buffer);
658 }
660 if (flags & VP9D_ADDNOISE) {
661 if (cm->postproc_state.last_q != q
662 || cm->postproc_state.last_noise != noise_level) {
663 fillrd(&cm->postproc_state, 63 - q, noise_level);
664 }
666 vp9_plane_add_noise(cm->post_proc_buffer.y_buffer,
667 cm->postproc_state.noise,
668 cm->postproc_state.blackclamp,
669 cm->postproc_state.whiteclamp,
670 cm->postproc_state.bothclamp,
671 cm->post_proc_buffer.y_width,
672 cm->post_proc_buffer.y_height,
673 cm->post_proc_buffer.y_stride);
674 }
676 #if 0 && CONFIG_POSTPROC_VISUALIZER
677 if (flags & VP9D_DEBUG_TXT_FRAME_INFO) {
678 char message[512];
679 snprintf(message, sizeof(message) -1,
680 "F%1dG%1dQ%3dF%3dP%d_s%dx%d",
681 (cm->frame_type == KEY_FRAME),
682 cm->refresh_golden_frame,
683 cm->base_qindex,
684 cm->filter_level,
685 flags,
686 cm->mb_cols, cm->mb_rows);
687 vp9_blit_text(message, cm->post_proc_buffer.y_buffer,
688 cm->post_proc_buffer.y_stride);
689 }
691 if (flags & VP9D_DEBUG_TXT_MBLK_MODES) {
692 int i, j;
693 uint8_t *y_ptr;
694 YV12_BUFFER_CONFIG *post = &cm->post_proc_buffer;
695 int mb_rows = post->y_height >> 4;
696 int mb_cols = post->y_width >> 4;
697 int mb_index = 0;
698 MODE_INFO *mi = cm->mi;
700 y_ptr = post->y_buffer + 4 * post->y_stride + 4;
702 /* vp9_filter each macro block */
703 for (i = 0; i < mb_rows; i++) {
704 for (j = 0; j < mb_cols; j++) {
705 char zz[4];
707 snprintf(zz, sizeof(zz) - 1, "%c", mi[mb_index].mbmi.mode + 'a');
709 vp9_blit_text(zz, y_ptr, post->y_stride);
710 mb_index++;
711 y_ptr += 16;
712 }
714 mb_index++; /* border */
715 y_ptr += post->y_stride * 16 - post->y_width;
716 }
717 }
719 if (flags & VP9D_DEBUG_TXT_DC_DIFF) {
720 int i, j;
721 uint8_t *y_ptr;
722 YV12_BUFFER_CONFIG *post = &cm->post_proc_buffer;
723 int mb_rows = post->y_height >> 4;
724 int mb_cols = post->y_width >> 4;
725 int mb_index = 0;
726 MODE_INFO *mi = cm->mi;
728 y_ptr = post->y_buffer + 4 * post->y_stride + 4;
730 /* vp9_filter each macro block */
731 for (i = 0; i < mb_rows; i++) {
732 for (j = 0; j < mb_cols; j++) {
733 char zz[4];
734 int dc_diff = !(mi[mb_index].mbmi.mode != I4X4_PRED &&
735 mi[mb_index].mbmi.mode != SPLITMV &&
736 mi[mb_index].mbmi.skip_coeff);
738 if (cm->frame_type == KEY_FRAME)
739 snprintf(zz, sizeof(zz) - 1, "a");
740 else
741 snprintf(zz, sizeof(zz) - 1, "%c", dc_diff + '0');
743 vp9_blit_text(zz, y_ptr, post->y_stride);
744 mb_index++;
745 y_ptr += 16;
746 }
748 mb_index++; /* border */
749 y_ptr += post->y_stride * 16 - post->y_width;
750 }
751 }
753 if (flags & VP9D_DEBUG_TXT_RATE_INFO) {
754 char message[512];
755 snprintf(message, sizeof(message),
756 "Bitrate: %10.2f framerate: %10.2f ",
757 cm->bitrate, cm->framerate);
758 vp9_blit_text(message, cm->post_proc_buffer.y_buffer,
759 cm->post_proc_buffer.y_stride);
760 }
762 /* Draw motion vectors */
763 if ((flags & VP9D_DEBUG_DRAW_MV) && ppflags->display_mv_flag) {
764 YV12_BUFFER_CONFIG *post = &cm->post_proc_buffer;
765 int width = post->y_width;
766 int height = post->y_height;
767 uint8_t *y_buffer = cm->post_proc_buffer.y_buffer;
768 int y_stride = cm->post_proc_buffer.y_stride;
769 MODE_INFO *mi = cm->mi;
770 int x0, y0;
772 for (y0 = 0; y0 < height; y0 += 16) {
773 for (x0 = 0; x0 < width; x0 += 16) {
774 int x1, y1;
776 if (!(ppflags->display_mv_flag & (1 << mi->mbmi.mode))) {
777 mi++;
778 continue;
779 }
781 if (mi->mbmi.mode == SPLITMV) {
782 switch (mi->mbmi.partitioning) {
783 case PARTITIONING_16X8 : { /* mv_top_bottom */
784 union b_mode_info *bmi = &mi->bmi[0];
785 MV *mv = &bmi->mv.as_mv;
787 x1 = x0 + 8 + (mv->col >> 3);
788 y1 = y0 + 4 + (mv->row >> 3);
790 constrain_line(x0 + 8, &x1, y0 + 4, &y1, width, height);
791 vp9_blit_line(x0 + 8, x1, y0 + 4, y1, y_buffer, y_stride);
793 bmi = &mi->bmi[8];
795 x1 = x0 + 8 + (mv->col >> 3);
796 y1 = y0 + 12 + (mv->row >> 3);
798 constrain_line(x0 + 8, &x1, y0 + 12, &y1, width, height);
799 vp9_blit_line(x0 + 8, x1, y0 + 12, y1, y_buffer, y_stride);
801 break;
802 }
803 case PARTITIONING_8X16 : { /* mv_left_right */
804 union b_mode_info *bmi = &mi->bmi[0];
805 MV *mv = &bmi->mv.as_mv;
807 x1 = x0 + 4 + (mv->col >> 3);
808 y1 = y0 + 8 + (mv->row >> 3);
810 constrain_line(x0 + 4, &x1, y0 + 8, &y1, width, height);
811 vp9_blit_line(x0 + 4, x1, y0 + 8, y1, y_buffer, y_stride);
813 bmi = &mi->bmi[2];
815 x1 = x0 + 12 + (mv->col >> 3);
816 y1 = y0 + 8 + (mv->row >> 3);
818 constrain_line(x0 + 12, &x1, y0 + 8, &y1, width, height);
819 vp9_blit_line(x0 + 12, x1, y0 + 8, y1, y_buffer, y_stride);
821 break;
822 }
823 case PARTITIONING_8X8 : { /* mv_quarters */
824 union b_mode_info *bmi = &mi->bmi[0];
825 MV *mv = &bmi->mv.as_mv;
827 x1 = x0 + 4 + (mv->col >> 3);
828 y1 = y0 + 4 + (mv->row >> 3);
830 constrain_line(x0 + 4, &x1, y0 + 4, &y1, width, height);
831 vp9_blit_line(x0 + 4, x1, y0 + 4, y1, y_buffer, y_stride);
833 bmi = &mi->bmi[2];
835 x1 = x0 + 12 + (mv->col >> 3);
836 y1 = y0 + 4 + (mv->row >> 3);
838 constrain_line(x0 + 12, &x1, y0 + 4, &y1, width, height);
839 vp9_blit_line(x0 + 12, x1, y0 + 4, y1, y_buffer, y_stride);
841 bmi = &mi->bmi[8];
843 x1 = x0 + 4 + (mv->col >> 3);
844 y1 = y0 + 12 + (mv->row >> 3);
846 constrain_line(x0 + 4, &x1, y0 + 12, &y1, width, height);
847 vp9_blit_line(x0 + 4, x1, y0 + 12, y1, y_buffer, y_stride);
849 bmi = &mi->bmi[10];
851 x1 = x0 + 12 + (mv->col >> 3);
852 y1 = y0 + 12 + (mv->row >> 3);
854 constrain_line(x0 + 12, &x1, y0 + 12, &y1, width, height);
855 vp9_blit_line(x0 + 12, x1, y0 + 12, y1, y_buffer, y_stride);
856 break;
857 }
858 case PARTITIONING_4X4:
859 default : {
860 union b_mode_info *bmi = mi->bmi;
861 int bx0, by0;
863 for (by0 = y0; by0 < (y0 + 16); by0 += 4) {
864 for (bx0 = x0; bx0 < (x0 + 16); bx0 += 4) {
865 MV *mv = &bmi->mv.as_mv;
867 x1 = bx0 + 2 + (mv->col >> 3);
868 y1 = by0 + 2 + (mv->row >> 3);
870 constrain_line(bx0 + 2, &x1, by0 + 2, &y1, width, height);
871 vp9_blit_line(bx0 + 2, x1, by0 + 2, y1, y_buffer, y_stride);
873 bmi++;
874 }
875 }
876 }
877 }
878 } else if (is_inter_mode(mi->mbmi.mode)) {
879 MV *mv = &mi->mbmi.mv.as_mv;
880 const int lx0 = x0 + 8;
881 const int ly0 = y0 + 8;
883 x1 = lx0 + (mv->col >> 3);
884 y1 = ly0 + (mv->row >> 3);
886 if (x1 != lx0 && y1 != ly0) {
887 constrain_line(lx0, &x1, ly0 - 1, &y1, width, height);
888 vp9_blit_line(lx0, x1, ly0 - 1, y1, y_buffer, y_stride);
890 constrain_line(lx0, &x1, ly0 + 1, &y1, width, height);
891 vp9_blit_line(lx0, x1, ly0 + 1, y1, y_buffer, y_stride);
892 } else {
893 vp9_blit_line(lx0, x1, ly0, y1, y_buffer, y_stride);
894 }
895 }
897 mi++;
898 }
899 mi++;
900 }
901 }
903 /* Color in block modes */
904 if ((flags & VP9D_DEBUG_CLR_BLK_MODES)
905 && (ppflags->display_mb_modes_flag || ppflags->display_b_modes_flag)) {
906 int y, x;
907 YV12_BUFFER_CONFIG *post = &cm->post_proc_buffer;
908 int width = post->y_width;
909 int height = post->y_height;
910 uint8_t *y_ptr = cm->post_proc_buffer.y_buffer;
911 uint8_t *u_ptr = cm->post_proc_buffer.u_buffer;
912 uint8_t *v_ptr = cm->post_proc_buffer.v_buffer;
913 int y_stride = cm->post_proc_buffer.y_stride;
914 MODE_INFO *mi = cm->mi;
916 for (y = 0; y < height; y += 16) {
917 for (x = 0; x < width; x += 16) {
918 int Y = 0, U = 0, V = 0;
920 if (mi->mbmi.mode == I4X4_PRED &&
921 ((ppflags->display_mb_modes_flag & I4X4_PRED) ||
922 ppflags->display_b_modes_flag)) {
923 int by, bx;
924 uint8_t *yl, *ul, *vl;
925 union b_mode_info *bmi = mi->bmi;
927 yl = y_ptr + x;
928 ul = u_ptr + (x >> 1);
929 vl = v_ptr + (x >> 1);
931 for (by = 0; by < 16; by += 4) {
932 for (bx = 0; bx < 16; bx += 4) {
933 if ((ppflags->display_b_modes_flag & (1 << mi->mbmi.mode))
934 || (ppflags->display_mb_modes_flag & I4X4_PRED)) {
935 Y = B_PREDICTION_MODE_colors[bmi->as_mode][0];
936 U = B_PREDICTION_MODE_colors[bmi->as_mode][1];
937 V = B_PREDICTION_MODE_colors[bmi->as_mode][2];
939 vp9_blend_b(yl + bx, ul + (bx >> 1), vl + (bx >> 1), Y, U, V,
940 0xc000, y_stride);
941 }
942 bmi++;
943 }
945 yl += y_stride * 4;
946 ul += y_stride * 1;
947 vl += y_stride * 1;
948 }
949 } else if (ppflags->display_mb_modes_flag & (1 << mi->mbmi.mode)) {
950 Y = MB_PREDICTION_MODE_colors[mi->mbmi.mode][0];
951 U = MB_PREDICTION_MODE_colors[mi->mbmi.mode][1];
952 V = MB_PREDICTION_MODE_colors[mi->mbmi.mode][2];
954 vp9_blend_mb_inner(y_ptr + x, u_ptr + (x >> 1), v_ptr + (x >> 1),
955 Y, U, V, 0xc000, y_stride);
956 }
958 mi++;
959 }
960 y_ptr += y_stride * 16;
961 u_ptr += y_stride * 4;
962 v_ptr += y_stride * 4;
964 mi++;
965 }
966 }
968 /* Color in frame reference blocks */
969 if ((flags & VP9D_DEBUG_CLR_FRM_REF_BLKS) &&
970 ppflags->display_ref_frame_flag) {
971 int y, x;
972 YV12_BUFFER_CONFIG *post = &cm->post_proc_buffer;
973 int width = post->y_width;
974 int height = post->y_height;
975 uint8_t *y_ptr = cm->post_proc_buffer.y_buffer;
976 uint8_t *u_ptr = cm->post_proc_buffer.u_buffer;
977 uint8_t *v_ptr = cm->post_proc_buffer.v_buffer;
978 int y_stride = cm->post_proc_buffer.y_stride;
979 MODE_INFO *mi = cm->mi;
981 for (y = 0; y < height; y += 16) {
982 for (x = 0; x < width; x += 16) {
983 int Y = 0, U = 0, V = 0;
985 if (ppflags->display_ref_frame_flag & (1 << mi->mbmi.ref_frame)) {
986 Y = MV_REFERENCE_FRAME_colors[mi->mbmi.ref_frame][0];
987 U = MV_REFERENCE_FRAME_colors[mi->mbmi.ref_frame][1];
988 V = MV_REFERENCE_FRAME_colors[mi->mbmi.ref_frame][2];
990 vp9_blend_mb_outer(y_ptr + x, u_ptr + (x >> 1), v_ptr + (x >> 1),
991 Y, U, V, 0xc000, y_stride);
992 }
994 mi++;
995 }
996 y_ptr += y_stride * 16;
997 u_ptr += y_stride * 4;
998 v_ptr += y_stride * 4;
1000 mi++;
1001 }
1002 }
1003 #endif
1005 *dest = cm->post_proc_buffer;
1007 /* handle problem with extending borders */
1008 dest->y_width = cm->width;
1009 dest->y_height = cm->height;
1010 dest->uv_width = dest->y_width >> cm->subsampling_x;
1011 dest->uv_height = dest->y_height >> cm->subsampling_y;
1013 return 0;
1014 }