media/libvpx/vp9/common/vp9_postproc.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     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  */
    11 #include <math.h>
    12 #include <stdlib.h>
    13 #include <stdio.h>
    15 #include "./vpx_config.h"
    16 #include "vpx_scale/yv12config.h"
    17 #include "vp9/common/vp9_postproc.h"
    18 #include "vp9/common/vp9_textblit.h"
    19 #include "vpx_scale/vpx_scale.h"
    20 #include "vp9/common/vp9_systemdependent.h"
    21 #include "./vp9_rtcd.h"
    22 #include "./vpx_scale_rtcd.h"
    24 #define RGB_TO_YUV(t)                                            \
    25   ( (0.257*(float)(t >> 16))  + (0.504*(float)(t >> 8 & 0xff)) + \
    26     (0.098*(float)(t & 0xff)) + 16),                             \
    27   (-(0.148*(float)(t >> 16))  - (0.291*(float)(t >> 8 & 0xff)) + \
    28     (0.439*(float)(t & 0xff)) + 128),                            \
    29   ( (0.439*(float)(t >> 16))  - (0.368*(float)(t >> 8 & 0xff)) - \
    30     (0.071*(float)(t & 0xff)) + 128)
    32 /* global constants */
    33 #if 0 && CONFIG_POSTPROC_VISUALIZER
    34 static const unsigned char MB_PREDICTION_MODE_colors[MB_MODE_COUNT][3] = {
    35   { RGB_TO_YUV(0x98FB98) },   /* PaleGreen */
    36   { RGB_TO_YUV(0x00FF00) },   /* Green */
    37   { RGB_TO_YUV(0xADFF2F) },   /* GreenYellow */
    38   { RGB_TO_YUV(0x8F0000) },   /* Dark Red */
    39   { RGB_TO_YUV(0x008F8F) },   /* Dark Cyan */
    40   { RGB_TO_YUV(0x008F8F) },   /* Dark Cyan */
    41   { RGB_TO_YUV(0x008F8F) },   /* Dark Cyan */
    42   { RGB_TO_YUV(0x8F0000) },   /* Dark Red */
    43   { RGB_TO_YUV(0x8F0000) },   /* Dark Red */
    44   { RGB_TO_YUV(0x228B22) },   /* ForestGreen */
    45   { RGB_TO_YUV(0x006400) },   /* DarkGreen */
    46   { RGB_TO_YUV(0x98F5FF) },   /* Cadet Blue */
    47   { RGB_TO_YUV(0x6CA6CD) },   /* Sky Blue */
    48   { RGB_TO_YUV(0x00008B) },   /* Dark blue */
    49   { RGB_TO_YUV(0x551A8B) },   /* Purple */
    50   { RGB_TO_YUV(0xFF0000) }    /* Red */
    51   { RGB_TO_YUV(0xCC33FF) },   /* Magenta */
    52 };
    54 static const unsigned char B_PREDICTION_MODE_colors[INTRA_MODES][3] = {
    55   { RGB_TO_YUV(0x6633ff) },   /* Purple */
    56   { RGB_TO_YUV(0xcc33ff) },   /* Magenta */
    57   { RGB_TO_YUV(0xff33cc) },   /* Pink */
    58   { RGB_TO_YUV(0xff3366) },   /* Coral */
    59   { RGB_TO_YUV(0x3366ff) },   /* Blue */
    60   { RGB_TO_YUV(0xed00f5) },   /* Dark Blue */
    61   { RGB_TO_YUV(0x2e00b8) },   /* Dark Purple */
    62   { RGB_TO_YUV(0xff6633) },   /* Orange */
    63   { RGB_TO_YUV(0x33ccff) },   /* Light Blue */
    64   { RGB_TO_YUV(0x8ab800) },   /* Green */
    65   { RGB_TO_YUV(0xffcc33) },   /* Light Orange */
    66   { RGB_TO_YUV(0x33ffcc) },   /* Aqua */
    67   { RGB_TO_YUV(0x66ff33) },   /* Light Green */
    68   { RGB_TO_YUV(0xccff33) },   /* Yellow */
    69 };
    71 static const unsigned char MV_REFERENCE_FRAME_colors[MAX_REF_FRAMES][3] = {
    72   { RGB_TO_YUV(0x00ff00) },   /* Blue */
    73   { RGB_TO_YUV(0x0000ff) },   /* Green */
    74   { RGB_TO_YUV(0xffff00) },   /* Yellow */
    75   { RGB_TO_YUV(0xff0000) },   /* Red */
    76 };
    77 #endif
    79 static const short kernel5[] = {
    80   1, 1, 4, 1, 1
    81 };
    83 const short vp9_rv[] = {
    84   8, 5, 2, 2, 8, 12, 4, 9, 8, 3,
    85   0, 3, 9, 0, 0, 0, 8, 3, 14, 4,
    86   10, 1, 11, 14, 1, 14, 9, 6, 12, 11,
    87   8, 6, 10, 0, 0, 8, 9, 0, 3, 14,
    88   8, 11, 13, 4, 2, 9, 0, 3, 9, 6,
    89   1, 2, 3, 14, 13, 1, 8, 2, 9, 7,
    90   3, 3, 1, 13, 13, 6, 6, 5, 2, 7,
    91   11, 9, 11, 8, 7, 3, 2, 0, 13, 13,
    92   14, 4, 12, 5, 12, 10, 8, 10, 13, 10,
    93   4, 14, 4, 10, 0, 8, 11, 1, 13, 7,
    94   7, 14, 6, 14, 13, 2, 13, 5, 4, 4,
    95   0, 10, 0, 5, 13, 2, 12, 7, 11, 13,
    96   8, 0, 4, 10, 7, 2, 7, 2, 2, 5,
    97   3, 4, 7, 3, 3, 14, 14, 5, 9, 13,
    98   3, 14, 3, 6, 3, 0, 11, 8, 13, 1,
    99   13, 1, 12, 0, 10, 9, 7, 6, 2, 8,
   100   5, 2, 13, 7, 1, 13, 14, 7, 6, 7,
   101   9, 6, 10, 11, 7, 8, 7, 5, 14, 8,
   102   4, 4, 0, 8, 7, 10, 0, 8, 14, 11,
   103   3, 12, 5, 7, 14, 3, 14, 5, 2, 6,
   104   11, 12, 12, 8, 0, 11, 13, 1, 2, 0,
   105   5, 10, 14, 7, 8, 0, 4, 11, 0, 8,
   106   0, 3, 10, 5, 8, 0, 11, 6, 7, 8,
   107   10, 7, 13, 9, 2, 5, 1, 5, 10, 2,
   108   4, 3, 5, 6, 10, 8, 9, 4, 11, 14,
   109   0, 10, 0, 5, 13, 2, 12, 7, 11, 13,
   110   8, 0, 4, 10, 7, 2, 7, 2, 2, 5,
   111   3, 4, 7, 3, 3, 14, 14, 5, 9, 13,
   112   3, 14, 3, 6, 3, 0, 11, 8, 13, 1,
   113   13, 1, 12, 0, 10, 9, 7, 6, 2, 8,
   114   5, 2, 13, 7, 1, 13, 14, 7, 6, 7,
   115   9, 6, 10, 11, 7, 8, 7, 5, 14, 8,
   116   4, 4, 0, 8, 7, 10, 0, 8, 14, 11,
   117   3, 12, 5, 7, 14, 3, 14, 5, 2, 6,
   118   11, 12, 12, 8, 0, 11, 13, 1, 2, 0,
   119   5, 10, 14, 7, 8, 0, 4, 11, 0, 8,
   120   0, 3, 10, 5, 8, 0, 11, 6, 7, 8,
   121   10, 7, 13, 9, 2, 5, 1, 5, 10, 2,
   122   4, 3, 5, 6, 10, 8, 9, 4, 11, 14,
   123   3, 8, 3, 7, 8, 5, 11, 4, 12, 3,
   124   11, 9, 14, 8, 14, 13, 4, 3, 1, 2,
   125   14, 6, 5, 4, 4, 11, 4, 6, 2, 1,
   126   5, 8, 8, 12, 13, 5, 14, 10, 12, 13,
   127   0, 9, 5, 5, 11, 10, 13, 9, 10, 13,
   128 };
   131 /****************************************************************************
   132  */
   133 void vp9_post_proc_down_and_across_c(const uint8_t *src_ptr,
   134                                      uint8_t *dst_ptr,
   135                                      int src_pixels_per_line,
   136                                      int dst_pixels_per_line,
   137                                      int rows,
   138                                      int cols,
   139                                      int flimit) {
   140   uint8_t const *p_src;
   141   uint8_t *p_dst;
   142   int row;
   143   int col;
   144   int i;
   145   int v;
   146   int pitch = src_pixels_per_line;
   147   uint8_t d[8];
   148   (void)dst_pixels_per_line;
   150   for (row = 0; row < rows; row++) {
   151     /* post_proc_down for one row */
   152     p_src = src_ptr;
   153     p_dst = dst_ptr;
   155     for (col = 0; col < cols; col++) {
   156       int kernel = 4;
   157       int v = p_src[col];
   159       for (i = -2; i <= 2; i++) {
   160         if (abs(v - p_src[col + i * pitch]) > flimit)
   161           goto down_skip_convolve;
   163         kernel += kernel5[2 + i] * p_src[col + i * pitch];
   164       }
   166       v = (kernel >> 3);
   167     down_skip_convolve:
   168       p_dst[col] = v;
   169     }
   171     /* now post_proc_across */
   172     p_src = dst_ptr;
   173     p_dst = dst_ptr;
   175     for (i = 0; i < 8; i++)
   176       d[i] = p_src[i];
   178     for (col = 0; col < cols; col++) {
   179       int kernel = 4;
   180       v = p_src[col];
   182       d[col & 7] = v;
   184       for (i = -2; i <= 2; i++) {
   185         if (abs(v - p_src[col + i]) > flimit)
   186           goto across_skip_convolve;
   188         kernel += kernel5[2 + i] * p_src[col + i];
   189       }
   191       d[col & 7] = (kernel >> 3);
   192     across_skip_convolve:
   194       if (col >= 2)
   195         p_dst[col - 2] = d[(col - 2) & 7];
   196     }
   198     /* handle the last two pixels */
   199     p_dst[col - 2] = d[(col - 2) & 7];
   200     p_dst[col - 1] = d[(col - 1) & 7];
   203     /* next row */
   204     src_ptr += pitch;
   205     dst_ptr += pitch;
   206   }
   207 }
   209 static int q2mbl(int x) {
   210   if (x < 20) x = 20;
   212   x = 50 + (x - 50) * 10 / 8;
   213   return x * x / 3;
   214 }
   216 void vp9_mbpost_proc_across_ip_c(uint8_t *src, int pitch,
   217                                  int rows, int cols, int flimit) {
   218   int r, c, i;
   220   uint8_t *s = src;
   221   uint8_t d[16];
   224   for (r = 0; r < rows; r++) {
   225     int sumsq = 0;
   226     int sum   = 0;
   228     for (i = -8; i <= 6; i++) {
   229       sumsq += s[i] * s[i];
   230       sum   += s[i];
   231       d[i + 8] = 0;
   232     }
   234     for (c = 0; c < cols + 8; c++) {
   235       int x = s[c + 7] - s[c - 8];
   236       int y = s[c + 7] + s[c - 8];
   238       sum  += x;
   239       sumsq += x * y;
   241       d[c & 15] = s[c];
   243       if (sumsq * 15 - sum * sum < flimit) {
   244         d[c & 15] = (8 + sum + s[c]) >> 4;
   245       }
   247       s[c - 8] = d[(c - 8) & 15];
   248     }
   250     s += pitch;
   251   }
   252 }
   254 void vp9_mbpost_proc_down_c(uint8_t *dst, int pitch,
   255                             int rows, int cols, int flimit) {
   256   int r, c, i;
   257   const short *rv3 = &vp9_rv[63 & rand()]; // NOLINT
   259   for (c = 0; c < cols; c++) {
   260     uint8_t *s = &dst[c];
   261     int sumsq = 0;
   262     int sum   = 0;
   263     uint8_t d[16];
   264     const short *rv2 = rv3 + ((c * 17) & 127);
   266     for (i = -8; i <= 6; i++) {
   267       sumsq += s[i * pitch] * s[i * pitch];
   268       sum   += s[i * pitch];
   269     }
   271     for (r = 0; r < rows + 8; r++) {
   272       sumsq += s[7 * pitch] * s[ 7 * pitch] - s[-8 * pitch] * s[-8 * pitch];
   273       sum  += s[7 * pitch] - s[-8 * pitch];
   274       d[r & 15] = s[0];
   276       if (sumsq * 15 - sum * sum < flimit) {
   277         d[r & 15] = (rv2[r & 127] + sum + s[0]) >> 4;
   278       }
   280       s[-8 * pitch] = d[(r - 8) & 15];
   281       s += pitch;
   282     }
   283   }
   284 }
   286 static void deblock_and_de_macro_block(YV12_BUFFER_CONFIG   *source,
   287                                        YV12_BUFFER_CONFIG   *post,
   288                                        int                   q,
   289                                        int                   low_var_thresh,
   290                                        int                   flag) {
   291   double level = 6.0e-05 * q * q * q - .0067 * q * q + .306 * q + .0065;
   292   int ppl = (int)(level + .5);
   293   (void) low_var_thresh;
   294   (void) flag;
   296   vp9_post_proc_down_and_across(source->y_buffer, post->y_buffer,
   297                                 source->y_stride, post->y_stride,
   298                                 source->y_height, source->y_width, ppl);
   300   vp9_mbpost_proc_across_ip(post->y_buffer, post->y_stride, post->y_height,
   301                             post->y_width, q2mbl(q));
   303   vp9_mbpost_proc_down(post->y_buffer, post->y_stride, post->y_height,
   304                        post->y_width, q2mbl(q));
   306   vp9_post_proc_down_and_across(source->u_buffer, post->u_buffer,
   307                                 source->uv_stride, post->uv_stride,
   308                                 source->uv_height, source->uv_width, ppl);
   309   vp9_post_proc_down_and_across(source->v_buffer, post->v_buffer,
   310                                 source->uv_stride, post->uv_stride,
   311                                 source->uv_height, source->uv_width, ppl);
   312 }
   314 void vp9_deblock(const YV12_BUFFER_CONFIG *src, YV12_BUFFER_CONFIG *dst,
   315                  int q) {
   316   const int ppl = (int)(6.0e-05 * q * q * q - 0.0067 * q * q + 0.306 * q
   317                         + 0.0065 + 0.5);
   318   int i;
   320   const uint8_t *const srcs[4] = {src->y_buffer, src->u_buffer, src->v_buffer,
   321                                   src->alpha_buffer};
   322   const int src_strides[4] = {src->y_stride, src->uv_stride, src->uv_stride,
   323                               src->alpha_stride};
   324   const int src_widths[4] = {src->y_width, src->uv_width, src->uv_width,
   325                              src->alpha_width};
   326   const int src_heights[4] = {src->y_height, src->uv_height, src->uv_height,
   327                               src->alpha_height};
   329   uint8_t *const dsts[4] = {dst->y_buffer, dst->u_buffer, dst->v_buffer,
   330                             dst->alpha_buffer};
   331   const int dst_strides[4] = {dst->y_stride, dst->uv_stride, dst->uv_stride,
   332                               dst->alpha_stride};
   334   for (i = 0; i < MAX_MB_PLANE; ++i)
   335     vp9_post_proc_down_and_across(srcs[i], dsts[i],
   336                                   src_strides[i], dst_strides[i],
   337                                   src_heights[i], src_widths[i], ppl);
   338 }
   340 void vp9_denoise(const YV12_BUFFER_CONFIG *src, YV12_BUFFER_CONFIG *dst,
   341                  int q) {
   342   const int ppl = (int)(6.0e-05 * q * q * q - 0.0067 * q * q + 0.306 * q
   343                         + 0.0065 + 0.5);
   344   int i;
   346   const uint8_t *const srcs[4] = {src->y_buffer, src->u_buffer, src->v_buffer,
   347                                   src->alpha_buffer};
   348   const int src_strides[4] = {src->y_stride, src->uv_stride, src->uv_stride,
   349                               src->alpha_stride};
   350   const int src_widths[4] = {src->y_width, src->uv_width, src->uv_width,
   351                              src->alpha_width};
   352   const int src_heights[4] = {src->y_height, src->uv_height, src->uv_height,
   353                               src->alpha_height};
   355   uint8_t *const dsts[4] = {dst->y_buffer, dst->u_buffer, dst->v_buffer,
   356                             dst->alpha_buffer};
   357   const int dst_strides[4] = {dst->y_stride, dst->uv_stride, dst->uv_stride,
   358                               dst->alpha_stride};
   360   for (i = 0; i < MAX_MB_PLANE; ++i) {
   361     const int src_stride = src_strides[i];
   362     const uint8_t *const src = srcs[i] + 2 * src_stride + 2;
   363     const int src_width = src_widths[i] - 4;
   364     const int src_height = src_heights[i] - 4;
   366     const int dst_stride = dst_strides[i];
   367     uint8_t *const dst = dsts[i] + 2 * dst_stride + 2;
   369     vp9_post_proc_down_and_across(src, dst, src_stride, dst_stride,
   370                                   src_height, src_width, ppl);
   371   }
   372 }
   374 double vp9_gaussian(double sigma, double mu, double x) {
   375   return 1 / (sigma * sqrt(2.0 * 3.14159265)) *
   376          (exp(-(x - mu) * (x - mu) / (2 * sigma * sigma)));
   377 }
   379 static void fillrd(struct postproc_state *state, int q, int a) {
   380   char char_dist[300];
   382   double sigma;
   383   int ai = a, qi = q, i;
   385   vp9_clear_system_state();
   387   sigma = ai + .5 + .6 * (63 - qi) / 63.0;
   389   /* set up a lookup table of 256 entries that matches
   390    * a gaussian distribution with sigma determined by q.
   391    */
   392   {
   393     double i;
   394     int next, j;
   396     next = 0;
   398     for (i = -32; i < 32; i++) {
   399       int a = (int)(.5 + 256 * vp9_gaussian(sigma, 0, i));
   401       if (a) {
   402         for (j = 0; j < a; j++) {
   403           char_dist[next + j] = (char) i;
   404         }
   406         next = next + j;
   407       }
   408     }
   410     for (; next < 256; next++)
   411       char_dist[next] = 0;
   412   }
   414   for (i = 0; i < 3072; i++) {
   415     state->noise[i] = char_dist[rand() & 0xff];  // NOLINT
   416   }
   418   for (i = 0; i < 16; i++) {
   419     state->blackclamp[i] = -char_dist[0];
   420     state->whiteclamp[i] = -char_dist[0];
   421     state->bothclamp[i] = -2 * char_dist[0];
   422   }
   424   state->last_q = q;
   425   state->last_noise = a;
   426 }
   428 /****************************************************************************
   429  *
   430  *  ROUTINE       : plane_add_noise_c
   431  *
   432  *  INPUTS        : unsigned char *Start  starting address of buffer to
   433  *                                        add gaussian noise to
   434  *                  unsigned int width    width of plane
   435  *                  unsigned int height   height of plane
   436  *                  int  pitch    distance between subsequent lines of frame
   437  *                  int  q        quantizer used to determine amount of noise
   438  *                                  to add
   439  *
   440  *  OUTPUTS       : None.
   441  *
   442  *  RETURNS       : void.
   443  *
   444  *  FUNCTION      : adds gaussian noise to a plane of pixels
   445  *
   446  *  SPECIAL NOTES : None.
   447  *
   448  ****************************************************************************/
   449 void vp9_plane_add_noise_c(uint8_t *start, char *noise,
   450                            char blackclamp[16],
   451                            char whiteclamp[16],
   452                            char bothclamp[16],
   453                            unsigned int width, unsigned int height, int pitch) {
   454   unsigned int i, j;
   456   for (i = 0; i < height; i++) {
   457     uint8_t *pos = start + i * pitch;
   458     char  *ref = (char *)(noise + (rand() & 0xff));  // NOLINT
   460     for (j = 0; j < width; j++) {
   461       if (pos[j] < blackclamp[0])
   462         pos[j] = blackclamp[0];
   464       if (pos[j] > 255 + whiteclamp[0])
   465         pos[j] = 255 + whiteclamp[0];
   467       pos[j] += ref[j];
   468     }
   469   }
   470 }
   472 /* Blend the macro block with a solid colored square.  Leave the
   473  * edges unblended to give distinction to macro blocks in areas
   474  * filled with the same color block.
   475  */
   476 void vp9_blend_mb_inner_c(uint8_t *y, uint8_t *u, uint8_t *v,
   477                           int y1, int u1, int v1, int alpha, int stride) {
   478   int i, j;
   479   int y1_const = y1 * ((1 << 16) - alpha);
   480   int u1_const = u1 * ((1 << 16) - alpha);
   481   int v1_const = v1 * ((1 << 16) - alpha);
   483   y += 2 * stride + 2;
   484   for (i = 0; i < 12; i++) {
   485     for (j = 0; j < 12; j++) {
   486       y[j] = (y[j] * alpha + y1_const) >> 16;
   487     }
   488     y += stride;
   489   }
   491   stride >>= 1;
   493   u += stride + 1;
   494   v += stride + 1;
   496   for (i = 0; i < 6; i++) {
   497     for (j = 0; j < 6; j++) {
   498       u[j] = (u[j] * alpha + u1_const) >> 16;
   499       v[j] = (v[j] * alpha + v1_const) >> 16;
   500     }
   501     u += stride;
   502     v += stride;
   503   }
   504 }
   506 /* Blend only the edge of the macro block.  Leave center
   507  * unblended to allow for other visualizations to be layered.
   508  */
   509 void vp9_blend_mb_outer_c(uint8_t *y, uint8_t *u, uint8_t *v,
   510                           int y1, int u1, int v1, int alpha, int stride) {
   511   int i, j;
   512   int y1_const = y1 * ((1 << 16) - alpha);
   513   int u1_const = u1 * ((1 << 16) - alpha);
   514   int v1_const = v1 * ((1 << 16) - alpha);
   516   for (i = 0; i < 2; i++) {
   517     for (j = 0; j < 16; j++) {
   518       y[j] = (y[j] * alpha + y1_const) >> 16;
   519     }
   520     y += stride;
   521   }
   523   for (i = 0; i < 12; i++) {
   524     y[0]  = (y[0] * alpha  + y1_const) >> 16;
   525     y[1]  = (y[1] * alpha  + y1_const) >> 16;
   526     y[14] = (y[14] * alpha + y1_const) >> 16;
   527     y[15] = (y[15] * alpha + y1_const) >> 16;
   528     y += stride;
   529   }
   531   for (i = 0; i < 2; i++) {
   532     for (j = 0; j < 16; j++) {
   533       y[j] = (y[j] * alpha + y1_const) >> 16;
   534     }
   535     y += stride;
   536   }
   538   stride >>= 1;
   540   for (j = 0; j < 8; j++) {
   541     u[j] = (u[j] * alpha + u1_const) >> 16;
   542     v[j] = (v[j] * alpha + v1_const) >> 16;
   543   }
   544   u += stride;
   545   v += stride;
   547   for (i = 0; i < 6; i++) {
   548     u[0] = (u[0] * alpha + u1_const) >> 16;
   549     v[0] = (v[0] * alpha + v1_const) >> 16;
   551     u[7] = (u[7] * alpha + u1_const) >> 16;
   552     v[7] = (v[7] * alpha + v1_const) >> 16;
   554     u += stride;
   555     v += stride;
   556   }
   558   for (j = 0; j < 8; j++) {
   559     u[j] = (u[j] * alpha + u1_const) >> 16;
   560     v[j] = (v[j] * alpha + v1_const) >> 16;
   561   }
   562 }
   564 void vp9_blend_b_c(uint8_t *y, uint8_t *u, uint8_t *v,
   565                    int y1, int u1, int v1, int alpha, int stride) {
   566   int i, j;
   567   int y1_const = y1 * ((1 << 16) - alpha);
   568   int u1_const = u1 * ((1 << 16) - alpha);
   569   int v1_const = v1 * ((1 << 16) - alpha);
   571   for (i = 0; i < 4; i++) {
   572     for (j = 0; j < 4; j++) {
   573       y[j] = (y[j] * alpha + y1_const) >> 16;
   574     }
   575     y += stride;
   576   }
   578   stride >>= 1;
   580   for (i = 0; i < 2; i++) {
   581     for (j = 0; j < 2; j++) {
   582       u[j] = (u[j] * alpha + u1_const) >> 16;
   583       v[j] = (v[j] * alpha + v1_const) >> 16;
   584     }
   585     u += stride;
   586     v += stride;
   587   }
   588 }
   590 static void constrain_line(int x0, int *x1, int y0, int *y1,
   591                            int width, int height) {
   592   int dx;
   593   int dy;
   595   if (*x1 > width) {
   596     dx = *x1 - x0;
   597     dy = *y1 - y0;
   599     *x1 = width;
   600     if (dx)
   601       *y1 = ((width - x0) * dy) / dx + y0;
   602   }
   603   if (*x1 < 0) {
   604     dx = *x1 - x0;
   605     dy = *y1 - y0;
   607     *x1 = 0;
   608     if (dx)
   609       *y1 = ((0 - x0) * dy) / dx + y0;
   610   }
   611   if (*y1 > height) {
   612     dx = *x1 - x0;
   613     dy = *y1 - y0;
   615     *y1 = height;
   616     if (dy)
   617       *x1 = ((height - y0) * dx) / dy + x0;
   618   }
   619   if (*y1 < 0) {
   620     dx = *x1 - x0;
   621     dy = *y1 - y0;
   623     *y1 = 0;
   624     if (dy)
   625       *x1 = ((0 - y0) * dx) / dy + x0;
   626   }
   627 }
   629 int vp9_post_proc_frame(struct VP9Common *cm,
   630                         YV12_BUFFER_CONFIG *dest, vp9_ppflags_t *ppflags) {
   631   int q = cm->lf.filter_level * 10 / 6;
   632   int flags = ppflags->post_proc_flag;
   633   int deblock_level = ppflags->deblocking_level;
   634   int noise_level = ppflags->noise_level;
   636   if (!cm->frame_to_show)
   637     return -1;
   639   if (q > 63)
   640     q = 63;
   642   if (!flags) {
   643     *dest = *cm->frame_to_show;
   644     return 0;
   645   }
   647 #if ARCH_X86||ARCH_X86_64
   648   vpx_reset_mmx_state();
   649 #endif
   651   if (flags & VP9D_DEMACROBLOCK) {
   652     deblock_and_de_macro_block(cm->frame_to_show, &cm->post_proc_buffer,
   653                                q + (deblock_level - 5) * 10, 1, 0);
   654   } else if (flags & VP9D_DEBLOCK) {
   655     vp9_deblock(cm->frame_to_show, &cm->post_proc_buffer, q);
   656   } else {
   657     vp8_yv12_copy_frame(cm->frame_to_show, &cm->post_proc_buffer);
   658   }
   660   if (flags & VP9D_ADDNOISE) {
   661     if (cm->postproc_state.last_q != q
   662         || cm->postproc_state.last_noise != noise_level) {
   663       fillrd(&cm->postproc_state, 63 - q, noise_level);
   664     }
   666     vp9_plane_add_noise(cm->post_proc_buffer.y_buffer,
   667                         cm->postproc_state.noise,
   668                         cm->postproc_state.blackclamp,
   669                         cm->postproc_state.whiteclamp,
   670                         cm->postproc_state.bothclamp,
   671                         cm->post_proc_buffer.y_width,
   672                         cm->post_proc_buffer.y_height,
   673                         cm->post_proc_buffer.y_stride);
   674   }
   676 #if 0 && CONFIG_POSTPROC_VISUALIZER
   677   if (flags & VP9D_DEBUG_TXT_FRAME_INFO) {
   678     char message[512];
   679     snprintf(message, sizeof(message) -1,
   680              "F%1dG%1dQ%3dF%3dP%d_s%dx%d",
   681              (cm->frame_type == KEY_FRAME),
   682              cm->refresh_golden_frame,
   683              cm->base_qindex,
   684              cm->filter_level,
   685              flags,
   686              cm->mb_cols, cm->mb_rows);
   687     vp9_blit_text(message, cm->post_proc_buffer.y_buffer,
   688                   cm->post_proc_buffer.y_stride);
   689   }
   691   if (flags & VP9D_DEBUG_TXT_MBLK_MODES) {
   692     int i, j;
   693     uint8_t *y_ptr;
   694     YV12_BUFFER_CONFIG *post = &cm->post_proc_buffer;
   695     int mb_rows = post->y_height >> 4;
   696     int mb_cols = post->y_width  >> 4;
   697     int mb_index = 0;
   698     MODE_INFO *mi = cm->mi;
   700     y_ptr = post->y_buffer + 4 * post->y_stride + 4;
   702     /* vp9_filter each macro block */
   703     for (i = 0; i < mb_rows; i++) {
   704       for (j = 0; j < mb_cols; j++) {
   705         char zz[4];
   707         snprintf(zz, sizeof(zz) - 1, "%c", mi[mb_index].mbmi.mode + 'a');
   709         vp9_blit_text(zz, y_ptr, post->y_stride);
   710         mb_index++;
   711         y_ptr += 16;
   712       }
   714       mb_index++; /* border */
   715       y_ptr += post->y_stride  * 16 - post->y_width;
   716     }
   717   }
   719   if (flags & VP9D_DEBUG_TXT_DC_DIFF) {
   720     int i, j;
   721     uint8_t *y_ptr;
   722     YV12_BUFFER_CONFIG *post = &cm->post_proc_buffer;
   723     int mb_rows = post->y_height >> 4;
   724     int mb_cols = post->y_width  >> 4;
   725     int mb_index = 0;
   726     MODE_INFO *mi = cm->mi;
   728     y_ptr = post->y_buffer + 4 * post->y_stride + 4;
   730     /* vp9_filter each macro block */
   731     for (i = 0; i < mb_rows; i++) {
   732       for (j = 0; j < mb_cols; j++) {
   733         char zz[4];
   734         int dc_diff = !(mi[mb_index].mbmi.mode != I4X4_PRED &&
   735                         mi[mb_index].mbmi.mode != SPLITMV &&
   736                         mi[mb_index].mbmi.skip_coeff);
   738         if (cm->frame_type == KEY_FRAME)
   739           snprintf(zz, sizeof(zz) - 1, "a");
   740         else
   741           snprintf(zz, sizeof(zz) - 1, "%c", dc_diff + '0');
   743         vp9_blit_text(zz, y_ptr, post->y_stride);
   744         mb_index++;
   745         y_ptr += 16;
   746       }
   748       mb_index++; /* border */
   749       y_ptr += post->y_stride  * 16 - post->y_width;
   750     }
   751   }
   753   if (flags & VP9D_DEBUG_TXT_RATE_INFO) {
   754     char message[512];
   755     snprintf(message, sizeof(message),
   756              "Bitrate: %10.2f framerate: %10.2f ",
   757              cm->bitrate, cm->framerate);
   758     vp9_blit_text(message, cm->post_proc_buffer.y_buffer,
   759                   cm->post_proc_buffer.y_stride);
   760   }
   762   /* Draw motion vectors */
   763   if ((flags & VP9D_DEBUG_DRAW_MV) && ppflags->display_mv_flag) {
   764     YV12_BUFFER_CONFIG *post = &cm->post_proc_buffer;
   765     int width  = post->y_width;
   766     int height = post->y_height;
   767     uint8_t *y_buffer = cm->post_proc_buffer.y_buffer;
   768     int y_stride = cm->post_proc_buffer.y_stride;
   769     MODE_INFO *mi = cm->mi;
   770     int x0, y0;
   772     for (y0 = 0; y0 < height; y0 += 16) {
   773       for (x0 = 0; x0 < width; x0 += 16) {
   774         int x1, y1;
   776         if (!(ppflags->display_mv_flag & (1 << mi->mbmi.mode))) {
   777           mi++;
   778           continue;
   779         }
   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;
   787               x1 = x0 + 8 + (mv->col >> 3);
   788               y1 = y0 + 4 + (mv->row >> 3);
   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);
   793               bmi = &mi->bmi[8];
   795               x1 = x0 + 8 + (mv->col >> 3);
   796               y1 = y0 + 12 + (mv->row >> 3);
   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);
   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;
   807               x1 = x0 + 4 + (mv->col >> 3);
   808               y1 = y0 + 8 + (mv->row >> 3);
   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);
   813               bmi = &mi->bmi[2];
   815               x1 = x0 + 12 + (mv->col >> 3);
   816               y1 = y0 + 8 + (mv->row >> 3);
   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);
   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;
   827               x1 = x0 + 4 + (mv->col >> 3);
   828               y1 = y0 + 4 + (mv->row >> 3);
   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);
   833               bmi = &mi->bmi[2];
   835               x1 = x0 + 12 + (mv->col >> 3);
   836               y1 = y0 + 4 + (mv->row >> 3);
   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);
   841               bmi = &mi->bmi[8];
   843               x1 = x0 + 4 + (mv->col >> 3);
   844               y1 = y0 + 12 + (mv->row >> 3);
   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);
   849               bmi = &mi->bmi[10];
   851               x1 = x0 + 12 + (mv->col >> 3);
   852               y1 = y0 + 12 + (mv->row >> 3);
   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;
   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;
   867                   x1 = bx0 + 2 + (mv->col >> 3);
   868                   y1 = by0 + 2 + (mv->row >> 3);
   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);
   873                   bmi++;
   874                 }
   875               }
   876             }
   877           }
   878         } else if (is_inter_mode(mi->mbmi.mode)) {
   879           MV *mv = &mi->mbmi.mv.as_mv;
   880           const int lx0 = x0 + 8;
   881           const int ly0 = y0 + 8;
   883           x1 = lx0 + (mv->col >> 3);
   884           y1 = ly0 + (mv->row >> 3);
   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);
   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         }
   897         mi++;
   898       }
   899       mi++;
   900     }
   901   }
   903   /* Color in block modes */
   904   if ((flags & VP9D_DEBUG_CLR_BLK_MODES)
   905       && (ppflags->display_mb_modes_flag || ppflags->display_b_modes_flag)) {
   906     int y, x;
   907     YV12_BUFFER_CONFIG *post = &cm->post_proc_buffer;
   908     int width  = post->y_width;
   909     int height = post->y_height;
   910     uint8_t *y_ptr = cm->post_proc_buffer.y_buffer;
   911     uint8_t *u_ptr = cm->post_proc_buffer.u_buffer;
   912     uint8_t *v_ptr = cm->post_proc_buffer.v_buffer;
   913     int y_stride = cm->post_proc_buffer.y_stride;
   914     MODE_INFO *mi = cm->mi;
   916     for (y = 0; y < height; y += 16) {
   917       for (x = 0; x < width; x += 16) {
   918         int Y = 0, U = 0, V = 0;
   920         if (mi->mbmi.mode == I4X4_PRED &&
   921             ((ppflags->display_mb_modes_flag & I4X4_PRED) ||
   922              ppflags->display_b_modes_flag)) {
   923           int by, bx;
   924           uint8_t *yl, *ul, *vl;
   925           union b_mode_info *bmi = mi->bmi;
   927           yl = y_ptr + x;
   928           ul = u_ptr + (x >> 1);
   929           vl = v_ptr + (x >> 1);
   931           for (by = 0; by < 16; by += 4) {
   932             for (bx = 0; bx < 16; bx += 4) {
   933               if ((ppflags->display_b_modes_flag & (1 << mi->mbmi.mode))
   934                   || (ppflags->display_mb_modes_flag & I4X4_PRED)) {
   935                 Y = B_PREDICTION_MODE_colors[bmi->as_mode][0];
   936                 U = B_PREDICTION_MODE_colors[bmi->as_mode][1];
   937                 V = B_PREDICTION_MODE_colors[bmi->as_mode][2];
   939                 vp9_blend_b(yl + bx, ul + (bx >> 1), vl + (bx >> 1), Y, U, V,
   940                     0xc000, y_stride);
   941               }
   942               bmi++;
   943             }
   945             yl += y_stride * 4;
   946             ul += y_stride * 1;
   947             vl += y_stride * 1;
   948           }
   949         } else if (ppflags->display_mb_modes_flag & (1 << mi->mbmi.mode)) {
   950           Y = MB_PREDICTION_MODE_colors[mi->mbmi.mode][0];
   951           U = MB_PREDICTION_MODE_colors[mi->mbmi.mode][1];
   952           V = MB_PREDICTION_MODE_colors[mi->mbmi.mode][2];
   954           vp9_blend_mb_inner(y_ptr + x, u_ptr + (x >> 1), v_ptr + (x >> 1),
   955                              Y, U, V, 0xc000, y_stride);
   956         }
   958         mi++;
   959       }
   960       y_ptr += y_stride * 16;
   961       u_ptr += y_stride * 4;
   962       v_ptr += y_stride * 4;
   964       mi++;
   965     }
   966   }
   968   /* Color in frame reference blocks */
   969   if ((flags & VP9D_DEBUG_CLR_FRM_REF_BLKS) &&
   970       ppflags->display_ref_frame_flag) {
   971     int y, x;
   972     YV12_BUFFER_CONFIG *post = &cm->post_proc_buffer;
   973     int width  = post->y_width;
   974     int height = post->y_height;
   975     uint8_t *y_ptr = cm->post_proc_buffer.y_buffer;
   976     uint8_t *u_ptr = cm->post_proc_buffer.u_buffer;
   977     uint8_t *v_ptr = cm->post_proc_buffer.v_buffer;
   978     int y_stride = cm->post_proc_buffer.y_stride;
   979     MODE_INFO *mi = cm->mi;
   981     for (y = 0; y < height; y += 16) {
   982       for (x = 0; x < width; x += 16) {
   983         int Y = 0, U = 0, V = 0;
   985         if (ppflags->display_ref_frame_flag & (1 << mi->mbmi.ref_frame)) {
   986           Y = MV_REFERENCE_FRAME_colors[mi->mbmi.ref_frame][0];
   987           U = MV_REFERENCE_FRAME_colors[mi->mbmi.ref_frame][1];
   988           V = MV_REFERENCE_FRAME_colors[mi->mbmi.ref_frame][2];
   990           vp9_blend_mb_outer(y_ptr + x, u_ptr + (x >> 1), v_ptr + (x >> 1),
   991                              Y, U, V, 0xc000, y_stride);
   992         }
   994         mi++;
   995       }
   996       y_ptr += y_stride * 16;
   997       u_ptr += y_stride * 4;
   998       v_ptr += y_stride * 4;
  1000       mi++;
  1003 #endif
  1005   *dest = cm->post_proc_buffer;
  1007   /* handle problem with extending borders */
  1008   dest->y_width = cm->width;
  1009   dest->y_height = cm->height;
  1010   dest->uv_width = dest->y_width >> cm->subsampling_x;
  1011   dest->uv_height = dest->y_height >> cm->subsampling_y;
  1013   return 0;

mercurial