Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2165)

Side by Side Diff: source/libvpx/vp9/common/vp9_postproc.c

Issue 11555023: libvpx: Add VP9 decoder. (Closed) Base URL: svn://chrome-svn/chrome/trunk/deps/third_party/libvpx/
Patch Set: Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
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
12 #include "vpx_ports/config.h"
13 #include "vpx_scale/yv12config.h"
14 #include "vp9/common/vp9_postproc.h"
15 #include "vp9/common/vp9_textblit.h"
16 #include "vpx_scale/vpxscale.h"
17 #include "vp9/common/vp9_systemdependent.h"
18 #include "./vp9_rtcd.h"
19 #include "./vpx_scale_rtcd.h"
20
21
22 #include <math.h>
23 #include <stdlib.h>
24 #include <stdio.h>
25
26 #define RGB_TO_YUV(t) \
27 ( (0.257*(float)(t >> 16)) + (0.504*(float)(t >> 8 & 0xff)) + \
28 (0.098*(float)(t & 0xff)) + 16), \
29 (-(0.148*(float)(t >> 16)) - (0.291*(float)(t >> 8 & 0xff)) + \
30 (0.439*(float)(t & 0xff)) + 128), \
31 ( (0.439*(float)(t >> 16)) - (0.368*(float)(t >> 8 & 0xff)) - \
32 (0.071*(float)(t & 0xff)) + 128)
33
34 /* global constants */
35 #if CONFIG_POSTPROC_VISUALIZER
36 static const unsigned char MB_PREDICTION_MODE_colors[MB_MODE_COUNT][3] = {
37 { RGB_TO_YUV(0x98FB98) }, /* PaleGreen */
38 { RGB_TO_YUV(0x00FF00) }, /* Green */
39 { RGB_TO_YUV(0xADFF2F) }, /* GreenYellow */
40 { RGB_TO_YUV(0x8F0000) }, /* Dark Red */
41 { RGB_TO_YUV(0x008F8F) }, /* Dark Cyan */
42 { RGB_TO_YUV(0x008F8F) }, /* Dark Cyan */
43 { RGB_TO_YUV(0x008F8F) }, /* Dark Cyan */
44 { RGB_TO_YUV(0x8F0000) }, /* Dark Red */
45 { RGB_TO_YUV(0x8F0000) }, /* Dark Red */
46 { RGB_TO_YUV(0x228B22) }, /* ForestGreen */
47 { RGB_TO_YUV(0x006400) }, /* DarkGreen */
48 { RGB_TO_YUV(0x98F5FF) }, /* Cadet Blue */
49 { RGB_TO_YUV(0x6CA6CD) }, /* Sky Blue */
50 { RGB_TO_YUV(0x00008B) }, /* Dark blue */
51 { RGB_TO_YUV(0x551A8B) }, /* Purple */
52 { RGB_TO_YUV(0xFF0000) } /* Red */
53 { RGB_TO_YUV(0xCC33FF) }, /* Magenta */
54 };
55
56 static const unsigned char B_PREDICTION_MODE_colors[B_MODE_COUNT][3] = {
57 { RGB_TO_YUV(0x6633ff) }, /* Purple */
58 { RGB_TO_YUV(0xcc33ff) }, /* Magenta */
59 { RGB_TO_YUV(0xff33cc) }, /* Pink */
60 { RGB_TO_YUV(0xff3366) }, /* Coral */
61 { RGB_TO_YUV(0x3366ff) }, /* Blue */
62 { RGB_TO_YUV(0xed00f5) }, /* Dark Blue */
63 { RGB_TO_YUV(0x2e00b8) }, /* Dark Purple */
64 { RGB_TO_YUV(0xff6633) }, /* Orange */
65 { RGB_TO_YUV(0x33ccff) }, /* Light Blue */
66 { RGB_TO_YUV(0x8ab800) }, /* Green */
67 { RGB_TO_YUV(0xffcc33) }, /* Light Orange */
68 { RGB_TO_YUV(0x33ffcc) }, /* Aqua */
69 { RGB_TO_YUV(0x66ff33) }, /* Light Green */
70 { RGB_TO_YUV(0xccff33) }, /* Yellow */
71 };
72
73 static const unsigned char MV_REFERENCE_FRAME_colors[MAX_REF_FRAMES][3] = {
74 { RGB_TO_YUV(0x00ff00) }, /* Blue */
75 { RGB_TO_YUV(0x0000ff) }, /* Green */
76 { RGB_TO_YUV(0xffff00) }, /* Yellow */
77 { RGB_TO_YUV(0xff0000) }, /* Red */
78 };
79 #endif
80
81 static const short kernel5[] = {
82 1, 1, 4, 1, 1
83 };
84
85 const short vp9_rv[] = {
86 8, 5, 2, 2, 8, 12, 4, 9, 8, 3,
87 0, 3, 9, 0, 0, 0, 8, 3, 14, 4,
88 10, 1, 11, 14, 1, 14, 9, 6, 12, 11,
89 8, 6, 10, 0, 0, 8, 9, 0, 3, 14,
90 8, 11, 13, 4, 2, 9, 0, 3, 9, 6,
91 1, 2, 3, 14, 13, 1, 8, 2, 9, 7,
92 3, 3, 1, 13, 13, 6, 6, 5, 2, 7,
93 11, 9, 11, 8, 7, 3, 2, 0, 13, 13,
94 14, 4, 12, 5, 12, 10, 8, 10, 13, 10,
95 4, 14, 4, 10, 0, 8, 11, 1, 13, 7,
96 7, 14, 6, 14, 13, 2, 13, 5, 4, 4,
97 0, 10, 0, 5, 13, 2, 12, 7, 11, 13,
98 8, 0, 4, 10, 7, 2, 7, 2, 2, 5,
99 3, 4, 7, 3, 3, 14, 14, 5, 9, 13,
100 3, 14, 3, 6, 3, 0, 11, 8, 13, 1,
101 13, 1, 12, 0, 10, 9, 7, 6, 2, 8,
102 5, 2, 13, 7, 1, 13, 14, 7, 6, 7,
103 9, 6, 10, 11, 7, 8, 7, 5, 14, 8,
104 4, 4, 0, 8, 7, 10, 0, 8, 14, 11,
105 3, 12, 5, 7, 14, 3, 14, 5, 2, 6,
106 11, 12, 12, 8, 0, 11, 13, 1, 2, 0,
107 5, 10, 14, 7, 8, 0, 4, 11, 0, 8,
108 0, 3, 10, 5, 8, 0, 11, 6, 7, 8,
109 10, 7, 13, 9, 2, 5, 1, 5, 10, 2,
110 4, 3, 5, 6, 10, 8, 9, 4, 11, 14,
111 0, 10, 0, 5, 13, 2, 12, 7, 11, 13,
112 8, 0, 4, 10, 7, 2, 7, 2, 2, 5,
113 3, 4, 7, 3, 3, 14, 14, 5, 9, 13,
114 3, 14, 3, 6, 3, 0, 11, 8, 13, 1,
115 13, 1, 12, 0, 10, 9, 7, 6, 2, 8,
116 5, 2, 13, 7, 1, 13, 14, 7, 6, 7,
117 9, 6, 10, 11, 7, 8, 7, 5, 14, 8,
118 4, 4, 0, 8, 7, 10, 0, 8, 14, 11,
119 3, 12, 5, 7, 14, 3, 14, 5, 2, 6,
120 11, 12, 12, 8, 0, 11, 13, 1, 2, 0,
121 5, 10, 14, 7, 8, 0, 4, 11, 0, 8,
122 0, 3, 10, 5, 8, 0, 11, 6, 7, 8,
123 10, 7, 13, 9, 2, 5, 1, 5, 10, 2,
124 4, 3, 5, 6, 10, 8, 9, 4, 11, 14,
125 3, 8, 3, 7, 8, 5, 11, 4, 12, 3,
126 11, 9, 14, 8, 14, 13, 4, 3, 1, 2,
127 14, 6, 5, 4, 4, 11, 4, 6, 2, 1,
128 5, 8, 8, 12, 13, 5, 14, 10, 12, 13,
129 0, 9, 5, 5, 11, 10, 13, 9, 10, 13,
130 };
131
132
133 /****************************************************************************
134 */
135 void vp9_post_proc_down_and_across_c(unsigned char *src_ptr,
136 unsigned char *dst_ptr,
137 int src_pixels_per_line,
138 int dst_pixels_per_line,
139 int rows,
140 int cols,
141 int flimit) {
142 unsigned char *p_src, *p_dst;
143 int row;
144 int col;
145 int i;
146 int v;
147 int pitch = src_pixels_per_line;
148 unsigned char d[8];
149 (void)dst_pixels_per_line;
150
151 for (row = 0; row < rows; row++) {
152 /* post_proc_down for one row */
153 p_src = src_ptr;
154 p_dst = dst_ptr;
155
156 for (col = 0; col < cols; col++) {
157
158 int kernel = 4;
159 int v = p_src[col];
160
161 for (i = -2; i <= 2; i++) {
162 if (abs(v - p_src[col + i * pitch]) > flimit)
163 goto down_skip_convolve;
164
165 kernel += kernel5[2 + i] * p_src[col + i * pitch];
166 }
167
168 v = (kernel >> 3);
169 down_skip_convolve:
170 p_dst[col] = v;
171 }
172
173 /* now post_proc_across */
174 p_src = dst_ptr;
175 p_dst = dst_ptr;
176
177 for (i = 0; i < 8; i++)
178 d[i] = p_src[i];
179
180 for (col = 0; col < cols; col++) {
181 int kernel = 4;
182 v = p_src[col];
183
184 d[col & 7] = v;
185
186 for (i = -2; i <= 2; i++) {
187 if (abs(v - p_src[col + i]) > flimit)
188 goto across_skip_convolve;
189
190 kernel += kernel5[2 + i] * p_src[col + i];
191 }
192
193 d[col & 7] = (kernel >> 3);
194 across_skip_convolve:
195
196 if (col >= 2)
197 p_dst[col - 2] = d[(col - 2) & 7];
198 }
199
200 /* handle the last two pixels */
201 p_dst[col - 2] = d[(col - 2) & 7];
202 p_dst[col - 1] = d[(col - 1) & 7];
203
204
205 /* next row */
206 src_ptr += pitch;
207 dst_ptr += pitch;
208 }
209 }
210
211 static int q2mbl(int x) {
212 if (x < 20) x = 20;
213
214 x = 50 + (x - 50) * 10 / 8;
215 return x * x / 3;
216 }
217
218 void vp9_mbpost_proc_across_ip_c(unsigned char *src, int pitch,
219 int rows, int cols, int flimit) {
220 int r, c, i;
221
222 unsigned char *s = src;
223 unsigned char d[16];
224
225
226 for (r = 0; r < rows; r++) {
227 int sumsq = 0;
228 int sum = 0;
229
230 for (i = -8; i <= 6; i++) {
231 sumsq += s[i] * s[i];
232 sum += s[i];
233 d[i + 8] = 0;
234 }
235
236 for (c = 0; c < cols + 8; c++) {
237 int x = s[c + 7] - s[c - 8];
238 int y = s[c + 7] + s[c - 8];
239
240 sum += x;
241 sumsq += x * y;
242
243 d[c & 15] = s[c];
244
245 if (sumsq * 15 - sum * sum < flimit) {
246 d[c & 15] = (8 + sum + s[c]) >> 4;
247 }
248
249 s[c - 8] = d[(c - 8) & 15];
250 }
251
252 s += pitch;
253 }
254 }
255
256 void vp9_mbpost_proc_down_c(unsigned char *dst, int pitch,
257 int rows, int cols, int flimit) {
258 int r, c, i;
259 const short *rv3 = &vp9_rv[63 & rand()];
260
261 for (c = 0; c < cols; c++) {
262 unsigned char *s = &dst[c];
263 int sumsq = 0;
264 int sum = 0;
265 unsigned char d[16];
266 const short *rv2 = rv3 + ((c * 17) & 127);
267
268 for (i = -8; i <= 6; i++) {
269 sumsq += s[i * pitch] * s[i * pitch];
270 sum += s[i * pitch];
271 }
272
273 for (r = 0; r < rows + 8; r++) {
274 sumsq += s[7 * pitch] * s[ 7 * pitch] - s[-8 * pitch] * s[-8 * pitch];
275 sum += s[7 * pitch] - s[-8 * pitch];
276 d[r & 15] = s[0];
277
278 if (sumsq * 15 - sum * sum < flimit) {
279 d[r & 15] = (rv2[r & 127] + sum + s[0]) >> 4;
280 }
281
282 s[-8 * pitch] = d[(r - 8) & 15];
283 s += pitch;
284 }
285 }
286 }
287
288 static void deblock_and_de_macro_block(YV12_BUFFER_CONFIG *source,
289 YV12_BUFFER_CONFIG *post,
290 int q,
291 int low_var_thresh,
292 int flag) {
293 double level = 6.0e-05 * q * q * q - .0067 * q * q + .306 * q + .0065;
294 int ppl = (int)(level + .5);
295 (void) low_var_thresh;
296 (void) flag;
297
298 vp9_post_proc_down_and_across(source->y_buffer, post->y_buffer,
299 source->y_stride, post->y_stride,
300 source->y_height, source->y_width, ppl);
301
302 vp9_mbpost_proc_across_ip(post->y_buffer, post->y_stride, post->y_height,
303 post->y_width, q2mbl(q));
304
305 vp9_mbpost_proc_down(post->y_buffer, post->y_stride, post->y_height,
306 post->y_width, q2mbl(q));
307
308 vp9_post_proc_down_and_across(source->u_buffer, post->u_buffer,
309 source->uv_stride, post->uv_stride,
310 source->uv_height, source->uv_width, ppl);
311 vp9_post_proc_down_and_across(source->v_buffer, post->v_buffer,
312 source->uv_stride, post->uv_stride,
313 source->uv_height, source->uv_width, ppl);
314 }
315
316 void vp9_deblock(YV12_BUFFER_CONFIG *source,
317 YV12_BUFFER_CONFIG *post,
318 int q,
319 int low_var_thresh,
320 int flag) {
321 double level = 6.0e-05 * q * q * q - .0067 * q * q + .306 * q + .0065;
322 int ppl = (int)(level + .5);
323 (void) low_var_thresh;
324 (void) flag;
325
326 vp9_post_proc_down_and_across(source->y_buffer, post->y_buffer,
327 source->y_stride, post->y_stride,
328 source->y_height, source->y_width, ppl);
329
330 vp9_post_proc_down_and_across(source->u_buffer, post->u_buffer,
331 source->uv_stride, post->uv_stride,
332 source->uv_height, source->uv_width, ppl);
333
334 vp9_post_proc_down_and_across(source->v_buffer, post->v_buffer,
335 source->uv_stride, post->uv_stride,
336 source->uv_height, source->uv_width, ppl);
337 }
338
339 void vp9_de_noise(YV12_BUFFER_CONFIG *src,
340 YV12_BUFFER_CONFIG *post,
341 int q,
342 int low_var_thresh,
343 int flag) {
344 double level = 6.0e-05 * q * q * q - .0067 * q * q + .306 * q + .0065;
345 int ppl = (int)(level + .5);
346 (void) post;
347 (void) low_var_thresh;
348 (void) flag;
349
350 vp9_post_proc_down_and_across(src->y_buffer + 2 * src->y_stride + 2,
351 src->y_buffer + 2 * src->y_stride + 2,
352 src->y_stride, src->y_stride, src->y_height - 4,
353 src->y_width - 4, ppl);
354
355 vp9_post_proc_down_and_across(src->u_buffer + 2 * src->uv_stride + 2,
356 src->u_buffer + 2 * src->uv_stride + 2,
357 src->uv_stride, src->uv_stride,
358 src->uv_height - 4, src->uv_width - 4, ppl);
359
360 vp9_post_proc_down_and_across(src->v_buffer + 2 * src->uv_stride + 2,
361 src->v_buffer + 2 * src->uv_stride + 2,
362 src->uv_stride, src->uv_stride,
363 src->uv_height - 4, src->uv_width - 4, ppl);
364 }
365
366 double vp9_gaussian(double sigma, double mu, double x) {
367 return 1 / (sigma * sqrt(2.0 * 3.14159265)) *
368 (exp(-(x - mu) * (x - mu) / (2 * sigma * sigma)));
369 }
370
371 static void fillrd(struct postproc_state *state, int q, int a) {
372 char char_dist[300];
373
374 double sigma;
375 int ai = a, qi = q, i;
376
377 vp9_clear_system_state();
378
379 sigma = ai + .5 + .6 * (63 - qi) / 63.0;
380
381 /* set up a lookup table of 256 entries that matches
382 * a gaussian distribution with sigma determined by q.
383 */
384 {
385 double i;
386 int next, j;
387
388 next = 0;
389
390 for (i = -32; i < 32; i++) {
391 int a = (int)(.5 + 256 * vp9_gaussian(sigma, 0, i));
392
393 if (a) {
394 for (j = 0; j < a; j++) {
395 char_dist[next + j] = (char) i;
396 }
397
398 next = next + j;
399 }
400
401 }
402
403 for (next = next; next < 256; next++)
404 char_dist[next] = 0;
405 }
406
407 for (i = 0; i < 3072; i++) {
408 state->noise[i] = char_dist[rand() & 0xff];
409 }
410
411 for (i = 0; i < 16; i++) {
412 state->blackclamp[i] = -char_dist[0];
413 state->whiteclamp[i] = -char_dist[0];
414 state->bothclamp[i] = -2 * char_dist[0];
415 }
416
417 state->last_q = q;
418 state->last_noise = a;
419 }
420
421 /****************************************************************************
422 *
423 * ROUTINE : plane_add_noise_c
424 *
425 * INPUTS : unsigned char *Start starting address of buffer to
426 * add gaussian noise to
427 * unsigned int Width width of plane
428 * unsigned int Height height of plane
429 * int Pitch distance between subsequent lines of frame
430 * int q quantizer used to determine amount of noise
431 * to add
432 *
433 * OUTPUTS : None.
434 *
435 * RETURNS : void.
436 *
437 * FUNCTION : adds gaussian noise to a plane of pixels
438 *
439 * SPECIAL NOTES : None.
440 *
441 ****************************************************************************/
442 void vp9_plane_add_noise_c(unsigned char *Start, char *noise,
443 char blackclamp[16],
444 char whiteclamp[16],
445 char bothclamp[16],
446 unsigned int Width, unsigned int Height, int Pitch) {
447 unsigned int i, j;
448
449 for (i = 0; i < Height; i++) {
450 unsigned char *Pos = Start + i * Pitch;
451 char *Ref = (char *)(noise + (rand() & 0xff));
452
453 for (j = 0; j < Width; j++) {
454 if (Pos[j] < blackclamp[0])
455 Pos[j] = blackclamp[0];
456
457 if (Pos[j] > 255 + whiteclamp[0])
458 Pos[j] = 255 + whiteclamp[0];
459
460 Pos[j] += Ref[j];
461 }
462 }
463 }
464
465 /* Blend the macro block with a solid colored square. Leave the
466 * edges unblended to give distinction to macro blocks in areas
467 * filled with the same color block.
468 */
469 void vp9_blend_mb_inner_c(unsigned char *y, unsigned char *u, unsigned char *v,
470 int y1, int u1, int v1, int alpha, int stride) {
471 int i, j;
472 int y1_const = y1 * ((1 << 16) - alpha);
473 int u1_const = u1 * ((1 << 16) - alpha);
474 int v1_const = v1 * ((1 << 16) - alpha);
475
476 y += 2 * stride + 2;
477 for (i = 0; i < 12; i++) {
478 for (j = 0; j < 12; j++) {
479 y[j] = (y[j] * alpha + y1_const) >> 16;
480 }
481 y += stride;
482 }
483
484 stride >>= 1;
485
486 u += stride + 1;
487 v += stride + 1;
488
489 for (i = 0; i < 6; i++) {
490 for (j = 0; j < 6; j++) {
491 u[j] = (u[j] * alpha + u1_const) >> 16;
492 v[j] = (v[j] * alpha + v1_const) >> 16;
493 }
494 u += stride;
495 v += stride;
496 }
497 }
498
499 /* Blend only the edge of the macro block. Leave center
500 * unblended to allow for other visualizations to be layered.
501 */
502 void vp9_blend_mb_outer_c(unsigned char *y, unsigned char *u, unsigned char *v,
503 int y1, int u1, int v1, int alpha, int stride) {
504 int i, j;
505 int y1_const = y1 * ((1 << 16) - alpha);
506 int u1_const = u1 * ((1 << 16) - alpha);
507 int v1_const = v1 * ((1 << 16) - alpha);
508
509 for (i = 0; i < 2; i++) {
510 for (j = 0; j < 16; j++) {
511 y[j] = (y[j] * alpha + y1_const) >> 16;
512 }
513 y += stride;
514 }
515
516 for (i = 0; i < 12; i++) {
517 y[0] = (y[0] * alpha + y1_const) >> 16;
518 y[1] = (y[1] * alpha + y1_const) >> 16;
519 y[14] = (y[14] * alpha + y1_const) >> 16;
520 y[15] = (y[15] * alpha + y1_const) >> 16;
521 y += stride;
522 }
523
524 for (i = 0; i < 2; i++) {
525 for (j = 0; j < 16; j++) {
526 y[j] = (y[j] * alpha + y1_const) >> 16;
527 }
528 y += stride;
529 }
530
531 stride >>= 1;
532
533 for (j = 0; j < 8; j++) {
534 u[j] = (u[j] * alpha + u1_const) >> 16;
535 v[j] = (v[j] * alpha + v1_const) >> 16;
536 }
537 u += stride;
538 v += stride;
539
540 for (i = 0; i < 6; i++) {
541 u[0] = (u[0] * alpha + u1_const) >> 16;
542 v[0] = (v[0] * alpha + v1_const) >> 16;
543
544 u[7] = (u[7] * alpha + u1_const) >> 16;
545 v[7] = (v[7] * alpha + v1_const) >> 16;
546
547 u += stride;
548 v += stride;
549 }
550
551 for (j = 0; j < 8; j++) {
552 u[j] = (u[j] * alpha + u1_const) >> 16;
553 v[j] = (v[j] * alpha + v1_const) >> 16;
554 }
555 }
556
557 void vp9_blend_b_c(unsigned char *y, unsigned char *u, unsigned char *v,
558 int y1, int u1, int v1, int alpha, int stride) {
559 int i, j;
560 int y1_const = y1 * ((1 << 16) - alpha);
561 int u1_const = u1 * ((1 << 16) - alpha);
562 int v1_const = v1 * ((1 << 16) - alpha);
563
564 for (i = 0; i < 4; i++) {
565 for (j = 0; j < 4; j++) {
566 y[j] = (y[j] * alpha + y1_const) >> 16;
567 }
568 y += stride;
569 }
570
571 stride >>= 1;
572
573 for (i = 0; i < 2; i++) {
574 for (j = 0; j < 2; j++) {
575 u[j] = (u[j] * alpha + u1_const) >> 16;
576 v[j] = (v[j] * alpha + v1_const) >> 16;
577 }
578 u += stride;
579 v += stride;
580 }
581 }
582
583 static void constrain_line(int x0, int *x1, int y0, int *y1,
584 int width, int height) {
585 int dx;
586 int dy;
587
588 if (*x1 > width) {
589 dx = *x1 - x0;
590 dy = *y1 - y0;
591
592 *x1 = width;
593 if (dx)
594 *y1 = ((width - x0) * dy) / dx + y0;
595 }
596 if (*x1 < 0) {
597 dx = *x1 - x0;
598 dy = *y1 - y0;
599
600 *x1 = 0;
601 if (dx)
602 *y1 = ((0 - x0) * dy) / dx + y0;
603 }
604 if (*y1 > height) {
605 dx = *x1 - x0;
606 dy = *y1 - y0;
607
608 *y1 = height;
609 if (dy)
610 *x1 = ((height - y0) * dx) / dy + x0;
611 }
612 if (*y1 < 0) {
613 dx = *x1 - x0;
614 dy = *y1 - y0;
615
616 *y1 = 0;
617 if (dy)
618 *x1 = ((0 - y0) * dx) / dy + x0;
619 }
620 }
621
622 int vp9_post_proc_frame(VP9_COMMON *oci, YV12_BUFFER_CONFIG *dest,
623 vp9_ppflags_t *ppflags) {
624 int q = oci->filter_level * 10 / 6;
625 int flags = ppflags->post_proc_flag;
626 int deblock_level = ppflags->deblocking_level;
627 int noise_level = ppflags->noise_level;
628
629 if (!oci->frame_to_show)
630 return -1;
631
632 if (q > 63)
633 q = 63;
634
635 if (!flags) {
636 *dest = *oci->frame_to_show;
637
638 /* handle problem with extending borders */
639 dest->y_width = oci->Width;
640 dest->y_height = oci->Height;
641 dest->uv_height = dest->y_height / 2;
642 return 0;
643
644 }
645
646 #if ARCH_X86||ARCH_X86_64
647 vpx_reset_mmx_state();
648 #endif
649
650 if (flags & VP9D_DEMACROBLOCK) {
651 deblock_and_de_macro_block(oci->frame_to_show, &oci->post_proc_buffer,
652 q + (deblock_level - 5) * 10, 1, 0);
653 } else if (flags & VP9D_DEBLOCK) {
654 vp9_deblock(oci->frame_to_show, &oci->post_proc_buffer, q, 1, 0);
655 } else {
656 vp8_yv12_copy_frame(oci->frame_to_show, &oci->post_proc_buffer);
657 }
658
659 if (flags & VP9D_ADDNOISE) {
660 if (oci->postproc_state.last_q != q
661 || oci->postproc_state.last_noise != noise_level) {
662 fillrd(&oci->postproc_state, 63 - q, noise_level);
663 }
664
665 vp9_plane_add_noise(oci->post_proc_buffer.y_buffer,
666 oci->postproc_state.noise,
667 oci->postproc_state.blackclamp,
668 oci->postproc_state.whiteclamp,
669 oci->postproc_state.bothclamp,
670 oci->post_proc_buffer.y_width,
671 oci->post_proc_buffer.y_height,
672 oci->post_proc_buffer.y_stride);
673 }
674
675 #if CONFIG_POSTPROC_VISUALIZER
676 if (flags & VP9D_DEBUG_TXT_FRAME_INFO) {
677 char message[512];
678 sprintf(message, "F%1dG%1dQ%3dF%3dP%d_s%dx%d",
679 (oci->frame_type == KEY_FRAME),
680 oci->refresh_golden_frame,
681 oci->base_qindex,
682 oci->filter_level,
683 flags,
684 oci->mb_cols, oci->mb_rows);
685 vp9_blit_text(message, oci->post_proc_buffer.y_buffer,
686 oci->post_proc_buffer.y_stride);
687 }
688
689 if (flags & VP9D_DEBUG_TXT_MBLK_MODES) {
690 int i, j;
691 unsigned char *y_ptr;
692 YV12_BUFFER_CONFIG *post = &oci->post_proc_buffer;
693 int mb_rows = post->y_height >> 4;
694 int mb_cols = post->y_width >> 4;
695 int mb_index = 0;
696 MODE_INFO *mi = oci->mi;
697
698 y_ptr = post->y_buffer + 4 * post->y_stride + 4;
699
700 /* vp9_filter each macro block */
701 for (i = 0; i < mb_rows; i++) {
702 for (j = 0; j < mb_cols; j++) {
703 char zz[4];
704
705 sprintf(zz, "%c", mi[mb_index].mbmi.mode + 'a');
706
707 vp9_blit_text(zz, y_ptr, post->y_stride);
708 mb_index++;
709 y_ptr += 16;
710 }
711
712 mb_index++; /* border */
713 y_ptr += post->y_stride * 16 - post->y_width;
714
715 }
716 }
717
718 if (flags & VP9D_DEBUG_TXT_DC_DIFF) {
719 int i, j;
720 unsigned char *y_ptr;
721 YV12_BUFFER_CONFIG *post = &oci->post_proc_buffer;
722 int mb_rows = post->y_height >> 4;
723 int mb_cols = post->y_width >> 4;
724 int mb_index = 0;
725 MODE_INFO *mi = oci->mi;
726
727 y_ptr = post->y_buffer + 4 * post->y_stride + 4;
728
729 /* vp9_filter each macro block */
730 for (i = 0; i < mb_rows; i++) {
731 for (j = 0; j < mb_cols; j++) {
732 char zz[4];
733 int dc_diff = !(mi[mb_index].mbmi.mode != B_PRED &&
734 mi[mb_index].mbmi.mode != SPLITMV &&
735 mi[mb_index].mbmi.mb_skip_coeff);
736
737 if (oci->frame_type == KEY_FRAME)
738 sprintf(zz, "a");
739 else
740 sprintf(zz, "%c", dc_diff + '0');
741
742 vp9_blit_text(zz, y_ptr, post->y_stride);
743 mb_index++;
744 y_ptr += 16;
745 }
746
747 mb_index++; /* border */
748 y_ptr += post->y_stride * 16 - post->y_width;
749
750 }
751 }
752
753 if (flags & VP9D_DEBUG_TXT_RATE_INFO) {
754 char message[512];
755 snprintf(message, sizeof(message),
756 "Bitrate: %10.2f frame_rate: %10.2f ",
757 oci->bitrate, oci->framerate);
758 vp9_blit_text(message, oci->post_proc_buffer.y_buffer,
759 oci->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 = &oci->post_proc_buffer;
765 int width = post->y_width;
766 int height = post->y_height;
767 unsigned char *y_buffer = oci->post_proc_buffer.y_buffer;
768 int y_stride = oci->post_proc_buffer.y_stride;
769 MODE_INFO *mi = oci->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 (mi->mbmi.mode >= NEARESTMV) {
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 mi++;
897 }
898 mi++;
899 }
900 }
901
902 /* Color in block modes */
903 if ((flags & VP9D_DEBUG_CLR_BLK_MODES)
904 && (ppflags->display_mb_modes_flag || ppflags->display_b_modes_flag)) {
905 int y, x;
906 YV12_BUFFER_CONFIG *post = &oci->post_proc_buffer;
907 int width = post->y_width;
908 int height = post->y_height;
909 unsigned char *y_ptr = oci->post_proc_buffer.y_buffer;
910 unsigned char *u_ptr = oci->post_proc_buffer.u_buffer;
911 unsigned char *v_ptr = oci->post_proc_buffer.v_buffer;
912 int y_stride = oci->post_proc_buffer.y_stride;
913 MODE_INFO *mi = oci->mi;
914
915 for (y = 0; y < height; y += 16) {
916 for (x = 0; x < width; x += 16) {
917 int Y = 0, U = 0, V = 0;
918
919 if (mi->mbmi.mode == B_PRED &&
920 ((ppflags->display_mb_modes_flag & B_PRED) ||
921 ppflags->display_b_modes_flag)) {
922 int by, bx;
923 unsigned char *yl, *ul, *vl;
924 union b_mode_info *bmi = mi->bmi;
925
926 yl = y_ptr + x;
927 ul = u_ptr + (x >> 1);
928 vl = v_ptr + (x >> 1);
929
930 for (by = 0; by < 16; by += 4) {
931 for (bx = 0; bx < 16; bx += 4) {
932 if ((ppflags->display_b_modes_flag & (1 << mi->mbmi.mode))
933 || (ppflags->display_mb_modes_flag & B_PRED)) {
934 Y = B_PREDICTION_MODE_colors[bmi->as_mode.first][0];
935 U = B_PREDICTION_MODE_colors[bmi->as_mode.first][1];
936 V = B_PREDICTION_MODE_colors[bmi->as_mode.first][2];
937
938 vp9_blend_b(yl + bx, ul + (bx >> 1), vl + (bx >> 1), Y, U, V,
939 0xc000, y_stride);
940 }
941 bmi++;
942 }
943
944 yl += y_stride * 4;
945 ul += y_stride * 1;
946 vl += y_stride * 1;
947 }
948 } else if (ppflags->display_mb_modes_flag & (1 << mi->mbmi.mode)) {
949 Y = MB_PREDICTION_MODE_colors[mi->mbmi.mode][0];
950 U = MB_PREDICTION_MODE_colors[mi->mbmi.mode][1];
951 V = MB_PREDICTION_MODE_colors[mi->mbmi.mode][2];
952
953 vp9_blend_mb_inner(y_ptr + x, u_ptr + (x >> 1), v_ptr + (x >> 1),
954 Y, U, V, 0xc000, y_stride);
955 }
956
957 mi++;
958 }
959 y_ptr += y_stride * 16;
960 u_ptr += y_stride * 4;
961 v_ptr += y_stride * 4;
962
963 mi++;
964 }
965 }
966
967 /* Color in frame reference blocks */
968 if ((flags & VP9D_DEBUG_CLR_FRM_REF_BLKS) &&
969 ppflags->display_ref_frame_flag) {
970 int y, x;
971 YV12_BUFFER_CONFIG *post = &oci->post_proc_buffer;
972 int width = post->y_width;
973 int height = post->y_height;
974 unsigned char *y_ptr = oci->post_proc_buffer.y_buffer;
975 unsigned char *u_ptr = oci->post_proc_buffer.u_buffer;
976 unsigned char *v_ptr = oci->post_proc_buffer.v_buffer;
977 int y_stride = oci->post_proc_buffer.y_stride;
978 MODE_INFO *mi = oci->mi;
979
980 for (y = 0; y < height; y += 16) {
981 for (x = 0; x < width; x += 16) {
982 int Y = 0, U = 0, V = 0;
983
984 if (ppflags->display_ref_frame_flag & (1 << mi->mbmi.ref_frame)) {
985 Y = MV_REFERENCE_FRAME_colors[mi->mbmi.ref_frame][0];
986 U = MV_REFERENCE_FRAME_colors[mi->mbmi.ref_frame][1];
987 V = MV_REFERENCE_FRAME_colors[mi->mbmi.ref_frame][2];
988
989 vp9_blend_mb_outer(y_ptr + x, u_ptr + (x >> 1), v_ptr + (x >> 1),
990 Y, U, V, 0xc000, y_stride);
991 }
992
993 mi++;
994 }
995 y_ptr += y_stride * 16;
996 u_ptr += y_stride * 4;
997 v_ptr += y_stride * 4;
998
999 mi++;
1000 }
1001 }
1002 #endif
1003
1004 *dest = oci->post_proc_buffer;
1005
1006 /* handle problem with extending borders */
1007 dest->y_width = oci->Width;
1008 dest->y_height = oci->Height;
1009 dest->uv_height = dest->y_height / 2;
1010
1011 return 0;
1012 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698