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_ports/config.h"
13 #include "vpx_scale/yv12config.h"
15 #include "vpx_scale/yv12extend.h"
16 #include "vpx_scale/vpxscale.h"
17 #include "systemdependent.h"
23 #define RGB_TO_YUV(t) \
24 ( (0.257*(float)(t>>16)) + (0.504*(float)(t>>8&0xff)) + (0.098*(float)(t&0xff)) + 16), \
25 (-(0.148*(float)(t>>16)) - (0.291*(float)(t>>8&0xff)) + (0.439*(float)(t&0xff)) + 128), \
26 ( (0.439*(float)(t>>16)) - (0.368*(float)(t>>8&0xff)) - (0.071*(float)(t&0xff)) + 128)
28 /* global constants */
29 #if CONFIG_POSTPROC_VISUALIZER
30 static const unsigned char MB_PREDICTION_MODE_colors
[MB_MODE_COUNT
][3] =
32 { RGB_TO_YUV(0x98FB98) }, /* PaleGreen */
33 { RGB_TO_YUV(0x00FF00) }, /* Green */
34 { RGB_TO_YUV(0xADFF2F) }, /* GreenYellow */
35 { RGB_TO_YUV(0x228B22) }, /* ForestGreen */
36 { RGB_TO_YUV(0x006400) }, /* DarkGreen */
37 { RGB_TO_YUV(0x98F5FF) }, /* Cadet Blue */
38 { RGB_TO_YUV(0x6CA6CD) }, /* Sky Blue */
39 { RGB_TO_YUV(0x00008B) }, /* Dark blue */
40 { RGB_TO_YUV(0x551A8B) }, /* Purple */
41 { RGB_TO_YUV(0xFF0000) } /* Red */
44 static const unsigned char B_PREDICTION_MODE_colors
[B_MODE_COUNT
][3] =
46 { RGB_TO_YUV(0x6633ff) }, /* Purple */
47 { RGB_TO_YUV(0xcc33ff) }, /* Magenta */
48 { RGB_TO_YUV(0xff33cc) }, /* Pink */
49 { RGB_TO_YUV(0xff3366) }, /* Coral */
50 { RGB_TO_YUV(0x3366ff) }, /* Blue */
51 { RGB_TO_YUV(0xed00f5) }, /* Dark Blue */
52 { RGB_TO_YUV(0x2e00b8) }, /* Dark Purple */
53 { RGB_TO_YUV(0xff6633) }, /* Orange */
54 { RGB_TO_YUV(0x33ccff) }, /* Light Blue */
55 { RGB_TO_YUV(0x8ab800) }, /* Green */
56 { RGB_TO_YUV(0xffcc33) }, /* Light Orange */
57 { RGB_TO_YUV(0x33ffcc) }, /* Aqua */
58 { RGB_TO_YUV(0x66ff33) }, /* Light Green */
59 { RGB_TO_YUV(0xccff33) }, /* Yellow */
62 static const unsigned char MV_REFERENCE_FRAME_colors
[MAX_REF_FRAMES
][3] =
64 { RGB_TO_YUV(0x00ff00) }, /* Blue */
65 { RGB_TO_YUV(0x0000ff) }, /* Green */
66 { RGB_TO_YUV(0xffff00) }, /* Yellow */
67 { RGB_TO_YUV(0xff0000) }, /* Red */
71 static const short kernel5
[] =
76 const short vp8_rv
[] =
78 8, 5, 2, 2, 8, 12, 4, 9, 8, 3,
79 0, 3, 9, 0, 0, 0, 8, 3, 14, 4,
80 10, 1, 11, 14, 1, 14, 9, 6, 12, 11,
81 8, 6, 10, 0, 0, 8, 9, 0, 3, 14,
82 8, 11, 13, 4, 2, 9, 0, 3, 9, 6,
83 1, 2, 3, 14, 13, 1, 8, 2, 9, 7,
84 3, 3, 1, 13, 13, 6, 6, 5, 2, 7,
85 11, 9, 11, 8, 7, 3, 2, 0, 13, 13,
86 14, 4, 12, 5, 12, 10, 8, 10, 13, 10,
87 4, 14, 4, 10, 0, 8, 11, 1, 13, 7,
88 7, 14, 6, 14, 13, 2, 13, 5, 4, 4,
89 0, 10, 0, 5, 13, 2, 12, 7, 11, 13,
90 8, 0, 4, 10, 7, 2, 7, 2, 2, 5,
91 3, 4, 7, 3, 3, 14, 14, 5, 9, 13,
92 3, 14, 3, 6, 3, 0, 11, 8, 13, 1,
93 13, 1, 12, 0, 10, 9, 7, 6, 2, 8,
94 5, 2, 13, 7, 1, 13, 14, 7, 6, 7,
95 9, 6, 10, 11, 7, 8, 7, 5, 14, 8,
96 4, 4, 0, 8, 7, 10, 0, 8, 14, 11,
97 3, 12, 5, 7, 14, 3, 14, 5, 2, 6,
98 11, 12, 12, 8, 0, 11, 13, 1, 2, 0,
99 5, 10, 14, 7, 8, 0, 4, 11, 0, 8,
100 0, 3, 10, 5, 8, 0, 11, 6, 7, 8,
101 10, 7, 13, 9, 2, 5, 1, 5, 10, 2,
102 4, 3, 5, 6, 10, 8, 9, 4, 11, 14,
103 0, 10, 0, 5, 13, 2, 12, 7, 11, 13,
104 8, 0, 4, 10, 7, 2, 7, 2, 2, 5,
105 3, 4, 7, 3, 3, 14, 14, 5, 9, 13,
106 3, 14, 3, 6, 3, 0, 11, 8, 13, 1,
107 13, 1, 12, 0, 10, 9, 7, 6, 2, 8,
108 5, 2, 13, 7, 1, 13, 14, 7, 6, 7,
109 9, 6, 10, 11, 7, 8, 7, 5, 14, 8,
110 4, 4, 0, 8, 7, 10, 0, 8, 14, 11,
111 3, 12, 5, 7, 14, 3, 14, 5, 2, 6,
112 11, 12, 12, 8, 0, 11, 13, 1, 2, 0,
113 5, 10, 14, 7, 8, 0, 4, 11, 0, 8,
114 0, 3, 10, 5, 8, 0, 11, 6, 7, 8,
115 10, 7, 13, 9, 2, 5, 1, 5, 10, 2,
116 4, 3, 5, 6, 10, 8, 9, 4, 11, 14,
117 3, 8, 3, 7, 8, 5, 11, 4, 12, 3,
118 11, 9, 14, 8, 14, 13, 4, 3, 1, 2,
119 14, 6, 5, 4, 4, 11, 4, 6, 2, 1,
120 5, 8, 8, 12, 13, 5, 14, 10, 12, 13,
121 0, 9, 5, 5, 11, 10, 13, 9, 10, 13,
125 extern void vp8_blit_text(const char *msg
, unsigned char *address
, const int pitch
);
126 extern void vp8_blit_line(int x0
, int x1
, int y0
, int y1
, unsigned char *image
, const int pitch
);
127 /***********************************************************************************************************
129 void vp8_post_proc_down_and_across_c
131 unsigned char *src_ptr
,
132 unsigned char *dst_ptr
,
133 int src_pixels_per_line
,
134 int dst_pixels_per_line
,
140 unsigned char *p_src
, *p_dst
;
145 int pitch
= src_pixels_per_line
;
147 (void)dst_pixels_per_line
;
149 for (row
= 0; row
< rows
; row
++)
151 /* post_proc_down for one row */
155 for (col
= 0; col
< cols
; col
++)
161 for (i
= -2; i
<= 2; i
++)
163 if (abs(v
- p_src
[col
+i
*pitch
]) > flimit
)
164 goto down_skip_convolve
;
166 kernel
+= kernel5
[2+i
] * p_src
[col
+i
*pitch
];
174 /* now post_proc_across */
178 for (i
= 0; i
< 8; i
++)
181 for (col
= 0; col
< cols
; col
++)
188 for (i
= -2; i
<= 2; i
++)
190 if (abs(v
- p_src
[col
+i
]) > flimit
)
191 goto across_skip_convolve
;
193 kernel
+= kernel5
[2+i
] * p_src
[col
+i
];
196 d
[col
&7] = (kernel
>> 3);
197 across_skip_convolve
:
200 p_dst
[col
-2] = d
[(col
-2)&7];
203 /* handle the last two pixels */
204 p_dst
[col
-2] = d
[(col
-2)&7];
205 p_dst
[col
-1] = d
[(col
-1)&7];
218 x
= 50 + (x
- 50) * 10 / 8;
221 void vp8_mbpost_proc_across_ip_c(unsigned char *src
, int pitch
, int rows
, int cols
, int flimit
)
225 unsigned char *s
= src
;
229 for (r
= 0; r
< rows
; r
++)
234 for (i
= -8; i
<= 6; i
++)
236 sumsq
+= s
[i
] * s
[i
];
241 for (c
= 0; c
< cols
+ 8; c
++)
243 int x
= s
[c
+7] - s
[c
-8];
244 int y
= s
[c
+7] + s
[c
-8];
251 if (sumsq
* 15 - sum
* sum
< flimit
)
253 d
[c
&15] = (8 + sum
+ s
[c
]) >> 4;
256 s
[c
-8] = d
[(c
-8)&15];
267 void vp8_mbpost_proc_down_c(unsigned char *dst
, int pitch
, int rows
, int cols
, int flimit
)
270 const short *rv3
= &vp8_rv
[63&rand()];
272 for (c
= 0; c
< cols
; c
++)
274 unsigned char *s
= &dst
[c
];
278 const short *rv2
= rv3
+ ((c
* 17) & 127);
280 for (i
= -8; i
<= 6; i
++)
282 sumsq
+= s
[i
*pitch
] * s
[i
*pitch
];
286 for (r
= 0; r
< rows
+ 8; r
++)
288 sumsq
+= s
[7*pitch
] * s
[ 7*pitch
] - s
[-8*pitch
] * s
[-8*pitch
];
289 sum
+= s
[7*pitch
] - s
[-8*pitch
];
292 if (sumsq
* 15 - sum
* sum
< flimit
)
294 d
[r
&15] = (rv2
[r
&127] + sum
+ s
[0]) >> 4;
297 s
[-8*pitch
] = d
[(r
-8)&15];
304 static void vp8_deblock_and_de_macro_block(YV12_BUFFER_CONFIG
*source
,
305 YV12_BUFFER_CONFIG
*post
,
309 vp8_postproc_rtcd_vtable_t
*rtcd
)
311 double level
= 6.0e-05 * q
* q
* q
- .0067 * q
* q
+ .306 * q
+ .0065;
312 int ppl
= (int)(level
+ .5);
313 (void) low_var_thresh
;
316 POSTPROC_INVOKE(rtcd
, downacross
)(source
->y_buffer
, post
->y_buffer
, source
->y_stride
, post
->y_stride
, source
->y_height
, source
->y_width
, ppl
);
317 POSTPROC_INVOKE(rtcd
, across
)(post
->y_buffer
, post
->y_stride
, post
->y_height
, post
->y_width
, vp8_q2mbl(q
));
318 POSTPROC_INVOKE(rtcd
, down
)(post
->y_buffer
, post
->y_stride
, post
->y_height
, post
->y_width
, vp8_q2mbl(q
));
320 POSTPROC_INVOKE(rtcd
, downacross
)(source
->u_buffer
, post
->u_buffer
, source
->uv_stride
, post
->uv_stride
, source
->uv_height
, source
->uv_width
, ppl
);
321 POSTPROC_INVOKE(rtcd
, downacross
)(source
->v_buffer
, post
->v_buffer
, source
->uv_stride
, post
->uv_stride
, source
->uv_height
, source
->uv_width
, ppl
);
325 void vp8_deblock(YV12_BUFFER_CONFIG
*source
,
326 YV12_BUFFER_CONFIG
*post
,
330 vp8_postproc_rtcd_vtable_t
*rtcd
)
332 double level
= 6.0e-05 * q
* q
* q
- .0067 * q
* q
+ .306 * q
+ .0065;
333 int ppl
= (int)(level
+ .5);
334 (void) low_var_thresh
;
337 POSTPROC_INVOKE(rtcd
, downacross
)(source
->y_buffer
, post
->y_buffer
, source
->y_stride
, post
->y_stride
, source
->y_height
, source
->y_width
, ppl
);
338 POSTPROC_INVOKE(rtcd
, downacross
)(source
->u_buffer
, post
->u_buffer
, source
->uv_stride
, post
->uv_stride
, source
->uv_height
, source
->uv_width
, ppl
);
339 POSTPROC_INVOKE(rtcd
, downacross
)(source
->v_buffer
, post
->v_buffer
, source
->uv_stride
, post
->uv_stride
, source
->uv_height
, source
->uv_width
, ppl
);
342 void vp8_de_noise(YV12_BUFFER_CONFIG
*source
,
343 YV12_BUFFER_CONFIG
*post
,
347 vp8_postproc_rtcd_vtable_t
*rtcd
)
349 double level
= 6.0e-05 * q
* q
* q
- .0067 * q
* q
+ .306 * q
+ .0065;
350 int ppl
= (int)(level
+ .5);
352 (void) low_var_thresh
;
355 POSTPROC_INVOKE(rtcd
, downacross
)(
356 source
->y_buffer
+ 2 * source
->y_stride
+ 2,
357 source
->y_buffer
+ 2 * source
->y_stride
+ 2,
360 source
->y_height
- 4,
363 POSTPROC_INVOKE(rtcd
, downacross
)(
364 source
->u_buffer
+ 2 * source
->uv_stride
+ 2,
365 source
->u_buffer
+ 2 * source
->uv_stride
+ 2,
368 source
->uv_height
- 4,
369 source
->uv_width
- 4, ppl
);
370 POSTPROC_INVOKE(rtcd
, downacross
)(
371 source
->v_buffer
+ 2 * source
->uv_stride
+ 2,
372 source
->v_buffer
+ 2 * source
->uv_stride
+ 2,
375 source
->uv_height
- 4,
376 source
->uv_width
- 4, ppl
);
380 double vp8_gaussian(double sigma
, double mu
, double x
)
382 return 1 / (sigma
* sqrt(2.0 * 3.14159265)) *
383 (exp(-(x
- mu
) * (x
- mu
) / (2 * sigma
* sigma
)));
386 extern void (*vp8_clear_system_state
)(void);
389 static void fillrd(struct postproc_state
*state
, int q
, int a
)
394 int ai
= a
, qi
= q
, i
;
396 vp8_clear_system_state();
399 sigma
= ai
+ .5 + .6 * (63 - qi
) / 63.0;
401 /* set up a lookup table of 256 entries that matches
402 * a gaussian distribution with sigma determined by q.
410 for (i
= -32; i
< 32; i
++)
412 int a
= (int)(.5 + 256 * vp8_gaussian(sigma
, 0, i
));
416 for (j
= 0; j
< a
; j
++)
418 char_dist
[next
+j
] = (char) i
;
426 for (next
= next
; next
< 256; next
++)
431 for (i
= 0; i
< 3072; i
++)
433 state
->noise
[i
] = char_dist
[rand() & 0xff];
436 for (i
= 0; i
< 16; i
++)
438 state
->blackclamp
[i
] = -char_dist
[0];
439 state
->whiteclamp
[i
] = -char_dist
[0];
440 state
->bothclamp
[i
] = -2 * char_dist
[0];
444 state
->last_noise
= a
;
447 /****************************************************************************
449 * ROUTINE : plane_add_noise_c
451 * INPUTS : unsigned char *Start starting address of buffer to add gaussian
453 * unsigned int Width width of plane
454 * unsigned int Height height of plane
455 * int Pitch distance between subsequent lines of frame
456 * int q quantizer used to determine amount of noise
463 * FUNCTION : adds gaussian noise to a plane of pixels
465 * SPECIAL NOTES : None.
467 ****************************************************************************/
468 void vp8_plane_add_noise_c(unsigned char *Start
, char *noise
,
472 unsigned int Width
, unsigned int Height
, int Pitch
)
476 for (i
= 0; i
< Height
; i
++)
478 unsigned char *Pos
= Start
+ i
* Pitch
;
479 char *Ref
= (char *)(noise
+ (rand() & 0xff));
481 for (j
= 0; j
< Width
; j
++)
483 if (Pos
[j
] < blackclamp
[0])
484 Pos
[j
] = blackclamp
[0];
486 if (Pos
[j
] > 255 + whiteclamp
[0])
487 Pos
[j
] = 255 + whiteclamp
[0];
494 /* Blend the macro block with a solid colored square. Leave the
495 * edges unblended to give distinction to macro blocks in areas
496 * filled with the same color block.
498 void vp8_blend_mb_inner_c (unsigned char *y
, unsigned char *u
, unsigned char *v
,
499 int y1
, int u1
, int v1
, int alpha
, int stride
)
502 int y1_const
= y1
*((1<<16)-alpha
);
503 int u1_const
= u1
*((1<<16)-alpha
);
504 int v1_const
= v1
*((1<<16)-alpha
);
507 for (i
= 0; i
< 12; i
++)
509 for (j
= 0; j
< 12; j
++)
511 y
[j
] = (y
[j
]*alpha
+ y1_const
)>>16;
521 for (i
= 0; i
< 6; i
++)
523 for (j
= 0; j
< 6; j
++)
525 u
[j
] = (u
[j
]*alpha
+ u1_const
)>>16;
526 v
[j
] = (v
[j
]*alpha
+ v1_const
)>>16;
533 /* Blend only the edge of the macro block. Leave center
534 * unblended to allow for other visualizations to be layered.
536 void vp8_blend_mb_outer_c (unsigned char *y
, unsigned char *u
, unsigned char *v
,
537 int y1
, int u1
, int v1
, int alpha
, int stride
)
540 int y1_const
= y1
*((1<<16)-alpha
);
541 int u1_const
= u1
*((1<<16)-alpha
);
542 int v1_const
= v1
*((1<<16)-alpha
);
544 for (i
= 0; i
< 2; i
++)
546 for (j
= 0; j
< 16; j
++)
548 y
[j
] = (y
[j
]*alpha
+ y1_const
)>>16;
553 for (i
= 0; i
< 12; i
++)
555 y
[0] = (y
[0]*alpha
+ y1_const
)>>16;
556 y
[1] = (y
[1]*alpha
+ y1_const
)>>16;
557 y
[14] = (y
[14]*alpha
+ y1_const
)>>16;
558 y
[15] = (y
[15]*alpha
+ y1_const
)>>16;
562 for (i
= 0; i
< 2; i
++)
564 for (j
= 0; j
< 16; j
++)
566 y
[j
] = (y
[j
]*alpha
+ y1_const
)>>16;
573 for (j
= 0; j
< 8; j
++)
575 u
[j
] = (u
[j
]*alpha
+ u1_const
)>>16;
576 v
[j
] = (v
[j
]*alpha
+ v1_const
)>>16;
581 for (i
= 0; i
< 6; i
++)
583 u
[0] = (u
[0]*alpha
+ u1_const
)>>16;
584 v
[0] = (v
[0]*alpha
+ v1_const
)>>16;
586 u
[7] = (u
[7]*alpha
+ u1_const
)>>16;
587 v
[7] = (v
[7]*alpha
+ v1_const
)>>16;
593 for (j
= 0; j
< 8; j
++)
595 u
[j
] = (u
[j
]*alpha
+ u1_const
)>>16;
596 v
[j
] = (v
[j
]*alpha
+ v1_const
)>>16;
600 void vp8_blend_b_c (unsigned char *y
, unsigned char *u
, unsigned char *v
,
601 int y1
, int u1
, int v1
, int alpha
, int stride
)
604 int y1_const
= y1
*((1<<16)-alpha
);
605 int u1_const
= u1
*((1<<16)-alpha
);
606 int v1_const
= v1
*((1<<16)-alpha
);
608 for (i
= 0; i
< 4; i
++)
610 for (j
= 0; j
< 4; j
++)
612 y
[j
] = (y
[j
]*alpha
+ y1_const
)>>16;
619 for (i
= 0; i
< 2; i
++)
621 for (j
= 0; j
< 2; j
++)
623 u
[j
] = (u
[j
]*alpha
+ u1_const
)>>16;
624 v
[j
] = (v
[j
]*alpha
+ v1_const
)>>16;
631 static void constrain_line (int x0
, int *x1
, int y0
, int *y1
, int width
, int height
)
643 *y1
= ((width
-x0
)*dy
)/dx
+ y0
;
652 *y1
= ((0-x0
)*dy
)/dx
+ y0
;
661 *x1
= ((height
-y0
)*dx
)/dy
+ x0
;
670 *x1
= ((0-y0
)*dx
)/dy
+ x0
;
675 #if CONFIG_RUNTIME_CPU_DETECT
676 #define RTCD_VTABLE(oci) (&(oci)->rtcd.postproc)
678 #define RTCD_VTABLE(oci) NULL
681 int vp8_post_proc_frame(VP8_COMMON
*oci
, YV12_BUFFER_CONFIG
*dest
, vp8_ppflags_t
*ppflags
)
683 int q
= oci
->filter_level
* 10 / 6;
684 int flags
= ppflags
->post_proc_flag
;
685 int deblock_level
= ppflags
->deblocking_level
;
686 int noise_level
= ppflags
->noise_level
;
688 if (!oci
->frame_to_show
)
696 *dest
= *oci
->frame_to_show
;
698 /* handle problem with extending borders */
699 dest
->y_width
= oci
->Width
;
700 dest
->y_height
= oci
->Height
;
701 dest
->uv_height
= dest
->y_height
/ 2;
706 #if ARCH_X86||ARCH_X86_64
707 vpx_reset_mmx_state();
710 if (flags
& VP8D_DEMACROBLOCK
)
712 vp8_deblock_and_de_macro_block(oci
->frame_to_show
, &oci
->post_proc_buffer
,
713 q
+ (deblock_level
- 5) * 10, 1, 0, RTCD_VTABLE(oci
));
715 else if (flags
& VP8D_DEBLOCK
)
717 vp8_deblock(oci
->frame_to_show
, &oci
->post_proc_buffer
,
718 q
, 1, 0, RTCD_VTABLE(oci
));
722 vp8_yv12_copy_frame_ptr(oci
->frame_to_show
, &oci
->post_proc_buffer
);
725 if (flags
& VP8D_ADDNOISE
)
727 if (oci
->postproc_state
.last_q
!= q
728 || oci
->postproc_state
.last_noise
!= noise_level
)
730 fillrd(&oci
->postproc_state
, 63 - q
, noise_level
);
733 POSTPROC_INVOKE(RTCD_VTABLE(oci
), addnoise
)
734 (oci
->post_proc_buffer
.y_buffer
,
735 oci
->postproc_state
.noise
,
736 oci
->postproc_state
.blackclamp
,
737 oci
->postproc_state
.whiteclamp
,
738 oci
->postproc_state
.bothclamp
,
739 oci
->post_proc_buffer
.y_width
, oci
->post_proc_buffer
.y_height
,
740 oci
->post_proc_buffer
.y_stride
);
743 #if CONFIG_POSTPROC_VISUALIZER
744 if (flags
& VP8D_DEBUG_TXT_FRAME_INFO
)
747 sprintf(message
, "F%1dG%1dQ%3dF%3dP%d_s%dx%d",
748 (oci
->frame_type
== KEY_FRAME
),
749 oci
->refresh_golden_frame
,
753 oci
->mb_cols
, oci
->mb_rows
);
754 vp8_blit_text(message
, oci
->post_proc_buffer
.y_buffer
, oci
->post_proc_buffer
.y_stride
);
757 if (flags
& VP8D_DEBUG_TXT_MBLK_MODES
)
760 unsigned char *y_ptr
;
761 YV12_BUFFER_CONFIG
*post
= &oci
->post_proc_buffer
;
762 int mb_rows
= post
->y_height
>> 4;
763 int mb_cols
= post
->y_width
>> 4;
765 MODE_INFO
*mi
= oci
->mi
;
767 y_ptr
= post
->y_buffer
+ 4 * post
->y_stride
+ 4;
769 /* vp8_filter each macro block */
770 for (i
= 0; i
< mb_rows
; i
++)
772 for (j
= 0; j
< mb_cols
; j
++)
776 sprintf(zz
, "%c", mi
[mb_index
].mbmi
.mode
+ 'a');
778 vp8_blit_text(zz
, y_ptr
, post
->y_stride
);
783 mb_index
++; /* border */
784 y_ptr
+= post
->y_stride
* 16 - post
->y_width
;
789 if (flags
& VP8D_DEBUG_TXT_DC_DIFF
)
792 unsigned char *y_ptr
;
793 YV12_BUFFER_CONFIG
*post
= &oci
->post_proc_buffer
;
794 int mb_rows
= post
->y_height
>> 4;
795 int mb_cols
= post
->y_width
>> 4;
797 MODE_INFO
*mi
= oci
->mi
;
799 y_ptr
= post
->y_buffer
+ 4 * post
->y_stride
+ 4;
801 /* vp8_filter each macro block */
802 for (i
= 0; i
< mb_rows
; i
++)
804 for (j
= 0; j
< mb_cols
; j
++)
808 if (oci
->frame_type
== KEY_FRAME
)
811 sprintf(zz
, "%c", mi
[mb_index
].mbmi
.dc_diff
+ '0');
813 vp8_blit_text(zz
, y_ptr
, post
->y_stride
);
818 mb_index
++; /* border */
819 y_ptr
+= post
->y_stride
* 16 - post
->y_width
;
824 if (flags
& VP8D_DEBUG_TXT_RATE_INFO
)
827 sprintf(message
, "Bitrate: %10.2f frame_rate: %10.2f ", oci
->bitrate
, oci
->framerate
);
828 vp8_blit_text(message
, oci
->post_proc_buffer
.y_buffer
, oci
->post_proc_buffer
.y_stride
);
831 /* Draw motion vectors */
832 if ((flags
& VP8D_DEBUG_DRAW_MV
) && ppflags
->display_mv_flag
)
834 YV12_BUFFER_CONFIG
*post
= &oci
->post_proc_buffer
;
835 int width
= post
->y_width
;
836 int height
= post
->y_height
;
837 int mb_cols
= width
>> 4;
838 unsigned char *y_buffer
= oci
->post_proc_buffer
.y_buffer
;
839 int y_stride
= oci
->post_proc_buffer
.y_stride
;
840 MODE_INFO
*mi
= oci
->mi
;
843 for (y0
= 0; y0
< height
; y0
+= 16)
845 for (x0
= 0; x0
< width
; x0
+= 16)
849 if (!(ppflags
->display_mv_flag
& (1<<mi
->mbmi
.mode
)))
855 if (mi
->mbmi
.mode
== SPLITMV
)
857 switch (mi
->mbmi
.partitioning
)
859 case 0 : /* mv_top_bottom */
861 B_MODE_INFO
*bmi
= &mi
->bmi
[0];
862 MV
*mv
= &bmi
->mv
.as_mv
;
864 x1
= x0
+ 8 + (mv
->col
>> 3);
865 y1
= y0
+ 4 + (mv
->row
>> 3);
867 constrain_line (x0
+8, &x1
, y0
+4, &y1
, width
, height
);
868 vp8_blit_line (x0
+8, x1
, y0
+4, y1
, y_buffer
, y_stride
);
872 x1
= x0
+ 8 + (mv
->col
>> 3);
873 y1
= y0
+12 + (mv
->row
>> 3);
875 constrain_line (x0
+8, &x1
, y0
+12, &y1
, width
, height
);
876 vp8_blit_line (x0
+8, x1
, y0
+12, y1
, y_buffer
, y_stride
);
880 case 1 : /* mv_left_right */
882 B_MODE_INFO
*bmi
= &mi
->bmi
[0];
883 MV
*mv
= &bmi
->mv
.as_mv
;
885 x1
= x0
+ 4 + (mv
->col
>> 3);
886 y1
= y0
+ 8 + (mv
->row
>> 3);
888 constrain_line (x0
+4, &x1
, y0
+8, &y1
, width
, height
);
889 vp8_blit_line (x0
+4, x1
, y0
+8, y1
, y_buffer
, y_stride
);
893 x1
= x0
+12 + (mv
->col
>> 3);
894 y1
= y0
+ 8 + (mv
->row
>> 3);
896 constrain_line (x0
+12, &x1
, y0
+8, &y1
, width
, height
);
897 vp8_blit_line (x0
+12, x1
, y0
+8, y1
, y_buffer
, y_stride
);
901 case 2 : /* mv_quarters */
903 B_MODE_INFO
*bmi
= &mi
->bmi
[0];
904 MV
*mv
= &bmi
->mv
.as_mv
;
906 x1
= x0
+ 4 + (mv
->col
>> 3);
907 y1
= y0
+ 4 + (mv
->row
>> 3);
909 constrain_line (x0
+4, &x1
, y0
+4, &y1
, width
, height
);
910 vp8_blit_line (x0
+4, x1
, y0
+4, y1
, y_buffer
, y_stride
);
914 x1
= x0
+12 + (mv
->col
>> 3);
915 y1
= y0
+ 4 + (mv
->row
>> 3);
917 constrain_line (x0
+12, &x1
, y0
+4, &y1
, width
, height
);
918 vp8_blit_line (x0
+12, x1
, y0
+4, y1
, y_buffer
, y_stride
);
922 x1
= x0
+ 4 + (mv
->col
>> 3);
923 y1
= y0
+12 + (mv
->row
>> 3);
925 constrain_line (x0
+4, &x1
, y0
+12, &y1
, width
, height
);
926 vp8_blit_line (x0
+4, x1
, y0
+12, y1
, y_buffer
, y_stride
);
930 x1
= x0
+12 + (mv
->col
>> 3);
931 y1
= y0
+12 + (mv
->row
>> 3);
933 constrain_line (x0
+12, &x1
, y0
+12, &y1
, width
, height
);
934 vp8_blit_line (x0
+12, x1
, y0
+12, y1
, y_buffer
, y_stride
);
939 B_MODE_INFO
*bmi
= mi
->bmi
;
942 for (by0
= y0
; by0
< (y0
+16); by0
+= 4)
944 for (bx0
= x0
; bx0
< (x0
+16); bx0
+= 4)
946 MV
*mv
= &bmi
->mv
.as_mv
;
948 x1
= bx0
+ 2 + (mv
->col
>> 3);
949 y1
= by0
+ 2 + (mv
->row
>> 3);
951 constrain_line (bx0
+2, &x1
, by0
+2, &y1
, width
, height
);
952 vp8_blit_line (bx0
+2, x1
, by0
+2, y1
, y_buffer
, y_stride
);
960 else if (mi
->mbmi
.mode
>= NEARESTMV
)
962 MV
*mv
= &mi
->mbmi
.mv
.as_mv
;
963 const int lx0
= x0
+ 8;
964 const int ly0
= y0
+ 8;
966 x1
= lx0
+ (mv
->col
>> 3);
967 y1
= ly0
+ (mv
->row
>> 3);
969 if (x1
!= lx0
&& y1
!= ly0
)
971 constrain_line (lx0
, &x1
, ly0
-1, &y1
, width
, height
);
972 vp8_blit_line (lx0
, x1
, ly0
-1, y1
, y_buffer
, y_stride
);
974 constrain_line (lx0
, &x1
, ly0
+1, &y1
, width
, height
);
975 vp8_blit_line (lx0
, x1
, ly0
+1, y1
, y_buffer
, y_stride
);
978 vp8_blit_line (lx0
, x1
, ly0
, y1
, y_buffer
, y_stride
);
987 /* Color in block modes */
988 if ((flags
& VP8D_DEBUG_CLR_BLK_MODES
)
989 && (ppflags
->display_mb_modes_flag
|| ppflags
->display_b_modes_flag
))
992 YV12_BUFFER_CONFIG
*post
= &oci
->post_proc_buffer
;
993 int width
= post
->y_width
;
994 int height
= post
->y_height
;
995 unsigned char *y_ptr
= oci
->post_proc_buffer
.y_buffer
;
996 unsigned char *u_ptr
= oci
->post_proc_buffer
.u_buffer
;
997 unsigned char *v_ptr
= oci
->post_proc_buffer
.v_buffer
;
998 int y_stride
= oci
->post_proc_buffer
.y_stride
;
999 MODE_INFO
*mi
= oci
->mi
;
1001 for (y
= 0; y
< height
; y
+= 16)
1003 for (x
= 0; x
< width
; x
+= 16)
1005 int Y
= 0, U
= 0, V
= 0;
1007 if (mi
->mbmi
.mode
== B_PRED
&&
1008 ((ppflags
->display_mb_modes_flag
& B_PRED
) || ppflags
->display_b_modes_flag
))
1011 unsigned char *yl
, *ul
, *vl
;
1012 B_MODE_INFO
*bmi
= mi
->bmi
;
1015 ul
= u_ptr
+ (x
>>1);
1016 vl
= v_ptr
+ (x
>>1);
1018 for (by
= 0; by
< 16; by
+= 4)
1020 for (bx
= 0; bx
< 16; bx
+= 4)
1022 if ((ppflags
->display_b_modes_flag
& (1<<mi
->mbmi
.mode
))
1023 || (ppflags
->display_mb_modes_flag
& B_PRED
))
1025 Y
= B_PREDICTION_MODE_colors
[bmi
->mode
][0];
1026 U
= B_PREDICTION_MODE_colors
[bmi
->mode
][1];
1027 V
= B_PREDICTION_MODE_colors
[bmi
->mode
][2];
1029 POSTPROC_INVOKE(RTCD_VTABLE(oci
), blend_b
)
1030 (yl
+bx
, ul
+(bx
>>1), vl
+(bx
>>1), Y
, U
, V
, 0xc000, y_stride
);
1040 else if (ppflags
->display_mb_modes_flag
& (1<<mi
->mbmi
.mode
))
1042 Y
= MB_PREDICTION_MODE_colors
[mi
->mbmi
.mode
][0];
1043 U
= MB_PREDICTION_MODE_colors
[mi
->mbmi
.mode
][1];
1044 V
= MB_PREDICTION_MODE_colors
[mi
->mbmi
.mode
][2];
1046 POSTPROC_INVOKE(RTCD_VTABLE(oci
), blend_mb_inner
)
1047 (y_ptr
+x
, u_ptr
+(x
>>1), v_ptr
+(x
>>1), Y
, U
, V
, 0xc000, y_stride
);
1052 y_ptr
+= y_stride
*16;
1053 u_ptr
+= y_stride
*4;
1054 v_ptr
+= y_stride
*4;
1060 /* Color in frame reference blocks */
1061 if ((flags
& VP8D_DEBUG_CLR_FRM_REF_BLKS
) && ppflags
->display_ref_frame_flag
)
1064 YV12_BUFFER_CONFIG
*post
= &oci
->post_proc_buffer
;
1065 int width
= post
->y_width
;
1066 int height
= post
->y_height
;
1067 unsigned char *y_ptr
= oci
->post_proc_buffer
.y_buffer
;
1068 unsigned char *u_ptr
= oci
->post_proc_buffer
.u_buffer
;
1069 unsigned char *v_ptr
= oci
->post_proc_buffer
.v_buffer
;
1070 int y_stride
= oci
->post_proc_buffer
.y_stride
;
1071 MODE_INFO
*mi
= oci
->mi
;
1073 for (y
= 0; y
< height
; y
+= 16)
1075 for (x
= 0; x
< width
; x
+=16)
1077 int Y
= 0, U
= 0, V
= 0;
1079 if (ppflags
->display_ref_frame_flag
& (1<<mi
->mbmi
.ref_frame
))
1081 Y
= MV_REFERENCE_FRAME_colors
[mi
->mbmi
.ref_frame
][0];
1082 U
= MV_REFERENCE_FRAME_colors
[mi
->mbmi
.ref_frame
][1];
1083 V
= MV_REFERENCE_FRAME_colors
[mi
->mbmi
.ref_frame
][2];
1085 POSTPROC_INVOKE(RTCD_VTABLE(oci
), blend_mb_outer
)
1086 (y_ptr
+x
, u_ptr
+(x
>>1), v_ptr
+(x
>>1), Y
, U
, V
, 0xc000, y_stride
);
1091 y_ptr
+= y_stride
*16;
1092 u_ptr
+= y_stride
*4;
1093 v_ptr
+= y_stride
*4;
1100 *dest
= oci
->post_proc_buffer
;
1102 /* handle problem with extending borders */
1103 dest
->y_width
= oci
->Width
;
1104 dest
->y_height
= oci
->Height
;
1105 dest
->uv_height
= dest
->y_height
/ 2;