2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
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.
12 #include "vpx_config.h"
14 #include "vpx_scale_rtcd.h"
15 #include "vpx_scale/yv12config.h"
18 #include "vpx_scale/vpx_scale.h"
19 #include "systemdependent.h"
26 #define RGB_TO_YUV(t) \
27 ( (0.257*(float)(t>>16)) + (0.504*(float)(t>>8&0xff)) + (0.098*(float)(t&0xff)) + 16), \
28 (-(0.148*(float)(t>>16)) - (0.291*(float)(t>>8&0xff)) + (0.439*(float)(t&0xff)) + 128), \
29 ( (0.439*(float)(t>>16)) - (0.368*(float)(t>>8&0xff)) - (0.071*(float)(t&0xff)) + 128)
31 /* global constants */
32 #if CONFIG_POSTPROC_VISUALIZER
33 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(0x228B22) }, /* ForestGreen */
39 { RGB_TO_YUV(0x006400) }, /* DarkGreen */
40 { RGB_TO_YUV(0x98F5FF) }, /* Cadet Blue */
41 { RGB_TO_YUV(0x6CA6CD) }, /* Sky Blue */
42 { RGB_TO_YUV(0x00008B) }, /* Dark blue */
43 { RGB_TO_YUV(0x551A8B) }, /* Purple */
44 { RGB_TO_YUV(0xFF0000) } /* Red */
47 static const unsigned char B_PREDICTION_MODE_colors[B_MODE_COUNT][3] =
49 { RGB_TO_YUV(0x6633ff) }, /* Purple */
50 { RGB_TO_YUV(0xcc33ff) }, /* Magenta */
51 { RGB_TO_YUV(0xff33cc) }, /* Pink */
52 { RGB_TO_YUV(0xff3366) }, /* Coral */
53 { RGB_TO_YUV(0x3366ff) }, /* Blue */
54 { RGB_TO_YUV(0xed00f5) }, /* Dark Blue */
55 { RGB_TO_YUV(0x2e00b8) }, /* Dark Purple */
56 { RGB_TO_YUV(0xff6633) }, /* Orange */
57 { RGB_TO_YUV(0x33ccff) }, /* Light Blue */
58 { RGB_TO_YUV(0x8ab800) }, /* Green */
59 { RGB_TO_YUV(0xffcc33) }, /* Light Orange */
60 { RGB_TO_YUV(0x33ffcc) }, /* Aqua */
61 { RGB_TO_YUV(0x66ff33) }, /* Light Green */
62 { RGB_TO_YUV(0xccff33) }, /* Yellow */
65 static const unsigned char MV_REFERENCE_FRAME_colors[MAX_REF_FRAMES][3] =
67 { RGB_TO_YUV(0x00ff00) }, /* Blue */
68 { RGB_TO_YUV(0x0000ff) }, /* Green */
69 { RGB_TO_YUV(0xffff00) }, /* Yellow */
70 { RGB_TO_YUV(0xff0000) }, /* Red */
74 const short vp8_rv[] =
76 8, 5, 2, 2, 8, 12, 4, 9, 8, 3,
77 0, 3, 9, 0, 0, 0, 8, 3, 14, 4,
78 10, 1, 11, 14, 1, 14, 9, 6, 12, 11,
79 8, 6, 10, 0, 0, 8, 9, 0, 3, 14,
80 8, 11, 13, 4, 2, 9, 0, 3, 9, 6,
81 1, 2, 3, 14, 13, 1, 8, 2, 9, 7,
82 3, 3, 1, 13, 13, 6, 6, 5, 2, 7,
83 11, 9, 11, 8, 7, 3, 2, 0, 13, 13,
84 14, 4, 12, 5, 12, 10, 8, 10, 13, 10,
85 4, 14, 4, 10, 0, 8, 11, 1, 13, 7,
86 7, 14, 6, 14, 13, 2, 13, 5, 4, 4,
87 0, 10, 0, 5, 13, 2, 12, 7, 11, 13,
88 8, 0, 4, 10, 7, 2, 7, 2, 2, 5,
89 3, 4, 7, 3, 3, 14, 14, 5, 9, 13,
90 3, 14, 3, 6, 3, 0, 11, 8, 13, 1,
91 13, 1, 12, 0, 10, 9, 7, 6, 2, 8,
92 5, 2, 13, 7, 1, 13, 14, 7, 6, 7,
93 9, 6, 10, 11, 7, 8, 7, 5, 14, 8,
94 4, 4, 0, 8, 7, 10, 0, 8, 14, 11,
95 3, 12, 5, 7, 14, 3, 14, 5, 2, 6,
96 11, 12, 12, 8, 0, 11, 13, 1, 2, 0,
97 5, 10, 14, 7, 8, 0, 4, 11, 0, 8,
98 0, 3, 10, 5, 8, 0, 11, 6, 7, 8,
99 10, 7, 13, 9, 2, 5, 1, 5, 10, 2,
100 4, 3, 5, 6, 10, 8, 9, 4, 11, 14,
101 0, 10, 0, 5, 13, 2, 12, 7, 11, 13,
102 8, 0, 4, 10, 7, 2, 7, 2, 2, 5,
103 3, 4, 7, 3, 3, 14, 14, 5, 9, 13,
104 3, 14, 3, 6, 3, 0, 11, 8, 13, 1,
105 13, 1, 12, 0, 10, 9, 7, 6, 2, 8,
106 5, 2, 13, 7, 1, 13, 14, 7, 6, 7,
107 9, 6, 10, 11, 7, 8, 7, 5, 14, 8,
108 4, 4, 0, 8, 7, 10, 0, 8, 14, 11,
109 3, 12, 5, 7, 14, 3, 14, 5, 2, 6,
110 11, 12, 12, 8, 0, 11, 13, 1, 2, 0,
111 5, 10, 14, 7, 8, 0, 4, 11, 0, 8,
112 0, 3, 10, 5, 8, 0, 11, 6, 7, 8,
113 10, 7, 13, 9, 2, 5, 1, 5, 10, 2,
114 4, 3, 5, 6, 10, 8, 9, 4, 11, 14,
115 3, 8, 3, 7, 8, 5, 11, 4, 12, 3,
116 11, 9, 14, 8, 14, 13, 4, 3, 1, 2,
117 14, 6, 5, 4, 4, 11, 4, 6, 2, 1,
118 5, 8, 8, 12, 13, 5, 14, 10, 12, 13,
119 0, 9, 5, 5, 11, 10, 13, 9, 10, 13,
122 extern void vp8_blit_text(const char *msg, unsigned char *address, const int pitch);
123 extern void vp8_blit_line(int x0, int x1, int y0, int y1, unsigned char *image, const int pitch);
124 /***********************************************************************************************************
126 void vp8_post_proc_down_and_across_mb_row_c
128 unsigned char *src_ptr,
129 unsigned char *dst_ptr,
130 int src_pixels_per_line,
131 int dst_pixels_per_line,
137 unsigned char *p_src, *p_dst;
143 for (row = 0; row < size; row++)
145 /* post_proc_down for one row */
149 for (col = 0; col < cols; col++)
151 unsigned char p_above2 = p_src[col - 2 * src_pixels_per_line];
152 unsigned char p_above1 = p_src[col - src_pixels_per_line];
153 unsigned char p_below1 = p_src[col + src_pixels_per_line];
154 unsigned char p_below2 = p_src[col + 2 * src_pixels_per_line];
158 if ((abs(v - p_above2) < f[col]) && (abs(v - p_above1) < f[col])
159 && (abs(v - p_below1) < f[col]) && (abs(v - p_below2) < f[col]))
161 unsigned char k1, k2, k3;
162 k1 = (p_above2 + p_above1 + 1) >> 1;
163 k2 = (p_below2 + p_below1 + 1) >> 1;
164 k3 = (k1 + k2 + 1) >> 1;
165 v = (k3 + v + 1) >> 1;
171 /* now post_proc_across */
175 p_src[-2] = p_src[-1] = p_src[0];
176 p_src[cols] = p_src[cols + 1] = p_src[cols - 1];
178 for (col = 0; col < cols; col++)
182 if ((abs(v - p_src[col - 2]) < f[col])
183 && (abs(v - p_src[col - 1]) < f[col])
184 && (abs(v - p_src[col + 1]) < f[col])
185 && (abs(v - p_src[col + 2]) < f[col]))
187 unsigned char k1, k2, k3;
188 k1 = (p_src[col - 2] + p_src[col - 1] + 1) >> 1;
189 k2 = (p_src[col + 2] + p_src[col + 1] + 1) >> 1;
190 k3 = (k1 + k2 + 1) >> 1;
191 v = (k3 + v + 1) >> 1;
197 p_dst[col - 2] = d[(col - 2) & 3];
200 /* handle the last two pixels */
201 p_dst[col - 2] = d[(col - 2) & 3];
202 p_dst[col - 1] = d[(col - 1) & 3];
205 src_ptr += src_pixels_per_line;
206 dst_ptr += dst_pixels_per_line;
210 static int q2mbl(int x)
214 x = 50 + (x - 50) * 10 / 8;
218 void vp8_mbpost_proc_across_ip_c(unsigned char *src, int pitch, int rows, int cols, int flimit)
222 unsigned char *s = src;
225 for (r = 0; r < rows; r++)
230 for (i = -8; i < 0; i++)
233 /* 17 avoids valgrind warning - we buffer values in c in d
234 * and only write them when we've read 8 ahead...
236 for (i = 0; i < 17; i++)
239 for (i = -8; i <= 6; i++)
241 sumsq += s[i] * s[i];
246 for (c = 0; c < cols + 8; c++)
248 int x = s[c+7] - s[c-8];
249 int y = s[c+7] + s[c-8];
256 if (sumsq * 15 - sum * sum < flimit)
258 d[c&15] = (8 + sum + s[c]) >> 4;
261 s[c-8] = d[(c-8)&15];
268 void vp8_mbpost_proc_down_c(unsigned char *dst, int pitch, int rows, int cols, int flimit)
271 const short *rv3 = &vp8_rv[63&rand()];
273 for (c = 0; c < cols; c++ )
275 unsigned char *s = &dst[c];
279 const short *rv2 = rv3 + ((c * 17) & 127);
281 for (i = -8; i < 0; i++)
284 /* 17 avoids valgrind warning - we buffer values in c in d
285 * and only write them when we've read 8 ahead...
287 for (i = 0; i < 17; i++)
288 s[(i+rows)*pitch]=s[(rows-1)*pitch];
290 for (i = -8; i <= 6; i++)
292 sumsq += s[i*pitch] * s[i*pitch];
296 for (r = 0; r < rows + 8; r++)
298 sumsq += s[7*pitch] * s[ 7*pitch] - s[-8*pitch] * s[-8*pitch];
299 sum += s[7*pitch] - s[-8*pitch];
302 if (sumsq * 15 - sum * sum < flimit)
304 d[r&15] = (rv2[r&127] + sum + s[0]) >> 4;
307 s[-8*pitch] = d[(r-8)&15];
314 static void vp8_de_mblock(YV12_BUFFER_CONFIG *post,
317 vp8_mbpost_proc_across_ip(post->y_buffer, post->y_stride, post->y_height,
318 post->y_width, q2mbl(q));
319 vp8_mbpost_proc_down(post->y_buffer, post->y_stride, post->y_height,
320 post->y_width, q2mbl(q));
323 void vp8_deblock(VP8_COMMON *cm,
324 YV12_BUFFER_CONFIG *source,
325 YV12_BUFFER_CONFIG *post,
330 double level = 6.0e-05 * q * q * q - .0067 * q * q + .306 * q + .0065;
331 int ppl = (int)(level + .5);
333 const MODE_INFO *mode_info_context = cm->show_frame_mi;
336 /* The pixel thresholds are adjusted according to if or not the macroblock
337 * is a skipped block. */
338 unsigned char *ylimits = cm->pp_limits_buffer;
339 unsigned char *uvlimits = cm->pp_limits_buffer + 16 * cm->mb_cols;
340 (void) low_var_thresh;
345 for (mbr = 0; mbr < cm->mb_rows; mbr++)
347 unsigned char *ylptr = ylimits;
348 unsigned char *uvlptr = uvlimits;
349 for (mbc = 0; mbc < cm->mb_cols; mbc++)
351 unsigned char mb_ppl;
353 if (mode_info_context->mbmi.mb_skip_coeff)
354 mb_ppl = (unsigned char)ppl >> 1;
356 mb_ppl = (unsigned char)ppl;
358 vpx_memset(ylptr, mb_ppl, 16);
359 vpx_memset(uvlptr, mb_ppl, 8);
367 vp8_post_proc_down_and_across_mb_row(
368 source->y_buffer + 16 * mbr * source->y_stride,
369 post->y_buffer + 16 * mbr * post->y_stride, source->y_stride,
370 post->y_stride, source->y_width, ylimits, 16);
372 vp8_post_proc_down_and_across_mb_row(
373 source->u_buffer + 8 * mbr * source->uv_stride,
374 post->u_buffer + 8 * mbr * post->uv_stride, source->uv_stride,
375 post->uv_stride, source->uv_width, uvlimits, 8);
376 vp8_post_proc_down_and_across_mb_row(
377 source->v_buffer + 8 * mbr * source->uv_stride,
378 post->v_buffer + 8 * mbr * post->uv_stride, source->uv_stride,
379 post->uv_stride, source->uv_width, uvlimits, 8);
383 vp8_yv12_copy_frame(source, post);
388 void vp8_de_noise(VP8_COMMON *cm,
389 YV12_BUFFER_CONFIG *source,
390 YV12_BUFFER_CONFIG *post,
397 double level = 6.0e-05 * q * q * q - .0067 * q * q + .306 * q + .0065;
398 int ppl = (int)(level + .5);
399 int mb_rows = cm->mb_rows;
400 int mb_cols = cm->mb_cols;
401 unsigned char *limits = cm->pp_limits_buffer;;
403 (void) low_var_thresh;
406 vpx_memset(limits, (unsigned char)ppl, 16 * mb_cols);
408 /* TODO: The original code don't filter the 2 outer rows and columns. */
409 for (mbr = 0; mbr < mb_rows; mbr++)
411 vp8_post_proc_down_and_across_mb_row(
412 source->y_buffer + 16 * mbr * source->y_stride,
413 source->y_buffer + 16 * mbr * source->y_stride,
414 source->y_stride, source->y_stride, source->y_width, limits, 16);
416 vp8_post_proc_down_and_across_mb_row(
417 source->u_buffer + 8 * mbr * source->uv_stride,
418 source->u_buffer + 8 * mbr * source->uv_stride,
419 source->uv_stride, source->uv_stride, source->uv_width, limits,
421 vp8_post_proc_down_and_across_mb_row(
422 source->v_buffer + 8 * mbr * source->uv_stride,
423 source->v_buffer + 8 * mbr * source->uv_stride,
424 source->uv_stride, source->uv_stride, source->uv_width, limits,
430 double vp8_gaussian(double sigma, double mu, double x)
432 return 1 / (sigma * sqrt(2.0 * 3.14159265)) *
433 (exp(-(x - mu) * (x - mu) / (2 * sigma * sigma)));
436 static void fillrd(struct postproc_state *state, int q, int a)
443 vp8_clear_system_state();
446 sigma = a + .5 + .6 * (63 - q) / 63.0;
448 /* set up a lookup table of 256 entries that matches
449 * a gaussian distribution with sigma determined by q.
456 for (i = -32; i < 32; i++)
458 const int v = (int)(.5 + 256 * vp8_gaussian(sigma, 0, i));
462 for (j = 0; j < v; j++)
464 char_dist[next+j] = (char) i;
472 for (; next < 256; next++)
477 for (i = 0; i < 3072; i++)
479 state->noise[i] = char_dist[rand() & 0xff];
482 for (i = 0; i < 16; i++)
484 state->blackclamp[i] = -char_dist[0];
485 state->whiteclamp[i] = -char_dist[0];
486 state->bothclamp[i] = -2 * char_dist[0];
490 state->last_noise = a;
493 /****************************************************************************
495 * ROUTINE : plane_add_noise_c
497 * INPUTS : unsigned char *Start starting address of buffer to add gaussian
499 * unsigned int Width width of plane
500 * unsigned int Height height of plane
501 * int Pitch distance between subsequent lines of frame
502 * int q quantizer used to determine amount of noise
509 * FUNCTION : adds gaussian noise to a plane of pixels
511 * SPECIAL NOTES : None.
513 ****************************************************************************/
514 void vp8_plane_add_noise_c(unsigned char *Start, char *noise,
518 unsigned int Width, unsigned int Height, int Pitch)
522 for (i = 0; i < Height; i++)
524 unsigned char *Pos = Start + i * Pitch;
525 char *Ref = (char *)(noise + (rand() & 0xff));
527 for (j = 0; j < Width; j++)
529 if (Pos[j] < blackclamp[0])
530 Pos[j] = blackclamp[0];
532 if (Pos[j] > 255 + whiteclamp[0])
533 Pos[j] = 255 + whiteclamp[0];
540 /* Blend the macro block with a solid colored square. Leave the
541 * edges unblended to give distinction to macro blocks in areas
542 * filled with the same color block.
544 void vp8_blend_mb_inner_c (unsigned char *y, unsigned char *u, unsigned char *v,
545 int y_1, int u_1, int v_1, int alpha, int stride)
548 int y1_const = y_1*((1<<16)-alpha);
549 int u1_const = u_1*((1<<16)-alpha);
550 int v1_const = v_1*((1<<16)-alpha);
553 for (i = 0; i < 12; i++)
555 for (j = 0; j < 12; j++)
557 y[j] = (y[j]*alpha + y1_const)>>16;
567 for (i = 0; i < 6; i++)
569 for (j = 0; j < 6; j++)
571 u[j] = (u[j]*alpha + u1_const)>>16;
572 v[j] = (v[j]*alpha + v1_const)>>16;
579 /* Blend only the edge of the macro block. Leave center
580 * unblended to allow for other visualizations to be layered.
582 void vp8_blend_mb_outer_c (unsigned char *y, unsigned char *u, unsigned char *v,
583 int y_1, int u_1, int v_1, int alpha, int stride)
586 int y1_const = y_1*((1<<16)-alpha);
587 int u1_const = u_1*((1<<16)-alpha);
588 int v1_const = v_1*((1<<16)-alpha);
590 for (i = 0; i < 2; i++)
592 for (j = 0; j < 16; j++)
594 y[j] = (y[j]*alpha + y1_const)>>16;
599 for (i = 0; i < 12; i++)
601 y[0] = (y[0]*alpha + y1_const)>>16;
602 y[1] = (y[1]*alpha + y1_const)>>16;
603 y[14] = (y[14]*alpha + y1_const)>>16;
604 y[15] = (y[15]*alpha + y1_const)>>16;
608 for (i = 0; i < 2; i++)
610 for (j = 0; j < 16; j++)
612 y[j] = (y[j]*alpha + y1_const)>>16;
619 for (j = 0; j < 8; j++)
621 u[j] = (u[j]*alpha + u1_const)>>16;
622 v[j] = (v[j]*alpha + v1_const)>>16;
627 for (i = 0; i < 6; i++)
629 u[0] = (u[0]*alpha + u1_const)>>16;
630 v[0] = (v[0]*alpha + v1_const)>>16;
632 u[7] = (u[7]*alpha + u1_const)>>16;
633 v[7] = (v[7]*alpha + v1_const)>>16;
639 for (j = 0; j < 8; j++)
641 u[j] = (u[j]*alpha + u1_const)>>16;
642 v[j] = (v[j]*alpha + v1_const)>>16;
646 void vp8_blend_b_c (unsigned char *y, unsigned char *u, unsigned char *v,
647 int y_1, int u_1, int v_1, int alpha, int stride)
650 int y1_const = y_1*((1<<16)-alpha);
651 int u1_const = u_1*((1<<16)-alpha);
652 int v1_const = v_1*((1<<16)-alpha);
654 for (i = 0; i < 4; i++)
656 for (j = 0; j < 4; j++)
658 y[j] = (y[j]*alpha + y1_const)>>16;
665 for (i = 0; i < 2; i++)
667 for (j = 0; j < 2; j++)
669 u[j] = (u[j]*alpha + u1_const)>>16;
670 v[j] = (v[j]*alpha + v1_const)>>16;
677 static void constrain_line (int x_0, int *x_1, int y_0, int *y_1, int width, int height)
689 *y_1 = ((width-x_0)*dy)/dx + y_0;
698 *y_1 = ((0-x_0)*dy)/dx + y_0;
707 *x_1 = ((height-y_0)*dx)/dy + x_0;
716 *x_1 = ((0-y_0)*dx)/dy + x_0;
721 int vp8_post_proc_frame(VP8_COMMON *oci, YV12_BUFFER_CONFIG *dest, vp8_ppflags_t *ppflags)
723 int q = oci->filter_level * 10 / 6;
724 int flags = ppflags->post_proc_flag;
725 int deblock_level = ppflags->deblocking_level;
726 int noise_level = ppflags->noise_level;
728 if (!oci->frame_to_show)
736 *dest = *oci->frame_to_show;
738 /* handle problem with extending borders */
739 dest->y_width = oci->Width;
740 dest->y_height = oci->Height;
741 dest->uv_height = dest->y_height / 2;
742 oci->postproc_state.last_base_qindex = oci->base_qindex;
743 oci->postproc_state.last_frame_valid = 1;
747 /* Allocate post_proc_buffer_int if needed */
748 if ((flags & VP8D_MFQE) && !oci->post_proc_buffer_int_used)
750 if ((flags & VP8D_DEBLOCK) || (flags & VP8D_DEMACROBLOCK))
752 int width = (oci->Width + 15) & ~15;
753 int height = (oci->Height + 15) & ~15;
755 if (vp8_yv12_alloc_frame_buffer(&oci->post_proc_buffer_int,
756 width, height, VP8BORDERINPIXELS))
757 vpx_internal_error(&oci->error, VPX_CODEC_MEM_ERROR,
758 "Failed to allocate MFQE framebuffer");
760 oci->post_proc_buffer_int_used = 1;
762 /* insure that postproc is set to all 0's so that post proc
763 * doesn't pull random data in from edge
765 vpx_memset((&oci->post_proc_buffer_int)->buffer_alloc,128,(&oci->post_proc_buffer)->frame_size);
770 vp8_clear_system_state();
772 if ((flags & VP8D_MFQE) &&
773 oci->postproc_state.last_frame_valid &&
774 oci->current_video_frame >= 2 &&
775 oci->postproc_state.last_base_qindex < 60 &&
776 oci->base_qindex - oci->postproc_state.last_base_qindex >= 20)
778 vp8_multiframe_quality_enhance(oci);
779 if (((flags & VP8D_DEBLOCK) || (flags & VP8D_DEMACROBLOCK)) &&
780 oci->post_proc_buffer_int_used)
782 vp8_yv12_copy_frame(&oci->post_proc_buffer, &oci->post_proc_buffer_int);
783 if (flags & VP8D_DEMACROBLOCK)
785 vp8_deblock(oci, &oci->post_proc_buffer_int, &oci->post_proc_buffer,
786 q + (deblock_level - 5) * 10, 1, 0);
787 vp8_de_mblock(&oci->post_proc_buffer,
788 q + (deblock_level - 5) * 10);
790 else if (flags & VP8D_DEBLOCK)
792 vp8_deblock(oci, &oci->post_proc_buffer_int, &oci->post_proc_buffer,
796 /* Move partially towards the base q of the previous frame */
797 oci->postproc_state.last_base_qindex = (3*oci->postproc_state.last_base_qindex + oci->base_qindex)>>2;
799 else if (flags & VP8D_DEMACROBLOCK)
801 vp8_deblock(oci, oci->frame_to_show, &oci->post_proc_buffer,
802 q + (deblock_level - 5) * 10, 1, 0);
803 vp8_de_mblock(&oci->post_proc_buffer, q + (deblock_level - 5) * 10);
805 oci->postproc_state.last_base_qindex = oci->base_qindex;
807 else if (flags & VP8D_DEBLOCK)
809 vp8_deblock(oci, oci->frame_to_show, &oci->post_proc_buffer,
811 oci->postproc_state.last_base_qindex = oci->base_qindex;
815 vp8_yv12_copy_frame(oci->frame_to_show, &oci->post_proc_buffer);
816 oci->postproc_state.last_base_qindex = oci->base_qindex;
818 oci->postproc_state.last_frame_valid = 1;
820 if (flags & VP8D_ADDNOISE)
822 if (oci->postproc_state.last_q != q
823 || oci->postproc_state.last_noise != noise_level)
825 fillrd(&oci->postproc_state, 63 - q, noise_level);
829 (oci->post_proc_buffer.y_buffer,
830 oci->postproc_state.noise,
831 oci->postproc_state.blackclamp,
832 oci->postproc_state.whiteclamp,
833 oci->postproc_state.bothclamp,
834 oci->post_proc_buffer.y_width, oci->post_proc_buffer.y_height,
835 oci->post_proc_buffer.y_stride);
838 #if CONFIG_POSTPROC_VISUALIZER
839 if (flags & VP8D_DEBUG_TXT_FRAME_INFO)
842 sprintf(message, "F%1dG%1dQ%3dF%3dP%d_s%dx%d",
843 (oci->frame_type == KEY_FRAME),
844 oci->refresh_golden_frame,
848 oci->mb_cols, oci->mb_rows);
849 vp8_blit_text(message, oci->post_proc_buffer.y_buffer, oci->post_proc_buffer.y_stride);
852 if (flags & VP8D_DEBUG_TXT_MBLK_MODES)
855 unsigned char *y_ptr;
856 YV12_BUFFER_CONFIG *post = &oci->post_proc_buffer;
857 int mb_rows = post->y_height >> 4;
858 int mb_cols = post->y_width >> 4;
860 MODE_INFO *mi = oci->mi;
862 y_ptr = post->y_buffer + 4 * post->y_stride + 4;
864 /* vp8_filter each macro block */
865 for (i = 0; i < mb_rows; i++)
867 for (j = 0; j < mb_cols; j++)
871 sprintf(zz, "%c", mi[mb_index].mbmi.mode + 'a');
873 vp8_blit_text(zz, y_ptr, post->y_stride);
878 mb_index ++; /* border */
879 y_ptr += post->y_stride * 16 - post->y_width;
884 if (flags & VP8D_DEBUG_TXT_DC_DIFF)
887 unsigned char *y_ptr;
888 YV12_BUFFER_CONFIG *post = &oci->post_proc_buffer;
889 int mb_rows = post->y_height >> 4;
890 int mb_cols = post->y_width >> 4;
892 MODE_INFO *mi = oci->mi;
894 y_ptr = post->y_buffer + 4 * post->y_stride + 4;
896 /* vp8_filter each macro block */
897 for (i = 0; i < mb_rows; i++)
899 for (j = 0; j < mb_cols; j++)
902 int dc_diff = !(mi[mb_index].mbmi.mode != B_PRED &&
903 mi[mb_index].mbmi.mode != SPLITMV &&
904 mi[mb_index].mbmi.mb_skip_coeff);
906 if (oci->frame_type == KEY_FRAME)
909 sprintf(zz, "%c", dc_diff + '0');
911 vp8_blit_text(zz, y_ptr, post->y_stride);
916 mb_index ++; /* border */
917 y_ptr += post->y_stride * 16 - post->y_width;
922 if (flags & VP8D_DEBUG_TXT_RATE_INFO)
925 sprintf(message, "Bitrate: %10.2f framerate: %10.2f ", oci->bitrate, oci->framerate);
926 vp8_blit_text(message, oci->post_proc_buffer.y_buffer, oci->post_proc_buffer.y_stride);
929 /* Draw motion vectors */
930 if ((flags & VP8D_DEBUG_DRAW_MV) && ppflags->display_mv_flag)
932 YV12_BUFFER_CONFIG *post = &oci->post_proc_buffer;
933 int width = post->y_width;
934 int height = post->y_height;
935 unsigned char *y_buffer = oci->post_proc_buffer.y_buffer;
936 int y_stride = oci->post_proc_buffer.y_stride;
937 MODE_INFO *mi = oci->mi;
940 for (y0 = 0; y0 < height; y0 += 16)
942 for (x0 = 0; x0 < width; x0 += 16)
946 if (!(ppflags->display_mv_flag & (1<<mi->mbmi.mode)))
952 if (mi->mbmi.mode == SPLITMV)
954 switch (mi->mbmi.partitioning)
956 case 0 : /* mv_top_bottom */
958 union b_mode_info *bmi = &mi->bmi[0];
959 MV *mv = &bmi->mv.as_mv;
961 x1 = x0 + 8 + (mv->col >> 3);
962 y1 = y0 + 4 + (mv->row >> 3);
964 constrain_line (x0+8, &x1, y0+4, &y1, width, height);
965 vp8_blit_line (x0+8, x1, y0+4, y1, y_buffer, y_stride);
969 x1 = x0 + 8 + (mv->col >> 3);
970 y1 = y0 +12 + (mv->row >> 3);
972 constrain_line (x0+8, &x1, y0+12, &y1, width, height);
973 vp8_blit_line (x0+8, x1, y0+12, y1, y_buffer, y_stride);
977 case 1 : /* mv_left_right */
979 union b_mode_info *bmi = &mi->bmi[0];
980 MV *mv = &bmi->mv.as_mv;
982 x1 = x0 + 4 + (mv->col >> 3);
983 y1 = y0 + 8 + (mv->row >> 3);
985 constrain_line (x0+4, &x1, y0+8, &y1, width, height);
986 vp8_blit_line (x0+4, x1, y0+8, y1, y_buffer, y_stride);
990 x1 = x0 +12 + (mv->col >> 3);
991 y1 = y0 + 8 + (mv->row >> 3);
993 constrain_line (x0+12, &x1, y0+8, &y1, width, height);
994 vp8_blit_line (x0+12, x1, y0+8, y1, y_buffer, y_stride);
998 case 2 : /* mv_quarters */
1000 union b_mode_info *bmi = &mi->bmi[0];
1001 MV *mv = &bmi->mv.as_mv;
1003 x1 = x0 + 4 + (mv->col >> 3);
1004 y1 = y0 + 4 + (mv->row >> 3);
1006 constrain_line (x0+4, &x1, y0+4, &y1, width, height);
1007 vp8_blit_line (x0+4, x1, y0+4, y1, y_buffer, y_stride);
1011 x1 = x0 +12 + (mv->col >> 3);
1012 y1 = y0 + 4 + (mv->row >> 3);
1014 constrain_line (x0+12, &x1, y0+4, &y1, width, height);
1015 vp8_blit_line (x0+12, x1, y0+4, y1, y_buffer, y_stride);
1019 x1 = x0 + 4 + (mv->col >> 3);
1020 y1 = y0 +12 + (mv->row >> 3);
1022 constrain_line (x0+4, &x1, y0+12, &y1, width, height);
1023 vp8_blit_line (x0+4, x1, y0+12, y1, y_buffer, y_stride);
1027 x1 = x0 +12 + (mv->col >> 3);
1028 y1 = y0 +12 + (mv->row >> 3);
1030 constrain_line (x0+12, &x1, y0+12, &y1, width, height);
1031 vp8_blit_line (x0+12, x1, y0+12, y1, y_buffer, y_stride);
1036 union b_mode_info *bmi = mi->bmi;
1039 for (by0 = y0; by0 < (y0+16); by0 += 4)
1041 for (bx0 = x0; bx0 < (x0+16); bx0 += 4)
1043 MV *mv = &bmi->mv.as_mv;
1045 x1 = bx0 + 2 + (mv->col >> 3);
1046 y1 = by0 + 2 + (mv->row >> 3);
1048 constrain_line (bx0+2, &x1, by0+2, &y1, width, height);
1049 vp8_blit_line (bx0+2, x1, by0+2, y1, y_buffer, y_stride);
1057 else if (mi->mbmi.mode >= NEARESTMV)
1059 MV *mv = &mi->mbmi.mv.as_mv;
1060 const int lx0 = x0 + 8;
1061 const int ly0 = y0 + 8;
1063 x1 = lx0 + (mv->col >> 3);
1064 y1 = ly0 + (mv->row >> 3);
1066 if (x1 != lx0 && y1 != ly0)
1068 constrain_line (lx0, &x1, ly0-1, &y1, width, height);
1069 vp8_blit_line (lx0, x1, ly0-1, y1, y_buffer, y_stride);
1071 constrain_line (lx0, &x1, ly0+1, &y1, width, height);
1072 vp8_blit_line (lx0, x1, ly0+1, y1, y_buffer, y_stride);
1075 vp8_blit_line (lx0, x1, ly0, y1, y_buffer, y_stride);
1084 /* Color in block modes */
1085 if ((flags & VP8D_DEBUG_CLR_BLK_MODES)
1086 && (ppflags->display_mb_modes_flag || ppflags->display_b_modes_flag))
1089 YV12_BUFFER_CONFIG *post = &oci->post_proc_buffer;
1090 int width = post->y_width;
1091 int height = post->y_height;
1092 unsigned char *y_ptr = oci->post_proc_buffer.y_buffer;
1093 unsigned char *u_ptr = oci->post_proc_buffer.u_buffer;
1094 unsigned char *v_ptr = oci->post_proc_buffer.v_buffer;
1095 int y_stride = oci->post_proc_buffer.y_stride;
1096 MODE_INFO *mi = oci->mi;
1098 for (y = 0; y < height; y += 16)
1100 for (x = 0; x < width; x += 16)
1102 int Y = 0, U = 0, V = 0;
1104 if (mi->mbmi.mode == B_PRED &&
1105 ((ppflags->display_mb_modes_flag & B_PRED) || ppflags->display_b_modes_flag))
1108 unsigned char *yl, *ul, *vl;
1109 union b_mode_info *bmi = mi->bmi;
1112 ul = u_ptr + (x>>1);
1113 vl = v_ptr + (x>>1);
1115 for (by = 0; by < 16; by += 4)
1117 for (bx = 0; bx < 16; bx += 4)
1119 if ((ppflags->display_b_modes_flag & (1<<mi->mbmi.mode))
1120 || (ppflags->display_mb_modes_flag & B_PRED))
1122 Y = B_PREDICTION_MODE_colors[bmi->as_mode][0];
1123 U = B_PREDICTION_MODE_colors[bmi->as_mode][1];
1124 V = B_PREDICTION_MODE_colors[bmi->as_mode][2];
1127 (yl+bx, ul+(bx>>1), vl+(bx>>1), Y, U, V, 0xc000, y_stride);
1137 else if (ppflags->display_mb_modes_flag & (1<<mi->mbmi.mode))
1139 Y = MB_PREDICTION_MODE_colors[mi->mbmi.mode][0];
1140 U = MB_PREDICTION_MODE_colors[mi->mbmi.mode][1];
1141 V = MB_PREDICTION_MODE_colors[mi->mbmi.mode][2];
1144 (y_ptr+x, u_ptr+(x>>1), v_ptr+(x>>1), Y, U, V, 0xc000, y_stride);
1149 y_ptr += y_stride*16;
1150 u_ptr += y_stride*4;
1151 v_ptr += y_stride*4;
1157 /* Color in frame reference blocks */
1158 if ((flags & VP8D_DEBUG_CLR_FRM_REF_BLKS) && ppflags->display_ref_frame_flag)
1161 YV12_BUFFER_CONFIG *post = &oci->post_proc_buffer;
1162 int width = post->y_width;
1163 int height = post->y_height;
1164 unsigned char *y_ptr = oci->post_proc_buffer.y_buffer;
1165 unsigned char *u_ptr = oci->post_proc_buffer.u_buffer;
1166 unsigned char *v_ptr = oci->post_proc_buffer.v_buffer;
1167 int y_stride = oci->post_proc_buffer.y_stride;
1168 MODE_INFO *mi = oci->mi;
1170 for (y = 0; y < height; y += 16)
1172 for (x = 0; x < width; x +=16)
1174 int Y = 0, U = 0, V = 0;
1176 if (ppflags->display_ref_frame_flag & (1<<mi->mbmi.ref_frame))
1178 Y = MV_REFERENCE_FRAME_colors[mi->mbmi.ref_frame][0];
1179 U = MV_REFERENCE_FRAME_colors[mi->mbmi.ref_frame][1];
1180 V = MV_REFERENCE_FRAME_colors[mi->mbmi.ref_frame][2];
1183 (y_ptr+x, u_ptr+(x>>1), v_ptr+(x>>1), Y, U, V, 0xc000, y_stride);
1188 y_ptr += y_stride*16;
1189 u_ptr += y_stride*4;
1190 v_ptr += y_stride*4;
1197 *dest = oci->post_proc_buffer;
1199 /* handle problem with extending borders */
1200 dest->y_width = oci->Width;
1201 dest->y_height = oci->Height;
1202 dest->uv_height = dest->y_height / 2;