media/libvpx/vp9/common/vp9_postproc.c

branch
TOR_BUG_9701
changeset 15
b8a032363ba2
equal deleted inserted replaced
-1:000000000000 0:3405b8a49641
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 */
10
11 #include <math.h>
12 #include <stdlib.h>
13 #include <stdio.h>
14
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"
23
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)
31
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 };
53
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 };
70
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
78
79 static const short kernel5[] = {
80 1, 1, 4, 1, 1
81 };
82
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 };
129
130
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;
149
150 for (row = 0; row < rows; row++) {
151 /* post_proc_down for one row */
152 p_src = src_ptr;
153 p_dst = dst_ptr;
154
155 for (col = 0; col < cols; col++) {
156 int kernel = 4;
157 int v = p_src[col];
158
159 for (i = -2; i <= 2; i++) {
160 if (abs(v - p_src[col + i * pitch]) > flimit)
161 goto down_skip_convolve;
162
163 kernel += kernel5[2 + i] * p_src[col + i * pitch];
164 }
165
166 v = (kernel >> 3);
167 down_skip_convolve:
168 p_dst[col] = v;
169 }
170
171 /* now post_proc_across */
172 p_src = dst_ptr;
173 p_dst = dst_ptr;
174
175 for (i = 0; i < 8; i++)
176 d[i] = p_src[i];
177
178 for (col = 0; col < cols; col++) {
179 int kernel = 4;
180 v = p_src[col];
181
182 d[col & 7] = v;
183
184 for (i = -2; i <= 2; i++) {
185 if (abs(v - p_src[col + i]) > flimit)
186 goto across_skip_convolve;
187
188 kernel += kernel5[2 + i] * p_src[col + i];
189 }
190
191 d[col & 7] = (kernel >> 3);
192 across_skip_convolve:
193
194 if (col >= 2)
195 p_dst[col - 2] = d[(col - 2) & 7];
196 }
197
198 /* handle the last two pixels */
199 p_dst[col - 2] = d[(col - 2) & 7];
200 p_dst[col - 1] = d[(col - 1) & 7];
201
202
203 /* next row */
204 src_ptr += pitch;
205 dst_ptr += pitch;
206 }
207 }
208
209 static int q2mbl(int x) {
210 if (x < 20) x = 20;
211
212 x = 50 + (x - 50) * 10 / 8;
213 return x * x / 3;
214 }
215
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;
219
220 uint8_t *s = src;
221 uint8_t d[16];
222
223
224 for (r = 0; r < rows; r++) {
225 int sumsq = 0;
226 int sum = 0;
227
228 for (i = -8; i <= 6; i++) {
229 sumsq += s[i] * s[i];
230 sum += s[i];
231 d[i + 8] = 0;
232 }
233
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];
237
238 sum += x;
239 sumsq += x * y;
240
241 d[c & 15] = s[c];
242
243 if (sumsq * 15 - sum * sum < flimit) {
244 d[c & 15] = (8 + sum + s[c]) >> 4;
245 }
246
247 s[c - 8] = d[(c - 8) & 15];
248 }
249
250 s += pitch;
251 }
252 }
253
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
258
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);
265
266 for (i = -8; i <= 6; i++) {
267 sumsq += s[i * pitch] * s[i * pitch];
268 sum += s[i * pitch];
269 }
270
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];
275
276 if (sumsq * 15 - sum * sum < flimit) {
277 d[r & 15] = (rv2[r & 127] + sum + s[0]) >> 4;
278 }
279
280 s[-8 * pitch] = d[(r - 8) & 15];
281 s += pitch;
282 }
283 }
284 }
285
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;
295
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);
299
300 vp9_mbpost_proc_across_ip(post->y_buffer, post->y_stride, post->y_height,
301 post->y_width, q2mbl(q));
302
303 vp9_mbpost_proc_down(post->y_buffer, post->y_stride, post->y_height,
304 post->y_width, q2mbl(q));
305
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 }
313
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;
319
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};
328
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};
333
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 }
339
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;
345
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};
354
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};
359
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;
365
366 const int dst_stride = dst_strides[i];
367 uint8_t *const dst = dsts[i] + 2 * dst_stride + 2;
368
369 vp9_post_proc_down_and_across(src, dst, src_stride, dst_stride,
370 src_height, src_width, ppl);
371 }
372 }
373
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 }
378
379 static void fillrd(struct postproc_state *state, int q, int a) {
380 char char_dist[300];
381
382 double sigma;
383 int ai = a, qi = q, i;
384
385 vp9_clear_system_state();
386
387 sigma = ai + .5 + .6 * (63 - qi) / 63.0;
388
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;
395
396 next = 0;
397
398 for (i = -32; i < 32; i++) {
399 int a = (int)(.5 + 256 * vp9_gaussian(sigma, 0, i));
400
401 if (a) {
402 for (j = 0; j < a; j++) {
403 char_dist[next + j] = (char) i;
404 }
405
406 next = next + j;
407 }
408 }
409
410 for (; next < 256; next++)
411 char_dist[next] = 0;
412 }
413
414 for (i = 0; i < 3072; i++) {
415 state->noise[i] = char_dist[rand() & 0xff]; // NOLINT
416 }
417
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 }
423
424 state->last_q = q;
425 state->last_noise = a;
426 }
427
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;
455
456 for (i = 0; i < height; i++) {
457 uint8_t *pos = start + i * pitch;
458 char *ref = (char *)(noise + (rand() & 0xff)); // NOLINT
459
460 for (j = 0; j < width; j++) {
461 if (pos[j] < blackclamp[0])
462 pos[j] = blackclamp[0];
463
464 if (pos[j] > 255 + whiteclamp[0])
465 pos[j] = 255 + whiteclamp[0];
466
467 pos[j] += ref[j];
468 }
469 }
470 }
471
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);
482
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 }
490
491 stride >>= 1;
492
493 u += stride + 1;
494 v += stride + 1;
495
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 }
505
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);
515
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 }
522
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 }
530
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 }
537
538 stride >>= 1;
539
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;
546
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;
550
551 u[7] = (u[7] * alpha + u1_const) >> 16;
552 v[7] = (v[7] * alpha + v1_const) >> 16;
553
554 u += stride;
555 v += stride;
556 }
557
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 }
563
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);
570
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 }
577
578 stride >>= 1;
579
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 }
589
590 static void constrain_line(int x0, int *x1, int y0, int *y1,
591 int width, int height) {
592 int dx;
593 int dy;
594
595 if (*x1 > width) {
596 dx = *x1 - x0;
597 dy = *y1 - y0;
598
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;
606
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;
614
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;
622
623 *y1 = 0;
624 if (dy)
625 *x1 = ((0 - y0) * dx) / dy + x0;
626 }
627 }
628
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;
635
636 if (!cm->frame_to_show)
637 return -1;
638
639 if (q > 63)
640 q = 63;
641
642 if (!flags) {
643 *dest = *cm->frame_to_show;
644 return 0;
645 }
646
647 #if ARCH_X86||ARCH_X86_64
648 vpx_reset_mmx_state();
649 #endif
650
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 }
659
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 }
665
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 }
675
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 }
690
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;
699
700 y_ptr = post->y_buffer + 4 * post->y_stride + 4;
701
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];
706
707 snprintf(zz, sizeof(zz) - 1, "%c", mi[mb_index].mbmi.mode + 'a');
708
709 vp9_blit_text(zz, y_ptr, post->y_stride);
710 mb_index++;
711 y_ptr += 16;
712 }
713
714 mb_index++; /* border */
715 y_ptr += post->y_stride * 16 - post->y_width;
716 }
717 }
718
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;
727
728 y_ptr = post->y_buffer + 4 * post->y_stride + 4;
729
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);
737
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');
742
743 vp9_blit_text(zz, y_ptr, post->y_stride);
744 mb_index++;
745 y_ptr += 16;
746 }
747
748 mb_index++; /* border */
749 y_ptr += post->y_stride * 16 - post->y_width;
750 }
751 }
752
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 }
761
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;
771
772 for (y0 = 0; y0 < height; y0 += 16) {
773 for (x0 = 0; x0 < width; x0 += 16) {
774 int x1, y1;
775
776 if (!(ppflags->display_mv_flag & (1 << mi->mbmi.mode))) {
777 mi++;
778 continue;
779 }
780
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;
786
787 x1 = x0 + 8 + (mv->col >> 3);
788 y1 = y0 + 4 + (mv->row >> 3);
789
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);
792
793 bmi = &mi->bmi[8];
794
795 x1 = x0 + 8 + (mv->col >> 3);
796 y1 = y0 + 12 + (mv->row >> 3);
797
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);
800
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;
806
807 x1 = x0 + 4 + (mv->col >> 3);
808 y1 = y0 + 8 + (mv->row >> 3);
809
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);
812
813 bmi = &mi->bmi[2];
814
815 x1 = x0 + 12 + (mv->col >> 3);
816 y1 = y0 + 8 + (mv->row >> 3);
817
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);
820
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;
826
827 x1 = x0 + 4 + (mv->col >> 3);
828 y1 = y0 + 4 + (mv->row >> 3);
829
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);
832
833 bmi = &mi->bmi[2];
834
835 x1 = x0 + 12 + (mv->col >> 3);
836 y1 = y0 + 4 + (mv->row >> 3);
837
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);
840
841 bmi = &mi->bmi[8];
842
843 x1 = x0 + 4 + (mv->col >> 3);
844 y1 = y0 + 12 + (mv->row >> 3);
845
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);
848
849 bmi = &mi->bmi[10];
850
851 x1 = x0 + 12 + (mv->col >> 3);
852 y1 = y0 + 12 + (mv->row >> 3);
853
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;
862
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;
866
867 x1 = bx0 + 2 + (mv->col >> 3);
868 y1 = by0 + 2 + (mv->row >> 3);
869
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);
872
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;
882
883 x1 = lx0 + (mv->col >> 3);
884 y1 = ly0 + (mv->row >> 3);
885
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);
889
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 }
896
897 mi++;
898 }
899 mi++;
900 }
901 }
902
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;
915
916 for (y = 0; y < height; y += 16) {
917 for (x = 0; x < width; x += 16) {
918 int Y = 0, U = 0, V = 0;
919
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;
926
927 yl = y_ptr + x;
928 ul = u_ptr + (x >> 1);
929 vl = v_ptr + (x >> 1);
930
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];
938
939 vp9_blend_b(yl + bx, ul + (bx >> 1), vl + (bx >> 1), Y, U, V,
940 0xc000, y_stride);
941 }
942 bmi++;
943 }
944
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];
953
954 vp9_blend_mb_inner(y_ptr + x, u_ptr + (x >> 1), v_ptr + (x >> 1),
955 Y, U, V, 0xc000, y_stride);
956 }
957
958 mi++;
959 }
960 y_ptr += y_stride * 16;
961 u_ptr += y_stride * 4;
962 v_ptr += y_stride * 4;
963
964 mi++;
965 }
966 }
967
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;
980
981 for (y = 0; y < height; y += 16) {
982 for (x = 0; x < width; x += 16) {
983 int Y = 0, U = 0, V = 0;
984
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];
989
990 vp9_blend_mb_outer(y_ptr + x, u_ptr + (x >> 1), v_ptr + (x >> 1),
991 Y, U, V, 0xc000, y_stride);
992 }
993
994 mi++;
995 }
996 y_ptr += y_stride * 16;
997 u_ptr += y_stride * 4;
998 v_ptr += y_stride * 4;
999
1000 mi++;
1001 }
1002 }
1003 #endif
1004
1005 *dest = cm->post_proc_buffer;
1006
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;
1012
1013 return 0;
1014 }

mercurial