1ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/*
2ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *
4ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  Use of this source code is governed by a BSD-style license
5ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  that can be found in the LICENSE file in the root of the source
6ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  tree. An additional intellectual property rights grant can be found
7ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  in the file PATENTS.  All contributing project authors may
8ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  be found in the AUTHORS file in the root of the source tree.
9ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang */
10ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
115ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#include <math.h>
125ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#include <stdlib.h>
135ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#include <stdio.h>
14ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
15ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "./vpx_config.h"
16b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "./vpx_scale_rtcd.h"
17b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "./vp9_rtcd.h"
18b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
19b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "vpx_scale/vpx_scale.h"
20ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vpx_scale/yv12config.h"
21b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
22b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "vp9/common/vp9_onyxc_int.h"
23ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/common/vp9_postproc.h"
24ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/common/vp9_systemdependent.h"
25b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "vp9/common/vp9_textblit.h"
26ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
27ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#define RGB_TO_YUV(t)                                            \
28ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  ( (0.257*(float)(t >> 16))  + (0.504*(float)(t >> 8 & 0xff)) + \
29ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    (0.098*(float)(t & 0xff)) + 16),                             \
30ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  (-(0.148*(float)(t >> 16))  - (0.291*(float)(t >> 8 & 0xff)) + \
31ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    (0.439*(float)(t & 0xff)) + 128),                            \
32ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  ( (0.439*(float)(t >> 16))  - (0.368*(float)(t >> 8 & 0xff)) - \
33ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    (0.071*(float)(t & 0xff)) + 128)
34ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
35ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/* global constants */
36ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#if 0 && CONFIG_POSTPROC_VISUALIZER
37ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic const unsigned char MB_PREDICTION_MODE_colors[MB_MODE_COUNT][3] = {
38ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  { RGB_TO_YUV(0x98FB98) },   /* PaleGreen */
39ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  { RGB_TO_YUV(0x00FF00) },   /* Green */
40ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  { RGB_TO_YUV(0xADFF2F) },   /* GreenYellow */
41ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  { RGB_TO_YUV(0x8F0000) },   /* Dark Red */
42ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  { RGB_TO_YUV(0x008F8F) },   /* Dark Cyan */
43ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  { RGB_TO_YUV(0x008F8F) },   /* Dark Cyan */
44ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  { RGB_TO_YUV(0x008F8F) },   /* Dark Cyan */
45ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  { RGB_TO_YUV(0x8F0000) },   /* Dark Red */
46ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  { RGB_TO_YUV(0x8F0000) },   /* Dark Red */
47ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  { RGB_TO_YUV(0x228B22) },   /* ForestGreen */
48ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  { RGB_TO_YUV(0x006400) },   /* DarkGreen */
49ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  { RGB_TO_YUV(0x98F5FF) },   /* Cadet Blue */
50ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  { RGB_TO_YUV(0x6CA6CD) },   /* Sky Blue */
51ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  { RGB_TO_YUV(0x00008B) },   /* Dark blue */
52ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  { RGB_TO_YUV(0x551A8B) },   /* Purple */
53ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  { RGB_TO_YUV(0xFF0000) }    /* Red */
54ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  { RGB_TO_YUV(0xCC33FF) },   /* Magenta */
55ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang};
56ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
571184aebb761cbeac9124c37189a80a1a58f04b6bhkuangstatic const unsigned char B_PREDICTION_MODE_colors[INTRA_MODES][3] = {
58ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  { RGB_TO_YUV(0x6633ff) },   /* Purple */
59ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  { RGB_TO_YUV(0xcc33ff) },   /* Magenta */
60ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  { RGB_TO_YUV(0xff33cc) },   /* Pink */
61ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  { RGB_TO_YUV(0xff3366) },   /* Coral */
62ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  { RGB_TO_YUV(0x3366ff) },   /* Blue */
63ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  { RGB_TO_YUV(0xed00f5) },   /* Dark Blue */
64ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  { RGB_TO_YUV(0x2e00b8) },   /* Dark Purple */
65ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  { RGB_TO_YUV(0xff6633) },   /* Orange */
66ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  { RGB_TO_YUV(0x33ccff) },   /* Light Blue */
67ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  { RGB_TO_YUV(0x8ab800) },   /* Green */
68ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  { RGB_TO_YUV(0xffcc33) },   /* Light Orange */
69ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  { RGB_TO_YUV(0x33ffcc) },   /* Aqua */
70ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  { RGB_TO_YUV(0x66ff33) },   /* Light Green */
71ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  { RGB_TO_YUV(0xccff33) },   /* Yellow */
72ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang};
73ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
74ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic const unsigned char MV_REFERENCE_FRAME_colors[MAX_REF_FRAMES][3] = {
75ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  { RGB_TO_YUV(0x00ff00) },   /* Blue */
76ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  { RGB_TO_YUV(0x0000ff) },   /* Green */
77ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  { RGB_TO_YUV(0xffff00) },   /* Yellow */
78ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  { RGB_TO_YUV(0xff0000) },   /* Red */
79ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang};
80ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#endif
81ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
82ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic const short kernel5[] = {
83ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  1, 1, 4, 1, 1
84ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang};
85ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
86ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangconst short vp9_rv[] = {
87ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  8, 5, 2, 2, 8, 12, 4, 9, 8, 3,
88ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  0, 3, 9, 0, 0, 0, 8, 3, 14, 4,
89ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  10, 1, 11, 14, 1, 14, 9, 6, 12, 11,
90ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  8, 6, 10, 0, 0, 8, 9, 0, 3, 14,
91ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  8, 11, 13, 4, 2, 9, 0, 3, 9, 6,
92ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  1, 2, 3, 14, 13, 1, 8, 2, 9, 7,
93ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  3, 3, 1, 13, 13, 6, 6, 5, 2, 7,
94ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  11, 9, 11, 8, 7, 3, 2, 0, 13, 13,
95ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  14, 4, 12, 5, 12, 10, 8, 10, 13, 10,
96ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  4, 14, 4, 10, 0, 8, 11, 1, 13, 7,
97ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  7, 14, 6, 14, 13, 2, 13, 5, 4, 4,
98ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  0, 10, 0, 5, 13, 2, 12, 7, 11, 13,
99ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  8, 0, 4, 10, 7, 2, 7, 2, 2, 5,
100ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  3, 4, 7, 3, 3, 14, 14, 5, 9, 13,
101ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  3, 14, 3, 6, 3, 0, 11, 8, 13, 1,
102ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  13, 1, 12, 0, 10, 9, 7, 6, 2, 8,
103ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  5, 2, 13, 7, 1, 13, 14, 7, 6, 7,
104ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  9, 6, 10, 11, 7, 8, 7, 5, 14, 8,
105ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  4, 4, 0, 8, 7, 10, 0, 8, 14, 11,
106ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  3, 12, 5, 7, 14, 3, 14, 5, 2, 6,
107ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  11, 12, 12, 8, 0, 11, 13, 1, 2, 0,
108ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  5, 10, 14, 7, 8, 0, 4, 11, 0, 8,
109ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  0, 3, 10, 5, 8, 0, 11, 6, 7, 8,
110ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  10, 7, 13, 9, 2, 5, 1, 5, 10, 2,
111ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  4, 3, 5, 6, 10, 8, 9, 4, 11, 14,
112ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  0, 10, 0, 5, 13, 2, 12, 7, 11, 13,
113ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  8, 0, 4, 10, 7, 2, 7, 2, 2, 5,
114ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  3, 4, 7, 3, 3, 14, 14, 5, 9, 13,
115ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  3, 14, 3, 6, 3, 0, 11, 8, 13, 1,
116ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  13, 1, 12, 0, 10, 9, 7, 6, 2, 8,
117ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  5, 2, 13, 7, 1, 13, 14, 7, 6, 7,
118ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  9, 6, 10, 11, 7, 8, 7, 5, 14, 8,
119ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  4, 4, 0, 8, 7, 10, 0, 8, 14, 11,
120ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  3, 12, 5, 7, 14, 3, 14, 5, 2, 6,
121ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  11, 12, 12, 8, 0, 11, 13, 1, 2, 0,
122ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  5, 10, 14, 7, 8, 0, 4, 11, 0, 8,
123ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  0, 3, 10, 5, 8, 0, 11, 6, 7, 8,
124ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  10, 7, 13, 9, 2, 5, 1, 5, 10, 2,
125ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  4, 3, 5, 6, 10, 8, 9, 4, 11, 14,
126ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  3, 8, 3, 7, 8, 5, 11, 4, 12, 3,
127ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  11, 9, 14, 8, 14, 13, 4, 3, 1, 2,
128ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  14, 6, 5, 4, 4, 11, 4, 6, 2, 1,
129ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  5, 8, 8, 12, 13, 5, 14, 10, 12, 13,
130ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  0, 9, 5, 5, 11, 10, 13, 9, 10, 13,
131ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang};
132ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
133ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangvoid vp9_post_proc_down_and_across_c(const uint8_t *src_ptr,
134ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                     uint8_t *dst_ptr,
135ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                     int src_pixels_per_line,
136ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                     int dst_pixels_per_line,
137ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                     int rows,
138ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                     int cols,
139ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                     int flimit) {
140ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  uint8_t const *p_src;
141ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  uint8_t *p_dst;
142ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int row;
143ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int col;
144ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int i;
145ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int v;
146ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int pitch = src_pixels_per_line;
147ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  uint8_t d[8];
148ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  (void)dst_pixels_per_line;
149ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
150ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (row = 0; row < rows; row++) {
151ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    /* post_proc_down for one row */
152ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    p_src = src_ptr;
153ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    p_dst = dst_ptr;
154ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
155ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (col = 0; col < cols; col++) {
156ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      int kernel = 4;
157ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      int v = p_src[col];
158ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
159ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      for (i = -2; i <= 2; i++) {
160ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        if (abs(v - p_src[col + i * pitch]) > flimit)
161ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          goto down_skip_convolve;
162ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
163ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        kernel += kernel5[2 + i] * p_src[col + i * pitch];
164ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
165ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
166ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      v = (kernel >> 3);
167ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    down_skip_convolve:
168ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      p_dst[col] = v;
169ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
170ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
171ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    /* now post_proc_across */
172ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    p_src = dst_ptr;
173ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    p_dst = dst_ptr;
174ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
175ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (i = 0; i < 8; i++)
176ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      d[i] = p_src[i];
177ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
178ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (col = 0; col < cols; col++) {
179ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      int kernel = 4;
180ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      v = p_src[col];
181ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
182ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      d[col & 7] = v;
183ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
184ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      for (i = -2; i <= 2; i++) {
185ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        if (abs(v - p_src[col + i]) > flimit)
186ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          goto across_skip_convolve;
187ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
188ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        kernel += kernel5[2 + i] * p_src[col + i];
189ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
190ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
191ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      d[col & 7] = (kernel >> 3);
192ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    across_skip_convolve:
193ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
194ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (col >= 2)
195ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        p_dst[col - 2] = d[(col - 2) & 7];
196ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
197ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
198ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    /* handle the last two pixels */
199ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    p_dst[col - 2] = d[(col - 2) & 7];
200ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    p_dst[col - 1] = d[(col - 1) & 7];
201ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
202ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
203ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    /* next row */
204ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    src_ptr += pitch;
205ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    dst_ptr += pitch;
206ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
207ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
208ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
209ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic int q2mbl(int x) {
210ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (x < 20) x = 20;
211ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
212ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  x = 50 + (x - 50) * 10 / 8;
213ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return x * x / 3;
214ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
215ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
216ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangvoid vp9_mbpost_proc_across_ip_c(uint8_t *src, int pitch,
217ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                 int rows, int cols, int flimit) {
218ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int r, c, i;
219ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
220ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  uint8_t *s = src;
221ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  uint8_t d[16];
222ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
223ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
224ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (r = 0; r < rows; r++) {
225ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int sumsq = 0;
226ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int sum   = 0;
227ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
228ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (i = -8; i <= 6; i++) {
229ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      sumsq += s[i] * s[i];
230ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      sum   += s[i];
231ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      d[i + 8] = 0;
232ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
233ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
234ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (c = 0; c < cols + 8; c++) {
235ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      int x = s[c + 7] - s[c - 8];
236ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      int y = s[c + 7] + s[c - 8];
237ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
238ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      sum  += x;
239ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      sumsq += x * y;
240ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
241ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      d[c & 15] = s[c];
242ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
243ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (sumsq * 15 - sum * sum < flimit) {
244ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        d[c & 15] = (8 + sum + s[c]) >> 4;
245ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
246ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
247ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      s[c - 8] = d[(c - 8) & 15];
248ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
249ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
250ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    s += pitch;
251ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
252ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
253ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
254ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangvoid vp9_mbpost_proc_down_c(uint8_t *dst, int pitch,
255ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                            int rows, int cols, int flimit) {
256ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int r, c, i;
2575ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  const short *rv3 = &vp9_rv[63 & rand()]; // NOLINT
258ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
259ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (c = 0; c < cols; c++) {
260ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    uint8_t *s = &dst[c];
261ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int sumsq = 0;
262ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int sum   = 0;
263ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    uint8_t d[16];
264ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    const short *rv2 = rv3 + ((c * 17) & 127);
265ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
266ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (i = -8; i <= 6; i++) {
267ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      sumsq += s[i * pitch] * s[i * pitch];
268ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      sum   += s[i * pitch];
269ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
270ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
271ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (r = 0; r < rows + 8; r++) {
272ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      sumsq += s[7 * pitch] * s[ 7 * pitch] - s[-8 * pitch] * s[-8 * pitch];
273ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      sum  += s[7 * pitch] - s[-8 * pitch];
274ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      d[r & 15] = s[0];
275ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
276ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (sumsq * 15 - sum * sum < flimit) {
277ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        d[r & 15] = (rv2[r & 127] + sum + s[0]) >> 4;
278ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
279ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
280ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      s[-8 * pitch] = d[(r - 8) & 15];
281ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      s += pitch;
282ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
283ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
284ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
285ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
286ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void deblock_and_de_macro_block(YV12_BUFFER_CONFIG   *source,
287ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                       YV12_BUFFER_CONFIG   *post,
288ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                       int                   q,
289ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                       int                   low_var_thresh,
290ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                       int                   flag) {
291ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  double level = 6.0e-05 * q * q * q - .0067 * q * q + .306 * q + .0065;
292ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int ppl = (int)(level + .5);
293ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  (void) low_var_thresh;
294ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  (void) flag;
295ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
296ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  vp9_post_proc_down_and_across(source->y_buffer, post->y_buffer,
297ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                source->y_stride, post->y_stride,
298ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                source->y_height, source->y_width, ppl);
299ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
300ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  vp9_mbpost_proc_across_ip(post->y_buffer, post->y_stride, post->y_height,
301ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                            post->y_width, q2mbl(q));
302ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
303ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  vp9_mbpost_proc_down(post->y_buffer, post->y_stride, post->y_height,
304ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                       post->y_width, q2mbl(q));
305ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
306ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  vp9_post_proc_down_and_across(source->u_buffer, post->u_buffer,
307ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                source->uv_stride, post->uv_stride,
308ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                source->uv_height, source->uv_width, ppl);
309ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  vp9_post_proc_down_and_across(source->v_buffer, post->v_buffer,
310ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                source->uv_stride, post->uv_stride,
311ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                source->uv_height, source->uv_width, ppl);
312ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
313ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
314ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangvoid vp9_deblock(const YV12_BUFFER_CONFIG *src, YV12_BUFFER_CONFIG *dst,
315ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                 int q) {
316ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const int ppl = (int)(6.0e-05 * q * q * q - 0.0067 * q * q + 0.306 * q
317ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                        + 0.0065 + 0.5);
318ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int i;
319ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
320ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const uint8_t *const srcs[4] = {src->y_buffer, src->u_buffer, src->v_buffer,
321ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                  src->alpha_buffer};
322ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const int src_strides[4] = {src->y_stride, src->uv_stride, src->uv_stride,
323ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                              src->alpha_stride};
324ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const int src_widths[4] = {src->y_width, src->uv_width, src->uv_width,
325ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                             src->alpha_width};
326ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const int src_heights[4] = {src->y_height, src->uv_height, src->uv_height,
327ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                              src->alpha_height};
328ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
329ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  uint8_t *const dsts[4] = {dst->y_buffer, dst->u_buffer, dst->v_buffer,
330ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                            dst->alpha_buffer};
331ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const int dst_strides[4] = {dst->y_stride, dst->uv_stride, dst->uv_stride,
332ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                              dst->alpha_stride};
333ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
334ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (i = 0; i < MAX_MB_PLANE; ++i)
335ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    vp9_post_proc_down_and_across(srcs[i], dsts[i],
336ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                  src_strides[i], dst_strides[i],
337ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                  src_heights[i], src_widths[i], ppl);
338ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
339ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
340ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangvoid vp9_denoise(const YV12_BUFFER_CONFIG *src, YV12_BUFFER_CONFIG *dst,
341ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                 int q) {
342ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const int ppl = (int)(6.0e-05 * q * q * q - 0.0067 * q * q + 0.306 * q
343ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                        + 0.0065 + 0.5);
344ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int i;
345ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
346ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const uint8_t *const srcs[4] = {src->y_buffer, src->u_buffer, src->v_buffer,
347ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                  src->alpha_buffer};
348ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const int src_strides[4] = {src->y_stride, src->uv_stride, src->uv_stride,
349ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                              src->alpha_stride};
350ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const int src_widths[4] = {src->y_width, src->uv_width, src->uv_width,
351ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                             src->alpha_width};
352ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const int src_heights[4] = {src->y_height, src->uv_height, src->uv_height,
353ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                              src->alpha_height};
354ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
355ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  uint8_t *const dsts[4] = {dst->y_buffer, dst->u_buffer, dst->v_buffer,
356ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                            dst->alpha_buffer};
357ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const int dst_strides[4] = {dst->y_stride, dst->uv_stride, dst->uv_stride,
358ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                              dst->alpha_stride};
359ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
360ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (i = 0; i < MAX_MB_PLANE; ++i) {
361ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    const int src_stride = src_strides[i];
362ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    const uint8_t *const src = srcs[i] + 2 * src_stride + 2;
363ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    const int src_width = src_widths[i] - 4;
364ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    const int src_height = src_heights[i] - 4;
365ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
366ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    const int dst_stride = dst_strides[i];
367ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    uint8_t *const dst = dsts[i] + 2 * dst_stride + 2;
368ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
369ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    vp9_post_proc_down_and_across(src, dst, src_stride, dst_stride,
370ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                  src_height, src_width, ppl);
371ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
372ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
373ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
374b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic double gaussian(double sigma, double mu, double x) {
375ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return 1 / (sigma * sqrt(2.0 * 3.14159265)) *
376ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang         (exp(-(x - mu) * (x - mu) / (2 * sigma * sigma)));
377ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
378ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
379ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void fillrd(struct postproc_state *state, int q, int a) {
380ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  char char_dist[300];
381ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
382ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  double sigma;
383ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int ai = a, qi = q, i;
384ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
385ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  vp9_clear_system_state();
386ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
387ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  sigma = ai + .5 + .6 * (63 - qi) / 63.0;
388ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
389ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  /* set up a lookup table of 256 entries that matches
390ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang   * a gaussian distribution with sigma determined by q.
391ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang   */
392ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  {
393ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    double i;
394ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int next, j;
395ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
396ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    next = 0;
397ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
398ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (i = -32; i < 32; i++) {
399b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      int a = (int)(0.5 + 256 * gaussian(sigma, 0, i));
400ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
401ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (a) {
402ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        for (j = 0; j < a; j++) {
403ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          char_dist[next + j] = (char) i;
404ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        }
405ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
406ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        next = next + j;
407ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
408ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
409ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
41091037db265ecdd914a26e056cf69207b4f50924ehkuang    for (; next < 256; next++)
411ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      char_dist[next] = 0;
412ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
413ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
414ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (i = 0; i < 3072; i++) {
4155ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    state->noise[i] = char_dist[rand() & 0xff];  // NOLINT
416ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
417ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
418ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (i = 0; i < 16; i++) {
419ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    state->blackclamp[i] = -char_dist[0];
420ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    state->whiteclamp[i] = -char_dist[0];
421ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    state->bothclamp[i] = -2 * char_dist[0];
422ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
423ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
424ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  state->last_q = q;
425ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  state->last_noise = a;
426ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
427ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
428ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangvoid vp9_plane_add_noise_c(uint8_t *start, char *noise,
429ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                           char blackclamp[16],
430ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                           char whiteclamp[16],
431ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                           char bothclamp[16],
432ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                           unsigned int width, unsigned int height, int pitch) {
433ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  unsigned int i, j;
434ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
435ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (i = 0; i < height; i++) {
436ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    uint8_t *pos = start + i * pitch;
437ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    char  *ref = (char *)(noise + (rand() & 0xff));  // NOLINT
438ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
439ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (j = 0; j < width; j++) {
440ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (pos[j] < blackclamp[0])
441ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        pos[j] = blackclamp[0];
442ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
443ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (pos[j] > 255 + whiteclamp[0])
444ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        pos[j] = 255 + whiteclamp[0];
445ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
446ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      pos[j] += ref[j];
447ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
448ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
449ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
450ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
451ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/* Blend the macro block with a solid colored square.  Leave the
452ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * edges unblended to give distinction to macro blocks in areas
453ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * filled with the same color block.
454ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang */
455ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangvoid vp9_blend_mb_inner_c(uint8_t *y, uint8_t *u, uint8_t *v,
456ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                          int y1, int u1, int v1, int alpha, int stride) {
457ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int i, j;
458ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int y1_const = y1 * ((1 << 16) - alpha);
459ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int u1_const = u1 * ((1 << 16) - alpha);
460ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int v1_const = v1 * ((1 << 16) - alpha);
461ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
462ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  y += 2 * stride + 2;
463ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (i = 0; i < 12; i++) {
464ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (j = 0; j < 12; j++) {
465ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      y[j] = (y[j] * alpha + y1_const) >> 16;
466ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
467ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    y += stride;
468ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
469ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
470ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  stride >>= 1;
471ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
472ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  u += stride + 1;
473ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  v += stride + 1;
474ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
475ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (i = 0; i < 6; i++) {
476ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (j = 0; j < 6; j++) {
477ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      u[j] = (u[j] * alpha + u1_const) >> 16;
478ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      v[j] = (v[j] * alpha + v1_const) >> 16;
479ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
480ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    u += stride;
481ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    v += stride;
482ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
483ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
484ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
485ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/* Blend only the edge of the macro block.  Leave center
486ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * unblended to allow for other visualizations to be layered.
487ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang */
488ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangvoid vp9_blend_mb_outer_c(uint8_t *y, uint8_t *u, uint8_t *v,
489ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                          int y1, int u1, int v1, int alpha, int stride) {
490ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int i, j;
491ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int y1_const = y1 * ((1 << 16) - alpha);
492ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int u1_const = u1 * ((1 << 16) - alpha);
493ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int v1_const = v1 * ((1 << 16) - alpha);
494ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
495ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (i = 0; i < 2; i++) {
496ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (j = 0; j < 16; j++) {
497ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      y[j] = (y[j] * alpha + y1_const) >> 16;
498ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
499ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    y += stride;
500ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
501ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
502ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (i = 0; i < 12; i++) {
503ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    y[0]  = (y[0] * alpha  + y1_const) >> 16;
504ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    y[1]  = (y[1] * alpha  + y1_const) >> 16;
505ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    y[14] = (y[14] * alpha + y1_const) >> 16;
506ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    y[15] = (y[15] * alpha + y1_const) >> 16;
507ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    y += stride;
508ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
509ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
510ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (i = 0; i < 2; i++) {
511ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (j = 0; j < 16; j++) {
512ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      y[j] = (y[j] * alpha + y1_const) >> 16;
513ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
514ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    y += stride;
515ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
516ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
517ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  stride >>= 1;
518ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
519ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (j = 0; j < 8; j++) {
520ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    u[j] = (u[j] * alpha + u1_const) >> 16;
521ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    v[j] = (v[j] * alpha + v1_const) >> 16;
522ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
523ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  u += stride;
524ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  v += stride;
525ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
526ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (i = 0; i < 6; i++) {
527ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    u[0] = (u[0] * alpha + u1_const) >> 16;
528ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    v[0] = (v[0] * alpha + v1_const) >> 16;
529ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
530ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    u[7] = (u[7] * alpha + u1_const) >> 16;
531ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    v[7] = (v[7] * alpha + v1_const) >> 16;
532ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
533ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    u += stride;
534ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    v += stride;
535ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
536ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
537ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (j = 0; j < 8; j++) {
538ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    u[j] = (u[j] * alpha + u1_const) >> 16;
539ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    v[j] = (v[j] * alpha + v1_const) >> 16;
540ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
541ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
542ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
543ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangvoid vp9_blend_b_c(uint8_t *y, uint8_t *u, uint8_t *v,
544ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                   int y1, int u1, int v1, int alpha, int stride) {
545ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int i, j;
546ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int y1_const = y1 * ((1 << 16) - alpha);
547ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int u1_const = u1 * ((1 << 16) - alpha);
548ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int v1_const = v1 * ((1 << 16) - alpha);
549ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
550ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (i = 0; i < 4; i++) {
551ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (j = 0; j < 4; j++) {
552ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      y[j] = (y[j] * alpha + y1_const) >> 16;
553ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
554ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    y += stride;
555ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
556ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
557ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  stride >>= 1;
558ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
559ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (i = 0; i < 2; i++) {
560ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (j = 0; j < 2; j++) {
561ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      u[j] = (u[j] * alpha + u1_const) >> 16;
562ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      v[j] = (v[j] * alpha + v1_const) >> 16;
563ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
564ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    u += stride;
565ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    v += stride;
566ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
567ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
568ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
569ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void constrain_line(int x0, int *x1, int y0, int *y1,
570ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                           int width, int height) {
571ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int dx;
572ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int dy;
573ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
574ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (*x1 > width) {
575ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    dx = *x1 - x0;
576ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    dy = *y1 - y0;
577ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
578ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    *x1 = width;
579ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (dx)
580ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      *y1 = ((width - x0) * dy) / dx + y0;
581ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
582ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (*x1 < 0) {
583ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    dx = *x1 - x0;
584ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    dy = *y1 - y0;
585ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
586ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    *x1 = 0;
587ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (dx)
588ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      *y1 = ((0 - x0) * dy) / dx + y0;
589ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
590ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (*y1 > height) {
591ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    dx = *x1 - x0;
592ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    dy = *y1 - y0;
593ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
594ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    *y1 = height;
595ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (dy)
596ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      *x1 = ((height - y0) * dx) / dy + x0;
597ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
598ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (*y1 < 0) {
599ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    dx = *x1 - x0;
600ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    dy = *y1 - y0;
601ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
602ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    *y1 = 0;
603ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (dy)
604ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      *x1 = ((0 - y0) * dx) / dy + x0;
605ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
606ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
607ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
6081184aebb761cbeac9124c37189a80a1a58f04b6bhkuangint vp9_post_proc_frame(struct VP9Common *cm,
6091184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                        YV12_BUFFER_CONFIG *dest, vp9_ppflags_t *ppflags) {
610b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const int q = MIN(63, cm->lf.filter_level * 10 / 6);
611b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const int flags = ppflags->post_proc_flag;
612b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  YV12_BUFFER_CONFIG *const ppbuf = &cm->post_proc_buffer;
613b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  struct postproc_state *const ppstate = &cm->postproc_state;
614ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
6151184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  if (!cm->frame_to_show)
616ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    return -1;
617ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
618ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (!flags) {
6191184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    *dest = *cm->frame_to_show;
620ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    return 0;
621ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
622ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
623b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  vp9_clear_system_state();
624ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
625ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (flags & VP9D_DEMACROBLOCK) {
626b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    deblock_and_de_macro_block(cm->frame_to_show, ppbuf,
627b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                               q + (ppflags->deblocking_level - 5) * 10, 1, 0);
628ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  } else if (flags & VP9D_DEBLOCK) {
629b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    vp9_deblock(cm->frame_to_show, ppbuf, q);
630ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  } else {
631b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    vp8_yv12_copy_frame(cm->frame_to_show, ppbuf);
632ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
633ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
634ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (flags & VP9D_ADDNOISE) {
635b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    const int noise_level = ppflags->noise_level;
636b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (ppstate->last_q != q ||
637b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        ppstate->last_noise != noise_level) {
638b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      fillrd(ppstate, 63 - q, noise_level);
639ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
640ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
641b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    vp9_plane_add_noise(ppbuf->y_buffer, ppstate->noise, ppstate->blackclamp,
642b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                        ppstate->whiteclamp, ppstate->bothclamp,
643b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                        ppbuf->y_width, ppbuf->y_height, ppbuf->y_stride);
644ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
645ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
646ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#if 0 && CONFIG_POSTPROC_VISUALIZER
647ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (flags & VP9D_DEBUG_TXT_FRAME_INFO) {
648ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    char message[512];
6495ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    snprintf(message, sizeof(message) -1,
6505ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang             "F%1dG%1dQ%3dF%3dP%d_s%dx%d",
6515ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang             (cm->frame_type == KEY_FRAME),
6525ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang             cm->refresh_golden_frame,
6535ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang             cm->base_qindex,
6545ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang             cm->filter_level,
6555ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang             flags,
6565ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang             cm->mb_cols, cm->mb_rows);
657b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    vp9_blit_text(message, ppbuf->y_buffer, ppbuf->y_stride);
658ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
659ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
660ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (flags & VP9D_DEBUG_TXT_MBLK_MODES) {
661ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int i, j;
662ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    uint8_t *y_ptr;
663b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    int mb_rows = ppbuf->y_height >> 4;
664b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    int mb_cols = ppbuf->y_width  >> 4;
665ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int mb_index = 0;
6661184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    MODE_INFO *mi = cm->mi;
667ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
668ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    y_ptr = post->y_buffer + 4 * post->y_stride + 4;
669ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
670ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    /* vp9_filter each macro block */
671ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (i = 0; i < mb_rows; i++) {
672ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      for (j = 0; j < mb_cols; j++) {
673ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        char zz[4];
674ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
6755ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        snprintf(zz, sizeof(zz) - 1, "%c", mi[mb_index].mbmi.mode + 'a');
676ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
677ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        vp9_blit_text(zz, y_ptr, post->y_stride);
678ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        mb_index++;
679ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        y_ptr += 16;
680ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
681ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
682ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      mb_index++; /* border */
683ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      y_ptr += post->y_stride  * 16 - post->y_width;
684ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
685ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
686ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
687ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (flags & VP9D_DEBUG_TXT_DC_DIFF) {
688ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int i, j;
689ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    uint8_t *y_ptr;
690b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    int mb_rows = ppbuf->y_height >> 4;
691b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    int mb_cols = ppbuf->y_width  >> 4;
692ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int mb_index = 0;
6931184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    MODE_INFO *mi = cm->mi;
694ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
695ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    y_ptr = post->y_buffer + 4 * post->y_stride + 4;
696ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
697ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    /* vp9_filter each macro block */
698ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (i = 0; i < mb_rows; i++) {
699ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      for (j = 0; j < mb_cols; j++) {
700ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        char zz[4];
701ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        int dc_diff = !(mi[mb_index].mbmi.mode != I4X4_PRED &&
702ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                        mi[mb_index].mbmi.mode != SPLITMV &&
703b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                        mi[mb_index].mbmi.skip);
704ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
7051184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        if (cm->frame_type == KEY_FRAME)
7065ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          snprintf(zz, sizeof(zz) - 1, "a");
707ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        else
7085ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          snprintf(zz, sizeof(zz) - 1, "%c", dc_diff + '0');
709ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
710ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        vp9_blit_text(zz, y_ptr, post->y_stride);
711ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        mb_index++;
712ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        y_ptr += 16;
713ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
714ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
715ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      mb_index++; /* border */
716ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      y_ptr += post->y_stride  * 16 - post->y_width;
717ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
718ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
719ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
720ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (flags & VP9D_DEBUG_TXT_RATE_INFO) {
721ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    char message[512];
722ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    snprintf(message, sizeof(message),
72391037db265ecdd914a26e056cf69207b4f50924ehkuang             "Bitrate: %10.2f framerate: %10.2f ",
7241184aebb761cbeac9124c37189a80a1a58f04b6bhkuang             cm->bitrate, cm->framerate);
725b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    vp9_blit_text(message, ppbuf->y_buffer, ppbuf->y_stride);
726ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
727ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
728ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  /* Draw motion vectors */
729ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if ((flags & VP9D_DEBUG_DRAW_MV) && ppflags->display_mv_flag) {
730b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    int width  = ppbuf->y_width;
731b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    int height = ppbuf->y_height;
732b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    uint8_t *y_buffer = ppbuf->y_buffer;
733b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    int y_stride = ppbuf->y_stride;
7341184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    MODE_INFO *mi = cm->mi;
735ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int x0, y0;
736ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
737ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (y0 = 0; y0 < height; y0 += 16) {
738ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      for (x0 = 0; x0 < width; x0 += 16) {
739ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        int x1, y1;
740ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
741ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        if (!(ppflags->display_mv_flag & (1 << mi->mbmi.mode))) {
742ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          mi++;
743ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          continue;
744ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        }
745ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
746ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        if (mi->mbmi.mode == SPLITMV) {
747ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          switch (mi->mbmi.partitioning) {
748ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            case PARTITIONING_16X8 : {  /* mv_top_bottom */
749ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              union b_mode_info *bmi = &mi->bmi[0];
750ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              MV *mv = &bmi->mv.as_mv;
751ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
752ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              x1 = x0 + 8 + (mv->col >> 3);
753ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              y1 = y0 + 4 + (mv->row >> 3);
754ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
755ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              constrain_line(x0 + 8, &x1, y0 + 4, &y1, width, height);
756ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              vp9_blit_line(x0 + 8,  x1, y0 + 4,  y1, y_buffer, y_stride);
757ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
758ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              bmi = &mi->bmi[8];
759ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
760ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              x1 = x0 + 8 + (mv->col >> 3);
761ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              y1 = y0 + 12 + (mv->row >> 3);
762ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
763ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              constrain_line(x0 + 8, &x1, y0 + 12, &y1, width, height);
764ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              vp9_blit_line(x0 + 8,  x1, y0 + 12,  y1, y_buffer, y_stride);
765ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
766ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              break;
767ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            }
768ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            case PARTITIONING_8X16 : {  /* mv_left_right */
769ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              union b_mode_info *bmi = &mi->bmi[0];
770ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              MV *mv = &bmi->mv.as_mv;
771ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
772ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              x1 = x0 + 4 + (mv->col >> 3);
773ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              y1 = y0 + 8 + (mv->row >> 3);
774ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
775ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              constrain_line(x0 + 4, &x1, y0 + 8, &y1, width, height);
776ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              vp9_blit_line(x0 + 4,  x1, y0 + 8,  y1, y_buffer, y_stride);
777ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
778ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              bmi = &mi->bmi[2];
779ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
780ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              x1 = x0 + 12 + (mv->col >> 3);
781ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              y1 = y0 + 8 + (mv->row >> 3);
782ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
783ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              constrain_line(x0 + 12, &x1, y0 + 8, &y1, width, height);
784ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              vp9_blit_line(x0 + 12,  x1, y0 + 8,  y1, y_buffer, y_stride);
785ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
786ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              break;
787ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            }
788ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            case PARTITIONING_8X8 : {  /* mv_quarters   */
789ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              union b_mode_info *bmi = &mi->bmi[0];
790ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              MV *mv = &bmi->mv.as_mv;
791ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
792ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              x1 = x0 + 4 + (mv->col >> 3);
793ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              y1 = y0 + 4 + (mv->row >> 3);
794ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
795ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              constrain_line(x0 + 4, &x1, y0 + 4, &y1, width, height);
796ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              vp9_blit_line(x0 + 4,  x1, y0 + 4,  y1, y_buffer, y_stride);
797ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
798ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              bmi = &mi->bmi[2];
799ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
800ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              x1 = x0 + 12 + (mv->col >> 3);
801ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              y1 = y0 + 4 + (mv->row >> 3);
802ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
803ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              constrain_line(x0 + 12, &x1, y0 + 4, &y1, width, height);
804ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              vp9_blit_line(x0 + 12,  x1, y0 + 4,  y1, y_buffer, y_stride);
805ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
806ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              bmi = &mi->bmi[8];
807ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
808ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              x1 = x0 + 4 + (mv->col >> 3);
809ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              y1 = y0 + 12 + (mv->row >> 3);
810ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
811ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              constrain_line(x0 + 4, &x1, y0 + 12, &y1, width, height);
812ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              vp9_blit_line(x0 + 4,  x1, y0 + 12,  y1, y_buffer, y_stride);
813ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
814ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              bmi = &mi->bmi[10];
815ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
816ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              x1 = x0 + 12 + (mv->col >> 3);
817ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              y1 = y0 + 12 + (mv->row >> 3);
818ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
819ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              constrain_line(x0 + 12, &x1, y0 + 12, &y1, width, height);
820ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              vp9_blit_line(x0 + 12,  x1, y0 + 12,  y1, y_buffer, y_stride);
821ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              break;
822ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            }
823ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            case PARTITIONING_4X4:
824ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            default : {
825ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              union b_mode_info *bmi = mi->bmi;
826ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              int bx0, by0;
827ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
828ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              for (by0 = y0; by0 < (y0 + 16); by0 += 4) {
829ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                for (bx0 = x0; bx0 < (x0 + 16); bx0 += 4) {
830ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                  MV *mv = &bmi->mv.as_mv;
831ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
832ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                  x1 = bx0 + 2 + (mv->col >> 3);
833ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                  y1 = by0 + 2 + (mv->row >> 3);
834ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
835ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                  constrain_line(bx0 + 2, &x1, by0 + 2, &y1, width, height);
836ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                  vp9_blit_line(bx0 + 2,  x1, by0 + 2,  y1, y_buffer, y_stride);
837ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
838ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                  bmi++;
839ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                }
840ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              }
841ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            }
842ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          }
8431184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        } else if (is_inter_mode(mi->mbmi.mode)) {
844ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          MV *mv = &mi->mbmi.mv.as_mv;
845ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          const int lx0 = x0 + 8;
846ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          const int ly0 = y0 + 8;
847ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
848ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          x1 = lx0 + (mv->col >> 3);
849ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          y1 = ly0 + (mv->row >> 3);
850ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
851ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          if (x1 != lx0 && y1 != ly0) {
852ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            constrain_line(lx0, &x1, ly0 - 1, &y1, width, height);
853ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            vp9_blit_line(lx0,  x1, ly0 - 1,  y1, y_buffer, y_stride);
854ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
855ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            constrain_line(lx0, &x1, ly0 + 1, &y1, width, height);
856ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            vp9_blit_line(lx0,  x1, ly0 + 1,  y1, y_buffer, y_stride);
8575ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          } else {
858ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            vp9_blit_line(lx0,  x1, ly0,  y1, y_buffer, y_stride);
8595ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          }
860ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        }
861ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
862ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        mi++;
863ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
864ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      mi++;
865ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
866ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
867ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
868ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  /* Color in block modes */
869ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if ((flags & VP9D_DEBUG_CLR_BLK_MODES)
870ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      && (ppflags->display_mb_modes_flag || ppflags->display_b_modes_flag)) {
871ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int y, x;
872b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    int width  = ppbuf->y_width;
873b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    int height = ppbuf->y_height;
874b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    uint8_t *y_ptr = ppbuf->y_buffer;
875b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    uint8_t *u_ptr = ppbuf->u_buffer;
876b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    uint8_t *v_ptr = ppbuf->v_buffer;
877b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    int y_stride = ppbuf->y_stride;
8781184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    MODE_INFO *mi = cm->mi;
879ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
880ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (y = 0; y < height; y += 16) {
881ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      for (x = 0; x < width; x += 16) {
882ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        int Y = 0, U = 0, V = 0;
883ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
884ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        if (mi->mbmi.mode == I4X4_PRED &&
885ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            ((ppflags->display_mb_modes_flag & I4X4_PRED) ||
886ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang             ppflags->display_b_modes_flag)) {
887ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          int by, bx;
888ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          uint8_t *yl, *ul, *vl;
889ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          union b_mode_info *bmi = mi->bmi;
890ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
891ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          yl = y_ptr + x;
892ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          ul = u_ptr + (x >> 1);
893ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          vl = v_ptr + (x >> 1);
894ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
895ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          for (by = 0; by < 16; by += 4) {
896ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            for (bx = 0; bx < 16; bx += 4) {
897ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              if ((ppflags->display_b_modes_flag & (1 << mi->mbmi.mode))
898ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                  || (ppflags->display_mb_modes_flag & I4X4_PRED)) {
89991037db265ecdd914a26e056cf69207b4f50924ehkuang                Y = B_PREDICTION_MODE_colors[bmi->as_mode][0];
90091037db265ecdd914a26e056cf69207b4f50924ehkuang                U = B_PREDICTION_MODE_colors[bmi->as_mode][1];
90191037db265ecdd914a26e056cf69207b4f50924ehkuang                V = B_PREDICTION_MODE_colors[bmi->as_mode][2];
902ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
903ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                vp9_blend_b(yl + bx, ul + (bx >> 1), vl + (bx >> 1), Y, U, V,
904ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                    0xc000, y_stride);
905ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              }
906ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              bmi++;
907ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            }
908ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
909ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            yl += y_stride * 4;
910ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            ul += y_stride * 1;
911ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            vl += y_stride * 1;
912ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          }
913ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        } else if (ppflags->display_mb_modes_flag & (1 << mi->mbmi.mode)) {
914ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          Y = MB_PREDICTION_MODE_colors[mi->mbmi.mode][0];
915ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          U = MB_PREDICTION_MODE_colors[mi->mbmi.mode][1];
916ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          V = MB_PREDICTION_MODE_colors[mi->mbmi.mode][2];
917ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
918ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          vp9_blend_mb_inner(y_ptr + x, u_ptr + (x >> 1), v_ptr + (x >> 1),
919ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                             Y, U, V, 0xc000, y_stride);
920ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        }
921ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
922ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        mi++;
923ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
924ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      y_ptr += y_stride * 16;
925ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      u_ptr += y_stride * 4;
926ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      v_ptr += y_stride * 4;
927ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
928ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      mi++;
929ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
930ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
931ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
932ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  /* Color in frame reference blocks */
933ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if ((flags & VP9D_DEBUG_CLR_FRM_REF_BLKS) &&
934ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      ppflags->display_ref_frame_flag) {
935ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int y, x;
936b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    int width  = ppbuf->y_width;
937b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    int height = ppbuf->y_height;
938b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    uint8_t *y_ptr = ppbuf->y_buffer;
939b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    uint8_t *u_ptr = ppbuf->u_buffer;
940b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    uint8_t *v_ptr = ppbuf->v_buffer;
941b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    int y_stride = ppbuf->y_stride;
9421184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    MODE_INFO *mi = cm->mi;
943ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
944ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (y = 0; y < height; y += 16) {
945ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      for (x = 0; x < width; x += 16) {
946ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        int Y = 0, U = 0, V = 0;
947ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
948ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        if (ppflags->display_ref_frame_flag & (1 << mi->mbmi.ref_frame)) {
949ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          Y = MV_REFERENCE_FRAME_colors[mi->mbmi.ref_frame][0];
950ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          U = MV_REFERENCE_FRAME_colors[mi->mbmi.ref_frame][1];
951ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          V = MV_REFERENCE_FRAME_colors[mi->mbmi.ref_frame][2];
952ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
953ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          vp9_blend_mb_outer(y_ptr + x, u_ptr + (x >> 1), v_ptr + (x >> 1),
954ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                             Y, U, V, 0xc000, y_stride);
955ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        }
956ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
957ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        mi++;
958ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
959ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      y_ptr += y_stride * 16;
960ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      u_ptr += y_stride * 4;
961ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      v_ptr += y_stride * 4;
962ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
963ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      mi++;
964ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
965ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
966ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#endif
967ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
968b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  *dest = *ppbuf;
969ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
970ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  /* handle problem with extending borders */
9711184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  dest->y_width = cm->width;
9721184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  dest->y_height = cm->height;
9731184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  dest->uv_width = dest->y_width >> cm->subsampling_x;
9741184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  dest->uv_height = dest->y_height >> cm->subsampling_y;
975ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
976ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return 0;
977ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
978