1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13 * express or implied.
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
17 */
18 #include "mp4dec_lib.h"
19 #include "post_proc.h"
20
21 #ifdef PV_POSTPROC_ON
22
Deringing_Chroma(uint8 * Rec_C,int width,int height,int16 * QP_store,int,uint8 * pp_mod)23 void Deringing_Chroma(
24 uint8 *Rec_C,
25 int width,
26 int height,
27 int16 *QP_store,
28 int,
29 uint8 *pp_mod
30 )
31 {
32 /*----------------------------------------------------------------------------
33 ; Define all local variables
34 ----------------------------------------------------------------------------*/
35 int thres;
36 int v_blk, h_blk;
37 int max_diff;
38 int v_pel, h_pel;
39 int max_blk, min_blk;
40 int v0, h0;
41 uint8 *ptr;
42 int sum, sum1, incr;
43 int32 addr_v;
44 int sign_v[10], sum_v[10];
45 int *ptr2, *ptr3;
46 uint8 pelu, pelc, pell;
47 incr = width - BLKSIZE;
48
49 /*----------------------------------------------------------------------------
50 ; Function body here
51 ----------------------------------------------------------------------------*/
52 /* chrominance */
53 /* Do the first line (7 pixels at a time => Don't use MMX)*/
54 for (h_blk = 0; h_blk < width; h_blk += BLKSIZE)
55 {
56 max_diff = (QP_store[h_blk>>3] >> 2) + 4;
57 ptr = &Rec_C[h_blk];
58 max_blk = min_blk = *ptr;
59 FindMaxMin(ptr, &min_blk, &max_blk, width);
60 h0 = ((h_blk - 1) >= 1) ? (h_blk - 1) : 1;
61
62 if (max_blk - min_blk >= 4)
63 {
64 thres = (max_blk + min_blk + 1) >> 1;
65
66
67 for (v_pel = 1; v_pel < BLKSIZE - 1; v_pel++)
68 {
69 addr_v = (int32)v_pel * width;
70 ptr = &Rec_C[addr_v + h0 - 1];
71 ptr2 = &sum_v[0];
72 ptr3 = &sign_v[0];
73
74 pelu = *(ptr - width);
75 pelc = *ptr;
76 pell = *(ptr + width);
77 ptr++;
78 *ptr2++ = pelu + (pelc << 1) + pell;
79 *ptr3++ = INDEX(pelu, thres) + INDEX(pelc, thres) + INDEX(pell, thres);
80
81 pelu = *(ptr - width);
82 pelc = *ptr;
83 pell = *(ptr + width);
84 ptr++;
85 *ptr2++ = pelu + (pelc << 1) + pell;
86 *ptr3++ = INDEX(pelu, thres) + INDEX(pelc, thres) + INDEX(pell, thres);
87
88 for (h_pel = h0; h_pel < h_blk + BLKSIZE - 1; h_pel++)
89 {
90 pelu = *(ptr - width);
91 pelc = *ptr;
92 pell = *(ptr + width);
93
94 *ptr2 = pelu + (pelc << 1) + pell;
95 *ptr3 = INDEX(pelu, thres) + INDEX(pelc, thres) + INDEX(pell, thres);
96
97 sum1 = *(ptr3 - 2) + *(ptr3 - 1) + *ptr3;
98 if (sum1 == 0 || sum1 == 9)
99 {
100 sum = (*(ptr2 - 2) + (*(ptr2 - 1) << 1) + *ptr2 + 8) >> 4;
101
102 ptr--;
103 if (PV_ABS(*ptr - sum) > max_diff)
104 {
105 if (sum > *ptr)
106 sum = *ptr + max_diff;
107 else
108 sum = *ptr - max_diff;
109 }
110 *ptr++ = (uint8) sum;
111 }
112 ptr++;
113 ptr2++;
114 ptr3++;
115 }
116 }
117 }
118 }
119
120 for (v_blk = BLKSIZE; v_blk < height; v_blk += BLKSIZE)
121 {
122 v0 = v_blk - 1;
123 /* Do the first block (pixels=7 => No MMX) */
124 max_diff = (QP_store[((((int32)v_blk*width)>>3))>>3] >> 2) + 4;
125 ptr = &Rec_C[(int32)v_blk * width];
126 max_blk = min_blk = *ptr;
127 FindMaxMin(ptr, &min_blk, &max_blk, incr);
128
129 if (max_blk - min_blk >= 4)
130 {
131 thres = (max_blk + min_blk + 1) >> 1;
132
133 for (v_pel = v0; v_pel < v_blk + BLKSIZE - 1; v_pel++)
134 {
135 addr_v = v_pel * width;
136 ptr = &Rec_C[addr_v];
137 ptr2 = &sum_v[0];
138 ptr3 = &sign_v[0];
139
140 pelu = *(ptr - width);
141 pelc = *ptr;
142 pell = *(ptr + width);
143 ptr++;
144 *ptr2++ = pelu + (pelc << 1) + pell;
145 *ptr3++ = INDEX(pelu, thres) + INDEX(pelc, thres) + INDEX(pell, thres);
146
147 pelu = *(ptr - width);
148 pelc = *ptr;
149 pell = *(ptr + width);
150 ptr++;
151 *ptr2++ = pelu + (pelc << 1) + pell;
152 *ptr3++ = INDEX(pelu, thres) + INDEX(pelc, thres) + INDEX(pell, thres);
153
154 for (h_pel = 1; h_pel < BLKSIZE - 1; h_pel++)
155 {
156 pelu = *(ptr - width);
157 pelc = *ptr;
158 pell = *(ptr + width);
159
160 *ptr2 = pelu + (pelc << 1) + pell;
161 *ptr3 = INDEX(pelu, thres) + INDEX(pelc, thres) + INDEX(pell, thres);
162
163 sum1 = *(ptr3 - 2) + *(ptr3 - 1) + *ptr3;
164 if (sum1 == 0 || sum1 == 9)
165 {
166 sum = (*(ptr2 - 2) + (*(ptr2 - 1) << 1) + *ptr2 + 8) >> 4;
167
168 ptr--;
169 if (PV_ABS(*ptr - sum) > max_diff)
170 {
171 if (sum > *ptr)
172 sum = *ptr + max_diff;
173 else
174 sum = *ptr - max_diff;
175 }
176 *ptr++ = (uint8) sum;
177 }
178 ptr++;
179 ptr2++;
180 ptr3++;
181 }
182 }
183 }
184
185
186 /* Do the rest in MMX */
187 for (h_blk = BLKSIZE; h_blk < width; h_blk += BLKSIZE)
188 {
189 if ((pp_mod[(v_blk/8)*(width/8)+h_blk/8]&0x4) != 0)
190 {
191 max_diff = (QP_store[((((int32)v_blk*width)>>3)+h_blk)>>3] >> 2) + 4;
192 ptr = &Rec_C[(int32)v_blk * width + h_blk];
193 max_blk = min_blk = *ptr;
194 FindMaxMin(ptr, &min_blk, &max_blk, incr);
195 h0 = h_blk - 1;
196
197 if (max_blk - min_blk >= 4)
198 {
199 thres = (max_blk + min_blk + 1) >> 1;
200 #ifdef NoMMX
201 AdaptiveSmooth_NoMMX(Rec_C, v0, h0, v_blk, h_blk, thres, width, max_diff);
202 #else
203 DeringAdaptiveSmoothMMX(&Rec_C[(int32)v0*width+h0], width, thres, max_diff);
204 #endif
205 }
206 }
207 }
208 } /* macroblock level */
209
210 /*----------------------------------------------------------------------------
211 ; Return nothing or data or data pointer
212 ----------------------------------------------------------------------------*/
213 return;
214 }
215 #endif
216