1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/media/libvpx/vp8/common/postproc.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1206 @@ 1.4 +/* 1.5 + * Copyright (c) 2010 The WebM project authors. All Rights Reserved. 1.6 + * 1.7 + * Use of this source code is governed by a BSD-style license 1.8 + * that can be found in the LICENSE file in the root of the source 1.9 + * tree. An additional intellectual property rights grant can be found 1.10 + * in the file PATENTS. All contributing project authors may 1.11 + * be found in the AUTHORS file in the root of the source tree. 1.12 + */ 1.13 + 1.14 + 1.15 +#include "vpx_config.h" 1.16 +#include "vp8_rtcd.h" 1.17 +#include "vpx_scale_rtcd.h" 1.18 +#include "vpx_scale/yv12config.h" 1.19 +#include "postproc.h" 1.20 +#include "common.h" 1.21 +#include "vpx_scale/vpx_scale.h" 1.22 +#include "systemdependent.h" 1.23 + 1.24 +#include <limits.h> 1.25 +#include <math.h> 1.26 +#include <stdlib.h> 1.27 +#include <stdio.h> 1.28 + 1.29 +#define RGB_TO_YUV(t) \ 1.30 + ( (0.257*(float)(t>>16)) + (0.504*(float)(t>>8&0xff)) + (0.098*(float)(t&0xff)) + 16), \ 1.31 + (-(0.148*(float)(t>>16)) - (0.291*(float)(t>>8&0xff)) + (0.439*(float)(t&0xff)) + 128), \ 1.32 + ( (0.439*(float)(t>>16)) - (0.368*(float)(t>>8&0xff)) - (0.071*(float)(t&0xff)) + 128) 1.33 + 1.34 +/* global constants */ 1.35 +#if CONFIG_POSTPROC_VISUALIZER 1.36 +static const unsigned char MB_PREDICTION_MODE_colors[MB_MODE_COUNT][3] = 1.37 +{ 1.38 + { RGB_TO_YUV(0x98FB98) }, /* PaleGreen */ 1.39 + { RGB_TO_YUV(0x00FF00) }, /* Green */ 1.40 + { RGB_TO_YUV(0xADFF2F) }, /* GreenYellow */ 1.41 + { RGB_TO_YUV(0x228B22) }, /* ForestGreen */ 1.42 + { RGB_TO_YUV(0x006400) }, /* DarkGreen */ 1.43 + { RGB_TO_YUV(0x98F5FF) }, /* Cadet Blue */ 1.44 + { RGB_TO_YUV(0x6CA6CD) }, /* Sky Blue */ 1.45 + { RGB_TO_YUV(0x00008B) }, /* Dark blue */ 1.46 + { RGB_TO_YUV(0x551A8B) }, /* Purple */ 1.47 + { RGB_TO_YUV(0xFF0000) } /* Red */ 1.48 +}; 1.49 + 1.50 +static const unsigned char B_PREDICTION_MODE_colors[B_MODE_COUNT][3] = 1.51 +{ 1.52 + { RGB_TO_YUV(0x6633ff) }, /* Purple */ 1.53 + { RGB_TO_YUV(0xcc33ff) }, /* Magenta */ 1.54 + { RGB_TO_YUV(0xff33cc) }, /* Pink */ 1.55 + { RGB_TO_YUV(0xff3366) }, /* Coral */ 1.56 + { RGB_TO_YUV(0x3366ff) }, /* Blue */ 1.57 + { RGB_TO_YUV(0xed00f5) }, /* Dark Blue */ 1.58 + { RGB_TO_YUV(0x2e00b8) }, /* Dark Purple */ 1.59 + { RGB_TO_YUV(0xff6633) }, /* Orange */ 1.60 + { RGB_TO_YUV(0x33ccff) }, /* Light Blue */ 1.61 + { RGB_TO_YUV(0x8ab800) }, /* Green */ 1.62 + { RGB_TO_YUV(0xffcc33) }, /* Light Orange */ 1.63 + { RGB_TO_YUV(0x33ffcc) }, /* Aqua */ 1.64 + { RGB_TO_YUV(0x66ff33) }, /* Light Green */ 1.65 + { RGB_TO_YUV(0xccff33) }, /* Yellow */ 1.66 +}; 1.67 + 1.68 +static const unsigned char MV_REFERENCE_FRAME_colors[MAX_REF_FRAMES][3] = 1.69 +{ 1.70 + { RGB_TO_YUV(0x00ff00) }, /* Blue */ 1.71 + { RGB_TO_YUV(0x0000ff) }, /* Green */ 1.72 + { RGB_TO_YUV(0xffff00) }, /* Yellow */ 1.73 + { RGB_TO_YUV(0xff0000) }, /* Red */ 1.74 +}; 1.75 +#endif 1.76 + 1.77 +static const short kernel5[] = 1.78 +{ 1.79 + 1, 1, 4, 1, 1 1.80 +}; 1.81 + 1.82 +const short vp8_rv[] = 1.83 +{ 1.84 + 8, 5, 2, 2, 8, 12, 4, 9, 8, 3, 1.85 + 0, 3, 9, 0, 0, 0, 8, 3, 14, 4, 1.86 + 10, 1, 11, 14, 1, 14, 9, 6, 12, 11, 1.87 + 8, 6, 10, 0, 0, 8, 9, 0, 3, 14, 1.88 + 8, 11, 13, 4, 2, 9, 0, 3, 9, 6, 1.89 + 1, 2, 3, 14, 13, 1, 8, 2, 9, 7, 1.90 + 3, 3, 1, 13, 13, 6, 6, 5, 2, 7, 1.91 + 11, 9, 11, 8, 7, 3, 2, 0, 13, 13, 1.92 + 14, 4, 12, 5, 12, 10, 8, 10, 13, 10, 1.93 + 4, 14, 4, 10, 0, 8, 11, 1, 13, 7, 1.94 + 7, 14, 6, 14, 13, 2, 13, 5, 4, 4, 1.95 + 0, 10, 0, 5, 13, 2, 12, 7, 11, 13, 1.96 + 8, 0, 4, 10, 7, 2, 7, 2, 2, 5, 1.97 + 3, 4, 7, 3, 3, 14, 14, 5, 9, 13, 1.98 + 3, 14, 3, 6, 3, 0, 11, 8, 13, 1, 1.99 + 13, 1, 12, 0, 10, 9, 7, 6, 2, 8, 1.100 + 5, 2, 13, 7, 1, 13, 14, 7, 6, 7, 1.101 + 9, 6, 10, 11, 7, 8, 7, 5, 14, 8, 1.102 + 4, 4, 0, 8, 7, 10, 0, 8, 14, 11, 1.103 + 3, 12, 5, 7, 14, 3, 14, 5, 2, 6, 1.104 + 11, 12, 12, 8, 0, 11, 13, 1, 2, 0, 1.105 + 5, 10, 14, 7, 8, 0, 4, 11, 0, 8, 1.106 + 0, 3, 10, 5, 8, 0, 11, 6, 7, 8, 1.107 + 10, 7, 13, 9, 2, 5, 1, 5, 10, 2, 1.108 + 4, 3, 5, 6, 10, 8, 9, 4, 11, 14, 1.109 + 0, 10, 0, 5, 13, 2, 12, 7, 11, 13, 1.110 + 8, 0, 4, 10, 7, 2, 7, 2, 2, 5, 1.111 + 3, 4, 7, 3, 3, 14, 14, 5, 9, 13, 1.112 + 3, 14, 3, 6, 3, 0, 11, 8, 13, 1, 1.113 + 13, 1, 12, 0, 10, 9, 7, 6, 2, 8, 1.114 + 5, 2, 13, 7, 1, 13, 14, 7, 6, 7, 1.115 + 9, 6, 10, 11, 7, 8, 7, 5, 14, 8, 1.116 + 4, 4, 0, 8, 7, 10, 0, 8, 14, 11, 1.117 + 3, 12, 5, 7, 14, 3, 14, 5, 2, 6, 1.118 + 11, 12, 12, 8, 0, 11, 13, 1, 2, 0, 1.119 + 5, 10, 14, 7, 8, 0, 4, 11, 0, 8, 1.120 + 0, 3, 10, 5, 8, 0, 11, 6, 7, 8, 1.121 + 10, 7, 13, 9, 2, 5, 1, 5, 10, 2, 1.122 + 4, 3, 5, 6, 10, 8, 9, 4, 11, 14, 1.123 + 3, 8, 3, 7, 8, 5, 11, 4, 12, 3, 1.124 + 11, 9, 14, 8, 14, 13, 4, 3, 1, 2, 1.125 + 14, 6, 5, 4, 4, 11, 4, 6, 2, 1, 1.126 + 5, 8, 8, 12, 13, 5, 14, 10, 12, 13, 1.127 + 0, 9, 5, 5, 11, 10, 13, 9, 10, 13, 1.128 +}; 1.129 + 1.130 +extern void vp8_blit_text(const char *msg, unsigned char *address, const int pitch); 1.131 +extern void vp8_blit_line(int x0, int x1, int y0, int y1, unsigned char *image, const int pitch); 1.132 +/*********************************************************************************************************** 1.133 + */ 1.134 +void vp8_post_proc_down_and_across_mb_row_c 1.135 +( 1.136 + unsigned char *src_ptr, 1.137 + unsigned char *dst_ptr, 1.138 + int src_pixels_per_line, 1.139 + int dst_pixels_per_line, 1.140 + int cols, 1.141 + unsigned char *f, 1.142 + int size 1.143 +) 1.144 +{ 1.145 + unsigned char *p_src, *p_dst; 1.146 + int row; 1.147 + int col; 1.148 + unsigned char v; 1.149 + unsigned char d[4]; 1.150 + 1.151 + for (row = 0; row < size; row++) 1.152 + { 1.153 + /* post_proc_down for one row */ 1.154 + p_src = src_ptr; 1.155 + p_dst = dst_ptr; 1.156 + 1.157 + for (col = 0; col < cols; col++) 1.158 + { 1.159 + unsigned char p_above2 = p_src[col - 2 * src_pixels_per_line]; 1.160 + unsigned char p_above1 = p_src[col - src_pixels_per_line]; 1.161 + unsigned char p_below1 = p_src[col + src_pixels_per_line]; 1.162 + unsigned char p_below2 = p_src[col + 2 * src_pixels_per_line]; 1.163 + 1.164 + v = p_src[col]; 1.165 + 1.166 + if ((abs(v - p_above2) < f[col]) && (abs(v - p_above1) < f[col]) 1.167 + && (abs(v - p_below1) < f[col]) && (abs(v - p_below2) < f[col])) 1.168 + { 1.169 + unsigned char k1, k2, k3; 1.170 + k1 = (p_above2 + p_above1 + 1) >> 1; 1.171 + k2 = (p_below2 + p_below1 + 1) >> 1; 1.172 + k3 = (k1 + k2 + 1) >> 1; 1.173 + v = (k3 + v + 1) >> 1; 1.174 + } 1.175 + 1.176 + p_dst[col] = v; 1.177 + } 1.178 + 1.179 + /* now post_proc_across */ 1.180 + p_src = dst_ptr; 1.181 + p_dst = dst_ptr; 1.182 + 1.183 + p_src[-2] = p_src[-1] = p_src[0]; 1.184 + p_src[cols] = p_src[cols + 1] = p_src[cols - 1]; 1.185 + 1.186 + for (col = 0; col < cols; col++) 1.187 + { 1.188 + v = p_src[col]; 1.189 + 1.190 + if ((abs(v - p_src[col - 2]) < f[col]) 1.191 + && (abs(v - p_src[col - 1]) < f[col]) 1.192 + && (abs(v - p_src[col + 1]) < f[col]) 1.193 + && (abs(v - p_src[col + 2]) < f[col])) 1.194 + { 1.195 + unsigned char k1, k2, k3; 1.196 + k1 = (p_src[col - 2] + p_src[col - 1] + 1) >> 1; 1.197 + k2 = (p_src[col + 2] + p_src[col + 1] + 1) >> 1; 1.198 + k3 = (k1 + k2 + 1) >> 1; 1.199 + v = (k3 + v + 1) >> 1; 1.200 + } 1.201 + 1.202 + d[col & 3] = v; 1.203 + 1.204 + if (col >= 2) 1.205 + p_dst[col - 2] = d[(col - 2) & 3]; 1.206 + } 1.207 + 1.208 + /* handle the last two pixels */ 1.209 + p_dst[col - 2] = d[(col - 2) & 3]; 1.210 + p_dst[col - 1] = d[(col - 1) & 3]; 1.211 + 1.212 + /* next row */ 1.213 + src_ptr += src_pixels_per_line; 1.214 + dst_ptr += dst_pixels_per_line; 1.215 + } 1.216 +} 1.217 + 1.218 +static int q2mbl(int x) 1.219 +{ 1.220 + if (x < 20) x = 20; 1.221 + 1.222 + x = 50 + (x - 50) * 10 / 8; 1.223 + return x * x / 3; 1.224 +} 1.225 +void vp8_mbpost_proc_across_ip_c(unsigned char *src, int pitch, int rows, int cols, int flimit) 1.226 +{ 1.227 + int r, c, i; 1.228 + 1.229 + unsigned char *s = src; 1.230 + unsigned char d[16]; 1.231 + 1.232 + for (r = 0; r < rows; r++) 1.233 + { 1.234 + int sumsq = 0; 1.235 + int sum = 0; 1.236 + 1.237 + for (i = -8; i<0; i++) 1.238 + s[i]=s[0]; 1.239 + 1.240 + /* 17 avoids valgrind warning - we buffer values in c in d 1.241 + * and only write them when we've read 8 ahead... 1.242 + */ 1.243 + for (i = cols; i<cols+17; i++) 1.244 + s[i]=s[cols-1]; 1.245 + 1.246 + for (i = -8; i <= 6; i++) 1.247 + { 1.248 + sumsq += s[i] * s[i]; 1.249 + sum += s[i]; 1.250 + d[i+8] = 0; 1.251 + } 1.252 + 1.253 + for (c = 0; c < cols + 8; c++) 1.254 + { 1.255 + int x = s[c+7] - s[c-8]; 1.256 + int y = s[c+7] + s[c-8]; 1.257 + 1.258 + sum += x; 1.259 + sumsq += x * y; 1.260 + 1.261 + d[c&15] = s[c]; 1.262 + 1.263 + if (sumsq * 15 - sum * sum < flimit) 1.264 + { 1.265 + d[c&15] = (8 + sum + s[c]) >> 4; 1.266 + } 1.267 + 1.268 + s[c-8] = d[(c-8)&15]; 1.269 + } 1.270 + 1.271 + s += pitch; 1.272 + } 1.273 +} 1.274 + 1.275 + 1.276 +void vp8_mbpost_proc_down_c(unsigned char *dst, int pitch, int rows, int cols, int flimit) 1.277 +{ 1.278 + int r, c, i; 1.279 + const short *rv3 = &vp8_rv[63&rand()]; 1.280 + 1.281 + for (c = 0; c < cols; c++ ) 1.282 + { 1.283 + unsigned char *s = &dst[c]; 1.284 + int sumsq = 0; 1.285 + int sum = 0; 1.286 + unsigned char d[16]; 1.287 + const short *rv2 = rv3 + ((c * 17) & 127); 1.288 + 1.289 + for (i = -8; i < 0; i++) 1.290 + s[i*pitch]=s[0]; 1.291 + 1.292 + /* 17 avoids valgrind warning - we buffer values in c in d 1.293 + * and only write them when we've read 8 ahead... 1.294 + */ 1.295 + for (i = rows; i < rows+17; i++) 1.296 + s[i*pitch]=s[(rows-1)*pitch]; 1.297 + 1.298 + for (i = -8; i <= 6; i++) 1.299 + { 1.300 + sumsq += s[i*pitch] * s[i*pitch]; 1.301 + sum += s[i*pitch]; 1.302 + } 1.303 + 1.304 + for (r = 0; r < rows + 8; r++) 1.305 + { 1.306 + sumsq += s[7*pitch] * s[ 7*pitch] - s[-8*pitch] * s[-8*pitch]; 1.307 + sum += s[7*pitch] - s[-8*pitch]; 1.308 + d[r&15] = s[0]; 1.309 + 1.310 + if (sumsq * 15 - sum * sum < flimit) 1.311 + { 1.312 + d[r&15] = (rv2[r&127] + sum + s[0]) >> 4; 1.313 + } 1.314 + 1.315 + s[-8*pitch] = d[(r-8)&15]; 1.316 + s += pitch; 1.317 + } 1.318 + } 1.319 +} 1.320 + 1.321 +static void vp8_de_mblock(YV12_BUFFER_CONFIG *post, 1.322 + int q) 1.323 +{ 1.324 + vp8_mbpost_proc_across_ip(post->y_buffer, post->y_stride, post->y_height, 1.325 + post->y_width, q2mbl(q)); 1.326 + vp8_mbpost_proc_down(post->y_buffer, post->y_stride, post->y_height, 1.327 + post->y_width, q2mbl(q)); 1.328 +} 1.329 + 1.330 +void vp8_deblock(VP8_COMMON *cm, 1.331 + YV12_BUFFER_CONFIG *source, 1.332 + YV12_BUFFER_CONFIG *post, 1.333 + int q, 1.334 + int low_var_thresh, 1.335 + int flag) 1.336 +{ 1.337 + double level = 6.0e-05 * q * q * q - .0067 * q * q + .306 * q + .0065; 1.338 + int ppl = (int)(level + .5); 1.339 + 1.340 + const MODE_INFO *mode_info_context = cm->show_frame_mi; 1.341 + int mbr, mbc; 1.342 + 1.343 + /* The pixel thresholds are adjusted according to if or not the macroblock 1.344 + * is a skipped block. */ 1.345 + unsigned char *ylimits = cm->pp_limits_buffer; 1.346 + unsigned char *uvlimits = cm->pp_limits_buffer + 16 * cm->mb_cols; 1.347 + (void) low_var_thresh; 1.348 + (void) flag; 1.349 + 1.350 + if (ppl > 0) 1.351 + { 1.352 + for (mbr = 0; mbr < cm->mb_rows; mbr++) 1.353 + { 1.354 + unsigned char *ylptr = ylimits; 1.355 + unsigned char *uvlptr = uvlimits; 1.356 + for (mbc = 0; mbc < cm->mb_cols; mbc++) 1.357 + { 1.358 + unsigned char mb_ppl; 1.359 + 1.360 + if (mode_info_context->mbmi.mb_skip_coeff) 1.361 + mb_ppl = (unsigned char)ppl >> 1; 1.362 + else 1.363 + mb_ppl = (unsigned char)ppl; 1.364 + 1.365 + vpx_memset(ylptr, mb_ppl, 16); 1.366 + vpx_memset(uvlptr, mb_ppl, 8); 1.367 + 1.368 + ylptr += 16; 1.369 + uvlptr += 8; 1.370 + mode_info_context++; 1.371 + } 1.372 + mode_info_context++; 1.373 + 1.374 + vp8_post_proc_down_and_across_mb_row( 1.375 + source->y_buffer + 16 * mbr * source->y_stride, 1.376 + post->y_buffer + 16 * mbr * post->y_stride, source->y_stride, 1.377 + post->y_stride, source->y_width, ylimits, 16); 1.378 + 1.379 + vp8_post_proc_down_and_across_mb_row( 1.380 + source->u_buffer + 8 * mbr * source->uv_stride, 1.381 + post->u_buffer + 8 * mbr * post->uv_stride, source->uv_stride, 1.382 + post->uv_stride, source->uv_width, uvlimits, 8); 1.383 + vp8_post_proc_down_and_across_mb_row( 1.384 + source->v_buffer + 8 * mbr * source->uv_stride, 1.385 + post->v_buffer + 8 * mbr * post->uv_stride, source->uv_stride, 1.386 + post->uv_stride, source->uv_width, uvlimits, 8); 1.387 + } 1.388 + } else 1.389 + { 1.390 + vp8_yv12_copy_frame(source, post); 1.391 + } 1.392 +} 1.393 + 1.394 +#if !(CONFIG_TEMPORAL_DENOISING) 1.395 +void vp8_de_noise(VP8_COMMON *cm, 1.396 + YV12_BUFFER_CONFIG *source, 1.397 + YV12_BUFFER_CONFIG *post, 1.398 + int q, 1.399 + int low_var_thresh, 1.400 + int flag) 1.401 +{ 1.402 + double level = 6.0e-05 * q * q * q - .0067 * q * q + .306 * q + .0065; 1.403 + int ppl = (int)(level + .5); 1.404 + int mb_rows = source->y_width >> 4; 1.405 + int mb_cols = source->y_height >> 4; 1.406 + unsigned char *limits = cm->pp_limits_buffer;; 1.407 + int mbr, mbc; 1.408 + (void) post; 1.409 + (void) low_var_thresh; 1.410 + (void) flag; 1.411 + 1.412 + vpx_memset(limits, (unsigned char)ppl, 16 * mb_cols); 1.413 + 1.414 + /* TODO: The original code don't filter the 2 outer rows and columns. */ 1.415 + for (mbr = 0; mbr < mb_rows; mbr++) 1.416 + { 1.417 + vp8_post_proc_down_and_across_mb_row( 1.418 + source->y_buffer + 16 * mbr * source->y_stride, 1.419 + source->y_buffer + 16 * mbr * source->y_stride, 1.420 + source->y_stride, source->y_stride, source->y_width, limits, 16); 1.421 + 1.422 + vp8_post_proc_down_and_across_mb_row( 1.423 + source->u_buffer + 8 * mbr * source->uv_stride, 1.424 + source->u_buffer + 8 * mbr * source->uv_stride, 1.425 + source->uv_stride, source->uv_stride, source->uv_width, limits, 8); 1.426 + vp8_post_proc_down_and_across_mb_row( 1.427 + source->v_buffer + 8 * mbr * source->uv_stride, 1.428 + source->v_buffer + 8 * mbr * source->uv_stride, 1.429 + source->uv_stride, source->uv_stride, source->uv_width, limits, 8); 1.430 + } 1.431 +} 1.432 +#endif 1.433 + 1.434 +double vp8_gaussian(double sigma, double mu, double x) 1.435 +{ 1.436 + return 1 / (sigma * sqrt(2.0 * 3.14159265)) * 1.437 + (exp(-(x - mu) * (x - mu) / (2 * sigma * sigma))); 1.438 +} 1.439 + 1.440 +static void fillrd(struct postproc_state *state, int q, int a) 1.441 +{ 1.442 + char char_dist[300]; 1.443 + 1.444 + double sigma; 1.445 + int i; 1.446 + 1.447 + vp8_clear_system_state(); 1.448 + 1.449 + 1.450 + sigma = a + .5 + .6 * (63 - q) / 63.0; 1.451 + 1.452 + /* set up a lookup table of 256 entries that matches 1.453 + * a gaussian distribution with sigma determined by q. 1.454 + */ 1.455 + { 1.456 + int next, j; 1.457 + 1.458 + next = 0; 1.459 + 1.460 + for (i = -32; i < 32; i++) 1.461 + { 1.462 + const int v = (int)(.5 + 256 * vp8_gaussian(sigma, 0, i)); 1.463 + 1.464 + if (v) 1.465 + { 1.466 + for (j = 0; j < v; j++) 1.467 + { 1.468 + char_dist[next+j] = (char) i; 1.469 + } 1.470 + 1.471 + next = next + j; 1.472 + } 1.473 + 1.474 + } 1.475 + 1.476 + for (; next < 256; next++) 1.477 + char_dist[next] = 0; 1.478 + 1.479 + } 1.480 + 1.481 + for (i = 0; i < 3072; i++) 1.482 + { 1.483 + state->noise[i] = char_dist[rand() & 0xff]; 1.484 + } 1.485 + 1.486 + for (i = 0; i < 16; i++) 1.487 + { 1.488 + state->blackclamp[i] = -char_dist[0]; 1.489 + state->whiteclamp[i] = -char_dist[0]; 1.490 + state->bothclamp[i] = -2 * char_dist[0]; 1.491 + } 1.492 + 1.493 + state->last_q = q; 1.494 + state->last_noise = a; 1.495 +} 1.496 + 1.497 +/**************************************************************************** 1.498 + * 1.499 + * ROUTINE : plane_add_noise_c 1.500 + * 1.501 + * INPUTS : unsigned char *Start starting address of buffer to add gaussian 1.502 + * noise to 1.503 + * unsigned int Width width of plane 1.504 + * unsigned int Height height of plane 1.505 + * int Pitch distance between subsequent lines of frame 1.506 + * int q quantizer used to determine amount of noise 1.507 + * to add 1.508 + * 1.509 + * OUTPUTS : None. 1.510 + * 1.511 + * RETURNS : void. 1.512 + * 1.513 + * FUNCTION : adds gaussian noise to a plane of pixels 1.514 + * 1.515 + * SPECIAL NOTES : None. 1.516 + * 1.517 + ****************************************************************************/ 1.518 +void vp8_plane_add_noise_c(unsigned char *Start, char *noise, 1.519 + char blackclamp[16], 1.520 + char whiteclamp[16], 1.521 + char bothclamp[16], 1.522 + unsigned int Width, unsigned int Height, int Pitch) 1.523 +{ 1.524 + unsigned int i, j; 1.525 + 1.526 + for (i = 0; i < Height; i++) 1.527 + { 1.528 + unsigned char *Pos = Start + i * Pitch; 1.529 + char *Ref = (char *)(noise + (rand() & 0xff)); 1.530 + 1.531 + for (j = 0; j < Width; j++) 1.532 + { 1.533 + if (Pos[j] < blackclamp[0]) 1.534 + Pos[j] = blackclamp[0]; 1.535 + 1.536 + if (Pos[j] > 255 + whiteclamp[0]) 1.537 + Pos[j] = 255 + whiteclamp[0]; 1.538 + 1.539 + Pos[j] += Ref[j]; 1.540 + } 1.541 + } 1.542 +} 1.543 + 1.544 +/* Blend the macro block with a solid colored square. Leave the 1.545 + * edges unblended to give distinction to macro blocks in areas 1.546 + * filled with the same color block. 1.547 + */ 1.548 +void vp8_blend_mb_inner_c (unsigned char *y, unsigned char *u, unsigned char *v, 1.549 + int y_1, int u_1, int v_1, int alpha, int stride) 1.550 +{ 1.551 + int i, j; 1.552 + int y1_const = y_1*((1<<16)-alpha); 1.553 + int u1_const = u_1*((1<<16)-alpha); 1.554 + int v1_const = v_1*((1<<16)-alpha); 1.555 + 1.556 + y += 2*stride + 2; 1.557 + for (i = 0; i < 12; i++) 1.558 + { 1.559 + for (j = 0; j < 12; j++) 1.560 + { 1.561 + y[j] = (y[j]*alpha + y1_const)>>16; 1.562 + } 1.563 + y += stride; 1.564 + } 1.565 + 1.566 + stride >>= 1; 1.567 + 1.568 + u += stride + 1; 1.569 + v += stride + 1; 1.570 + 1.571 + for (i = 0; i < 6; i++) 1.572 + { 1.573 + for (j = 0; j < 6; j++) 1.574 + { 1.575 + u[j] = (u[j]*alpha + u1_const)>>16; 1.576 + v[j] = (v[j]*alpha + v1_const)>>16; 1.577 + } 1.578 + u += stride; 1.579 + v += stride; 1.580 + } 1.581 +} 1.582 + 1.583 +/* Blend only the edge of the macro block. Leave center 1.584 + * unblended to allow for other visualizations to be layered. 1.585 + */ 1.586 +void vp8_blend_mb_outer_c (unsigned char *y, unsigned char *u, unsigned char *v, 1.587 + int y_1, int u_1, int v_1, int alpha, int stride) 1.588 +{ 1.589 + int i, j; 1.590 + int y1_const = y_1*((1<<16)-alpha); 1.591 + int u1_const = u_1*((1<<16)-alpha); 1.592 + int v1_const = v_1*((1<<16)-alpha); 1.593 + 1.594 + for (i = 0; i < 2; i++) 1.595 + { 1.596 + for (j = 0; j < 16; j++) 1.597 + { 1.598 + y[j] = (y[j]*alpha + y1_const)>>16; 1.599 + } 1.600 + y += stride; 1.601 + } 1.602 + 1.603 + for (i = 0; i < 12; i++) 1.604 + { 1.605 + y[0] = (y[0]*alpha + y1_const)>>16; 1.606 + y[1] = (y[1]*alpha + y1_const)>>16; 1.607 + y[14] = (y[14]*alpha + y1_const)>>16; 1.608 + y[15] = (y[15]*alpha + y1_const)>>16; 1.609 + y += stride; 1.610 + } 1.611 + 1.612 + for (i = 0; i < 2; i++) 1.613 + { 1.614 + for (j = 0; j < 16; j++) 1.615 + { 1.616 + y[j] = (y[j]*alpha + y1_const)>>16; 1.617 + } 1.618 + y += stride; 1.619 + } 1.620 + 1.621 + stride >>= 1; 1.622 + 1.623 + for (j = 0; j < 8; j++) 1.624 + { 1.625 + u[j] = (u[j]*alpha + u1_const)>>16; 1.626 + v[j] = (v[j]*alpha + v1_const)>>16; 1.627 + } 1.628 + u += stride; 1.629 + v += stride; 1.630 + 1.631 + for (i = 0; i < 6; i++) 1.632 + { 1.633 + u[0] = (u[0]*alpha + u1_const)>>16; 1.634 + v[0] = (v[0]*alpha + v1_const)>>16; 1.635 + 1.636 + u[7] = (u[7]*alpha + u1_const)>>16; 1.637 + v[7] = (v[7]*alpha + v1_const)>>16; 1.638 + 1.639 + u += stride; 1.640 + v += stride; 1.641 + } 1.642 + 1.643 + for (j = 0; j < 8; j++) 1.644 + { 1.645 + u[j] = (u[j]*alpha + u1_const)>>16; 1.646 + v[j] = (v[j]*alpha + v1_const)>>16; 1.647 + } 1.648 +} 1.649 + 1.650 +void vp8_blend_b_c (unsigned char *y, unsigned char *u, unsigned char *v, 1.651 + int y_1, int u_1, int v_1, int alpha, int stride) 1.652 +{ 1.653 + int i, j; 1.654 + int y1_const = y_1*((1<<16)-alpha); 1.655 + int u1_const = u_1*((1<<16)-alpha); 1.656 + int v1_const = v_1*((1<<16)-alpha); 1.657 + 1.658 + for (i = 0; i < 4; i++) 1.659 + { 1.660 + for (j = 0; j < 4; j++) 1.661 + { 1.662 + y[j] = (y[j]*alpha + y1_const)>>16; 1.663 + } 1.664 + y += stride; 1.665 + } 1.666 + 1.667 + stride >>= 1; 1.668 + 1.669 + for (i = 0; i < 2; i++) 1.670 + { 1.671 + for (j = 0; j < 2; j++) 1.672 + { 1.673 + u[j] = (u[j]*alpha + u1_const)>>16; 1.674 + v[j] = (v[j]*alpha + v1_const)>>16; 1.675 + } 1.676 + u += stride; 1.677 + v += stride; 1.678 + } 1.679 +} 1.680 + 1.681 +static void constrain_line (int x_0, int *x_1, int y_0, int *y_1, int width, int height) 1.682 +{ 1.683 + int dx; 1.684 + int dy; 1.685 + 1.686 + if (*x_1 > width) 1.687 + { 1.688 + dx = *x_1 - x_0; 1.689 + dy = *y_1 - y_0; 1.690 + 1.691 + *x_1 = width; 1.692 + if (dx) 1.693 + *y_1 = ((width-x_0)*dy)/dx + y_0; 1.694 + } 1.695 + if (*x_1 < 0) 1.696 + { 1.697 + dx = *x_1 - x_0; 1.698 + dy = *y_1 - y_0; 1.699 + 1.700 + *x_1 = 0; 1.701 + if (dx) 1.702 + *y_1 = ((0-x_0)*dy)/dx + y_0; 1.703 + } 1.704 + if (*y_1 > height) 1.705 + { 1.706 + dx = *x_1 - x_0; 1.707 + dy = *y_1 - y_0; 1.708 + 1.709 + *y_1 = height; 1.710 + if (dy) 1.711 + *x_1 = ((height-y_0)*dx)/dy + x_0; 1.712 + } 1.713 + if (*y_1 < 0) 1.714 + { 1.715 + dx = *x_1 - x_0; 1.716 + dy = *y_1 - y_0; 1.717 + 1.718 + *y_1 = 0; 1.719 + if (dy) 1.720 + *x_1 = ((0-y_0)*dx)/dy + x_0; 1.721 + } 1.722 +} 1.723 + 1.724 +#if CONFIG_POSTPROC 1.725 +int vp8_post_proc_frame(VP8_COMMON *oci, YV12_BUFFER_CONFIG *dest, vp8_ppflags_t *ppflags) 1.726 +{ 1.727 + int q = oci->filter_level * 10 / 6; 1.728 + int flags = ppflags->post_proc_flag; 1.729 + int deblock_level = ppflags->deblocking_level; 1.730 + int noise_level = ppflags->noise_level; 1.731 + 1.732 + if (!oci->frame_to_show) 1.733 + return -1; 1.734 + 1.735 + if (q > 63) 1.736 + q = 63; 1.737 + 1.738 + if (!flags) 1.739 + { 1.740 + *dest = *oci->frame_to_show; 1.741 + 1.742 + /* handle problem with extending borders */ 1.743 + dest->y_width = oci->Width; 1.744 + dest->y_height = oci->Height; 1.745 + dest->uv_height = dest->y_height / 2; 1.746 + oci->postproc_state.last_base_qindex = oci->base_qindex; 1.747 + oci->postproc_state.last_frame_valid = 1; 1.748 + return 0; 1.749 + } 1.750 + 1.751 + /* Allocate post_proc_buffer_int if needed */ 1.752 + if ((flags & VP8D_MFQE) && !oci->post_proc_buffer_int_used) 1.753 + { 1.754 + if ((flags & VP8D_DEBLOCK) || (flags & VP8D_DEMACROBLOCK)) 1.755 + { 1.756 + int width = (oci->Width + 15) & ~15; 1.757 + int height = (oci->Height + 15) & ~15; 1.758 + 1.759 + if (vp8_yv12_alloc_frame_buffer(&oci->post_proc_buffer_int, 1.760 + width, height, VP8BORDERINPIXELS)) 1.761 + vpx_internal_error(&oci->error, VPX_CODEC_MEM_ERROR, 1.762 + "Failed to allocate MFQE framebuffer"); 1.763 + 1.764 + oci->post_proc_buffer_int_used = 1; 1.765 + 1.766 + /* insure that postproc is set to all 0's so that post proc 1.767 + * doesn't pull random data in from edge 1.768 + */ 1.769 + vpx_memset((&oci->post_proc_buffer_int)->buffer_alloc,128,(&oci->post_proc_buffer)->frame_size); 1.770 + 1.771 + } 1.772 + } 1.773 + 1.774 + vp8_clear_system_state(); 1.775 + 1.776 + if ((flags & VP8D_MFQE) && 1.777 + oci->postproc_state.last_frame_valid && 1.778 + oci->current_video_frame >= 2 && 1.779 + oci->postproc_state.last_base_qindex < 60 && 1.780 + oci->base_qindex - oci->postproc_state.last_base_qindex >= 20) 1.781 + { 1.782 + vp8_multiframe_quality_enhance(oci); 1.783 + if (((flags & VP8D_DEBLOCK) || (flags & VP8D_DEMACROBLOCK)) && 1.784 + oci->post_proc_buffer_int_used) 1.785 + { 1.786 + vp8_yv12_copy_frame(&oci->post_proc_buffer, &oci->post_proc_buffer_int); 1.787 + if (flags & VP8D_DEMACROBLOCK) 1.788 + { 1.789 + vp8_deblock(oci, &oci->post_proc_buffer_int, &oci->post_proc_buffer, 1.790 + q + (deblock_level - 5) * 10, 1, 0); 1.791 + vp8_de_mblock(&oci->post_proc_buffer, 1.792 + q + (deblock_level - 5) * 10); 1.793 + } 1.794 + else if (flags & VP8D_DEBLOCK) 1.795 + { 1.796 + vp8_deblock(oci, &oci->post_proc_buffer_int, &oci->post_proc_buffer, 1.797 + q, 1, 0); 1.798 + } 1.799 + } 1.800 + /* Move partially towards the base q of the previous frame */ 1.801 + oci->postproc_state.last_base_qindex = (3*oci->postproc_state.last_base_qindex + oci->base_qindex)>>2; 1.802 + } 1.803 + else if (flags & VP8D_DEMACROBLOCK) 1.804 + { 1.805 + vp8_deblock(oci, oci->frame_to_show, &oci->post_proc_buffer, 1.806 + q + (deblock_level - 5) * 10, 1, 0); 1.807 + vp8_de_mblock(&oci->post_proc_buffer, q + (deblock_level - 5) * 10); 1.808 + 1.809 + oci->postproc_state.last_base_qindex = oci->base_qindex; 1.810 + } 1.811 + else if (flags & VP8D_DEBLOCK) 1.812 + { 1.813 + vp8_deblock(oci, oci->frame_to_show, &oci->post_proc_buffer, 1.814 + q, 1, 0); 1.815 + oci->postproc_state.last_base_qindex = oci->base_qindex; 1.816 + } 1.817 + else 1.818 + { 1.819 + vp8_yv12_copy_frame(oci->frame_to_show, &oci->post_proc_buffer); 1.820 + oci->postproc_state.last_base_qindex = oci->base_qindex; 1.821 + } 1.822 + oci->postproc_state.last_frame_valid = 1; 1.823 + 1.824 + if (flags & VP8D_ADDNOISE) 1.825 + { 1.826 + if (oci->postproc_state.last_q != q 1.827 + || oci->postproc_state.last_noise != noise_level) 1.828 + { 1.829 + fillrd(&oci->postproc_state, 63 - q, noise_level); 1.830 + } 1.831 + 1.832 + vp8_plane_add_noise 1.833 + (oci->post_proc_buffer.y_buffer, 1.834 + oci->postproc_state.noise, 1.835 + oci->postproc_state.blackclamp, 1.836 + oci->postproc_state.whiteclamp, 1.837 + oci->postproc_state.bothclamp, 1.838 + oci->post_proc_buffer.y_width, oci->post_proc_buffer.y_height, 1.839 + oci->post_proc_buffer.y_stride); 1.840 + } 1.841 + 1.842 +#if CONFIG_POSTPROC_VISUALIZER 1.843 + if (flags & VP8D_DEBUG_TXT_FRAME_INFO) 1.844 + { 1.845 + char message[512]; 1.846 + sprintf(message, "F%1dG%1dQ%3dF%3dP%d_s%dx%d", 1.847 + (oci->frame_type == KEY_FRAME), 1.848 + oci->refresh_golden_frame, 1.849 + oci->base_qindex, 1.850 + oci->filter_level, 1.851 + flags, 1.852 + oci->mb_cols, oci->mb_rows); 1.853 + vp8_blit_text(message, oci->post_proc_buffer.y_buffer, oci->post_proc_buffer.y_stride); 1.854 + } 1.855 + 1.856 + if (flags & VP8D_DEBUG_TXT_MBLK_MODES) 1.857 + { 1.858 + int i, j; 1.859 + unsigned char *y_ptr; 1.860 + YV12_BUFFER_CONFIG *post = &oci->post_proc_buffer; 1.861 + int mb_rows = post->y_height >> 4; 1.862 + int mb_cols = post->y_width >> 4; 1.863 + int mb_index = 0; 1.864 + MODE_INFO *mi = oci->mi; 1.865 + 1.866 + y_ptr = post->y_buffer + 4 * post->y_stride + 4; 1.867 + 1.868 + /* vp8_filter each macro block */ 1.869 + for (i = 0; i < mb_rows; i++) 1.870 + { 1.871 + for (j = 0; j < mb_cols; j++) 1.872 + { 1.873 + char zz[4]; 1.874 + 1.875 + sprintf(zz, "%c", mi[mb_index].mbmi.mode + 'a'); 1.876 + 1.877 + vp8_blit_text(zz, y_ptr, post->y_stride); 1.878 + mb_index ++; 1.879 + y_ptr += 16; 1.880 + } 1.881 + 1.882 + mb_index ++; /* border */ 1.883 + y_ptr += post->y_stride * 16 - post->y_width; 1.884 + 1.885 + } 1.886 + } 1.887 + 1.888 + if (flags & VP8D_DEBUG_TXT_DC_DIFF) 1.889 + { 1.890 + int i, j; 1.891 + unsigned char *y_ptr; 1.892 + YV12_BUFFER_CONFIG *post = &oci->post_proc_buffer; 1.893 + int mb_rows = post->y_height >> 4; 1.894 + int mb_cols = post->y_width >> 4; 1.895 + int mb_index = 0; 1.896 + MODE_INFO *mi = oci->mi; 1.897 + 1.898 + y_ptr = post->y_buffer + 4 * post->y_stride + 4; 1.899 + 1.900 + /* vp8_filter each macro block */ 1.901 + for (i = 0; i < mb_rows; i++) 1.902 + { 1.903 + for (j = 0; j < mb_cols; j++) 1.904 + { 1.905 + char zz[4]; 1.906 + int dc_diff = !(mi[mb_index].mbmi.mode != B_PRED && 1.907 + mi[mb_index].mbmi.mode != SPLITMV && 1.908 + mi[mb_index].mbmi.mb_skip_coeff); 1.909 + 1.910 + if (oci->frame_type == KEY_FRAME) 1.911 + sprintf(zz, "a"); 1.912 + else 1.913 + sprintf(zz, "%c", dc_diff + '0'); 1.914 + 1.915 + vp8_blit_text(zz, y_ptr, post->y_stride); 1.916 + mb_index ++; 1.917 + y_ptr += 16; 1.918 + } 1.919 + 1.920 + mb_index ++; /* border */ 1.921 + y_ptr += post->y_stride * 16 - post->y_width; 1.922 + 1.923 + } 1.924 + } 1.925 + 1.926 + if (flags & VP8D_DEBUG_TXT_RATE_INFO) 1.927 + { 1.928 + char message[512]; 1.929 + sprintf(message, "Bitrate: %10.2f framerate: %10.2f ", oci->bitrate, oci->framerate); 1.930 + vp8_blit_text(message, oci->post_proc_buffer.y_buffer, oci->post_proc_buffer.y_stride); 1.931 + } 1.932 + 1.933 + /* Draw motion vectors */ 1.934 + if ((flags & VP8D_DEBUG_DRAW_MV) && ppflags->display_mv_flag) 1.935 + { 1.936 + YV12_BUFFER_CONFIG *post = &oci->post_proc_buffer; 1.937 + int width = post->y_width; 1.938 + int height = post->y_height; 1.939 + unsigned char *y_buffer = oci->post_proc_buffer.y_buffer; 1.940 + int y_stride = oci->post_proc_buffer.y_stride; 1.941 + MODE_INFO *mi = oci->mi; 1.942 + int x0, y0; 1.943 + 1.944 + for (y0 = 0; y0 < height; y0 += 16) 1.945 + { 1.946 + for (x0 = 0; x0 < width; x0 += 16) 1.947 + { 1.948 + int x1, y1; 1.949 + 1.950 + if (!(ppflags->display_mv_flag & (1<<mi->mbmi.mode))) 1.951 + { 1.952 + mi++; 1.953 + continue; 1.954 + } 1.955 + 1.956 + if (mi->mbmi.mode == SPLITMV) 1.957 + { 1.958 + switch (mi->mbmi.partitioning) 1.959 + { 1.960 + case 0 : /* mv_top_bottom */ 1.961 + { 1.962 + union b_mode_info *bmi = &mi->bmi[0]; 1.963 + MV *mv = &bmi->mv.as_mv; 1.964 + 1.965 + x1 = x0 + 8 + (mv->col >> 3); 1.966 + y1 = y0 + 4 + (mv->row >> 3); 1.967 + 1.968 + constrain_line (x0+8, &x1, y0+4, &y1, width, height); 1.969 + vp8_blit_line (x0+8, x1, y0+4, y1, y_buffer, y_stride); 1.970 + 1.971 + bmi = &mi->bmi[8]; 1.972 + 1.973 + x1 = x0 + 8 + (mv->col >> 3); 1.974 + y1 = y0 +12 + (mv->row >> 3); 1.975 + 1.976 + constrain_line (x0+8, &x1, y0+12, &y1, width, height); 1.977 + vp8_blit_line (x0+8, x1, y0+12, y1, y_buffer, y_stride); 1.978 + 1.979 + break; 1.980 + } 1.981 + case 1 : /* mv_left_right */ 1.982 + { 1.983 + union b_mode_info *bmi = &mi->bmi[0]; 1.984 + MV *mv = &bmi->mv.as_mv; 1.985 + 1.986 + x1 = x0 + 4 + (mv->col >> 3); 1.987 + y1 = y0 + 8 + (mv->row >> 3); 1.988 + 1.989 + constrain_line (x0+4, &x1, y0+8, &y1, width, height); 1.990 + vp8_blit_line (x0+4, x1, y0+8, y1, y_buffer, y_stride); 1.991 + 1.992 + bmi = &mi->bmi[2]; 1.993 + 1.994 + x1 = x0 +12 + (mv->col >> 3); 1.995 + y1 = y0 + 8 + (mv->row >> 3); 1.996 + 1.997 + constrain_line (x0+12, &x1, y0+8, &y1, width, height); 1.998 + vp8_blit_line (x0+12, x1, y0+8, y1, y_buffer, y_stride); 1.999 + 1.1000 + break; 1.1001 + } 1.1002 + case 2 : /* mv_quarters */ 1.1003 + { 1.1004 + union b_mode_info *bmi = &mi->bmi[0]; 1.1005 + MV *mv = &bmi->mv.as_mv; 1.1006 + 1.1007 + x1 = x0 + 4 + (mv->col >> 3); 1.1008 + y1 = y0 + 4 + (mv->row >> 3); 1.1009 + 1.1010 + constrain_line (x0+4, &x1, y0+4, &y1, width, height); 1.1011 + vp8_blit_line (x0+4, x1, y0+4, y1, y_buffer, y_stride); 1.1012 + 1.1013 + bmi = &mi->bmi[2]; 1.1014 + 1.1015 + x1 = x0 +12 + (mv->col >> 3); 1.1016 + y1 = y0 + 4 + (mv->row >> 3); 1.1017 + 1.1018 + constrain_line (x0+12, &x1, y0+4, &y1, width, height); 1.1019 + vp8_blit_line (x0+12, x1, y0+4, y1, y_buffer, y_stride); 1.1020 + 1.1021 + bmi = &mi->bmi[8]; 1.1022 + 1.1023 + x1 = x0 + 4 + (mv->col >> 3); 1.1024 + y1 = y0 +12 + (mv->row >> 3); 1.1025 + 1.1026 + constrain_line (x0+4, &x1, y0+12, &y1, width, height); 1.1027 + vp8_blit_line (x0+4, x1, y0+12, y1, y_buffer, y_stride); 1.1028 + 1.1029 + bmi = &mi->bmi[10]; 1.1030 + 1.1031 + x1 = x0 +12 + (mv->col >> 3); 1.1032 + y1 = y0 +12 + (mv->row >> 3); 1.1033 + 1.1034 + constrain_line (x0+12, &x1, y0+12, &y1, width, height); 1.1035 + vp8_blit_line (x0+12, x1, y0+12, y1, y_buffer, y_stride); 1.1036 + break; 1.1037 + } 1.1038 + default : 1.1039 + { 1.1040 + union b_mode_info *bmi = mi->bmi; 1.1041 + int bx0, by0; 1.1042 + 1.1043 + for (by0 = y0; by0 < (y0+16); by0 += 4) 1.1044 + { 1.1045 + for (bx0 = x0; bx0 < (x0+16); bx0 += 4) 1.1046 + { 1.1047 + MV *mv = &bmi->mv.as_mv; 1.1048 + 1.1049 + x1 = bx0 + 2 + (mv->col >> 3); 1.1050 + y1 = by0 + 2 + (mv->row >> 3); 1.1051 + 1.1052 + constrain_line (bx0+2, &x1, by0+2, &y1, width, height); 1.1053 + vp8_blit_line (bx0+2, x1, by0+2, y1, y_buffer, y_stride); 1.1054 + 1.1055 + bmi++; 1.1056 + } 1.1057 + } 1.1058 + } 1.1059 + } 1.1060 + } 1.1061 + else if (mi->mbmi.mode >= NEARESTMV) 1.1062 + { 1.1063 + MV *mv = &mi->mbmi.mv.as_mv; 1.1064 + const int lx0 = x0 + 8; 1.1065 + const int ly0 = y0 + 8; 1.1066 + 1.1067 + x1 = lx0 + (mv->col >> 3); 1.1068 + y1 = ly0 + (mv->row >> 3); 1.1069 + 1.1070 + if (x1 != lx0 && y1 != ly0) 1.1071 + { 1.1072 + constrain_line (lx0, &x1, ly0-1, &y1, width, height); 1.1073 + vp8_blit_line (lx0, x1, ly0-1, y1, y_buffer, y_stride); 1.1074 + 1.1075 + constrain_line (lx0, &x1, ly0+1, &y1, width, height); 1.1076 + vp8_blit_line (lx0, x1, ly0+1, y1, y_buffer, y_stride); 1.1077 + } 1.1078 + else 1.1079 + vp8_blit_line (lx0, x1, ly0, y1, y_buffer, y_stride); 1.1080 + } 1.1081 + 1.1082 + mi++; 1.1083 + } 1.1084 + mi++; 1.1085 + } 1.1086 + } 1.1087 + 1.1088 + /* Color in block modes */ 1.1089 + if ((flags & VP8D_DEBUG_CLR_BLK_MODES) 1.1090 + && (ppflags->display_mb_modes_flag || ppflags->display_b_modes_flag)) 1.1091 + { 1.1092 + int y, x; 1.1093 + YV12_BUFFER_CONFIG *post = &oci->post_proc_buffer; 1.1094 + int width = post->y_width; 1.1095 + int height = post->y_height; 1.1096 + unsigned char *y_ptr = oci->post_proc_buffer.y_buffer; 1.1097 + unsigned char *u_ptr = oci->post_proc_buffer.u_buffer; 1.1098 + unsigned char *v_ptr = oci->post_proc_buffer.v_buffer; 1.1099 + int y_stride = oci->post_proc_buffer.y_stride; 1.1100 + MODE_INFO *mi = oci->mi; 1.1101 + 1.1102 + for (y = 0; y < height; y += 16) 1.1103 + { 1.1104 + for (x = 0; x < width; x += 16) 1.1105 + { 1.1106 + int Y = 0, U = 0, V = 0; 1.1107 + 1.1108 + if (mi->mbmi.mode == B_PRED && 1.1109 + ((ppflags->display_mb_modes_flag & B_PRED) || ppflags->display_b_modes_flag)) 1.1110 + { 1.1111 + int by, bx; 1.1112 + unsigned char *yl, *ul, *vl; 1.1113 + union b_mode_info *bmi = mi->bmi; 1.1114 + 1.1115 + yl = y_ptr + x; 1.1116 + ul = u_ptr + (x>>1); 1.1117 + vl = v_ptr + (x>>1); 1.1118 + 1.1119 + for (by = 0; by < 16; by += 4) 1.1120 + { 1.1121 + for (bx = 0; bx < 16; bx += 4) 1.1122 + { 1.1123 + if ((ppflags->display_b_modes_flag & (1<<mi->mbmi.mode)) 1.1124 + || (ppflags->display_mb_modes_flag & B_PRED)) 1.1125 + { 1.1126 + Y = B_PREDICTION_MODE_colors[bmi->as_mode][0]; 1.1127 + U = B_PREDICTION_MODE_colors[bmi->as_mode][1]; 1.1128 + V = B_PREDICTION_MODE_colors[bmi->as_mode][2]; 1.1129 + 1.1130 + vp8_blend_b 1.1131 + (yl+bx, ul+(bx>>1), vl+(bx>>1), Y, U, V, 0xc000, y_stride); 1.1132 + } 1.1133 + bmi++; 1.1134 + } 1.1135 + 1.1136 + yl += y_stride*4; 1.1137 + ul += y_stride*1; 1.1138 + vl += y_stride*1; 1.1139 + } 1.1140 + } 1.1141 + else if (ppflags->display_mb_modes_flag & (1<<mi->mbmi.mode)) 1.1142 + { 1.1143 + Y = MB_PREDICTION_MODE_colors[mi->mbmi.mode][0]; 1.1144 + U = MB_PREDICTION_MODE_colors[mi->mbmi.mode][1]; 1.1145 + V = MB_PREDICTION_MODE_colors[mi->mbmi.mode][2]; 1.1146 + 1.1147 + vp8_blend_mb_inner 1.1148 + (y_ptr+x, u_ptr+(x>>1), v_ptr+(x>>1), Y, U, V, 0xc000, y_stride); 1.1149 + } 1.1150 + 1.1151 + mi++; 1.1152 + } 1.1153 + y_ptr += y_stride*16; 1.1154 + u_ptr += y_stride*4; 1.1155 + v_ptr += y_stride*4; 1.1156 + 1.1157 + mi++; 1.1158 + } 1.1159 + } 1.1160 + 1.1161 + /* Color in frame reference blocks */ 1.1162 + if ((flags & VP8D_DEBUG_CLR_FRM_REF_BLKS) && ppflags->display_ref_frame_flag) 1.1163 + { 1.1164 + int y, x; 1.1165 + YV12_BUFFER_CONFIG *post = &oci->post_proc_buffer; 1.1166 + int width = post->y_width; 1.1167 + int height = post->y_height; 1.1168 + unsigned char *y_ptr = oci->post_proc_buffer.y_buffer; 1.1169 + unsigned char *u_ptr = oci->post_proc_buffer.u_buffer; 1.1170 + unsigned char *v_ptr = oci->post_proc_buffer.v_buffer; 1.1171 + int y_stride = oci->post_proc_buffer.y_stride; 1.1172 + MODE_INFO *mi = oci->mi; 1.1173 + 1.1174 + for (y = 0; y < height; y += 16) 1.1175 + { 1.1176 + for (x = 0; x < width; x +=16) 1.1177 + { 1.1178 + int Y = 0, U = 0, V = 0; 1.1179 + 1.1180 + if (ppflags->display_ref_frame_flag & (1<<mi->mbmi.ref_frame)) 1.1181 + { 1.1182 + Y = MV_REFERENCE_FRAME_colors[mi->mbmi.ref_frame][0]; 1.1183 + U = MV_REFERENCE_FRAME_colors[mi->mbmi.ref_frame][1]; 1.1184 + V = MV_REFERENCE_FRAME_colors[mi->mbmi.ref_frame][2]; 1.1185 + 1.1186 + vp8_blend_mb_outer 1.1187 + (y_ptr+x, u_ptr+(x>>1), v_ptr+(x>>1), Y, U, V, 0xc000, y_stride); 1.1188 + } 1.1189 + 1.1190 + mi++; 1.1191 + } 1.1192 + y_ptr += y_stride*16; 1.1193 + u_ptr += y_stride*4; 1.1194 + v_ptr += y_stride*4; 1.1195 + 1.1196 + mi++; 1.1197 + } 1.1198 + } 1.1199 +#endif 1.1200 + 1.1201 + *dest = oci->post_proc_buffer; 1.1202 + 1.1203 + /* handle problem with extending borders */ 1.1204 + dest->y_width = oci->Width; 1.1205 + dest->y_height = oci->Height; 1.1206 + dest->uv_height = dest->y_height / 2; 1.1207 + return 0; 1.1208 +} 1.1209 +#endif