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_Luma(uint8 * Rec_Y,int width,int height,int16 * QP_store,int,uint8 * pp_mod)23 void Deringing_Luma(
24 uint8 *Rec_Y,
25 int width,
26 int height,
27 int16 *QP_store,
28 int,
29 uint8 *pp_mod)
30 {
31 /*----------------------------------------------------------------------------
32 ; Define all local variables
33 ----------------------------------------------------------------------------*/
34 int thres[4], range[4], max_range_blk, max_thres_blk;
35 int MB_V, MB_H, BLK_V, BLK_H;
36 int v_blk, h_blk;
37 int max_diff;
38 int max_blk, min_blk;
39 int v0, h0;
40 uint8 *ptr;
41 int thr, blks, incr;
42 int mb_indx, blk_indx;
43
44 /*----------------------------------------------------------------------------
45 ; Function body here
46 ----------------------------------------------------------------------------*/
47 incr = width - BLKSIZE;
48
49 /* Dering the first line of macro blocks */
50 for (MB_H = 0; MB_H < width; MB_H += MBSIZE)
51 {
52 max_diff = (QP_store[(MB_H)>>4] >> 2) + 4;
53
54 /* threshold determination */
55 max_range_blk = max_thres_blk = 0;
56 blks = 0;
57
58 for (BLK_V = 0; BLK_V < MBSIZE; BLK_V += BLKSIZE)
59 {
60 for (BLK_H = 0; BLK_H < MBSIZE; BLK_H += BLKSIZE)
61 {
62 ptr = &Rec_Y[(int32)(BLK_V) * width + MB_H + BLK_H];
63 FindMaxMin(ptr, &min_blk, &max_blk, incr);
64
65 thres[blks] = (max_blk + min_blk + 1) >> 1;
66 range[blks] = max_blk - min_blk;
67
68 if (range[blks] >= max_range_blk)
69 {
70 max_range_blk = range[blks];
71 max_thres_blk = thres[blks];
72 }
73 blks++;
74 }
75 }
76
77 blks = 0;
78 for (v_blk = 0; v_blk < MBSIZE; v_blk += BLKSIZE)
79 {
80 v0 = ((v_blk - 1) >= 1) ? (v_blk - 1) : 1;
81 for (h_blk = MB_H; h_blk < MB_H + MBSIZE; h_blk += BLKSIZE)
82 {
83 h0 = ((h_blk - 1) >= 1) ? (h_blk - 1) : 1;
84
85 /* threshold rearrangement for flat region adjacent to non-flat region */
86 if (range[blks]<32 && max_range_blk >= 64)
87 thres[blks] = max_thres_blk;
88
89 /* threshold rearrangement for deblocking
90 (blockiness annoying at DC dominant region) */
91 if (max_range_blk >= 16)
92 {
93 /* adaptive smoothing */
94 thr = thres[blks];
95
96 AdaptiveSmooth_NoMMX(Rec_Y, v0, h0, v_blk, h_blk,
97 thr, width, max_diff);
98 }
99 blks++;
100 } /* block level (Luminance) */
101 }
102 } /* macroblock level */
103
104
105 /* Do the rest of the macro-block-lines */
106 for (MB_V = MBSIZE; MB_V < height; MB_V += MBSIZE)
107 {
108 /* First macro-block */
109 max_diff = (QP_store[((((int32)MB_V*width)>>4))>>4] >> 2) + 4;
110 /* threshold determination */
111 max_range_blk = max_thres_blk = 0;
112 blks = 0;
113 for (BLK_V = 0; BLK_V < MBSIZE; BLK_V += BLKSIZE)
114 {
115 for (BLK_H = 0; BLK_H < MBSIZE; BLK_H += BLKSIZE)
116 {
117 ptr = &Rec_Y[(int32)(MB_V + BLK_V) * width + BLK_H];
118 FindMaxMin(ptr, &min_blk, &max_blk, incr);
119 thres[blks] = (max_blk + min_blk + 1) >> 1;
120 range[blks] = max_blk - min_blk;
121
122 if (range[blks] >= max_range_blk)
123 {
124 max_range_blk = range[blks];
125 max_thres_blk = thres[blks];
126 }
127 blks++;
128 }
129 }
130
131 blks = 0;
132 for (v_blk = MB_V; v_blk < MB_V + MBSIZE; v_blk += BLKSIZE)
133 {
134 v0 = v_blk - 1;
135 for (h_blk = 0; h_blk < MBSIZE; h_blk += BLKSIZE)
136 {
137 h0 = ((h_blk - 1) >= 1) ? (h_blk - 1) : 1;
138
139 /* threshold rearrangement for flat region adjacent to non-flat region */
140 if (range[blks]<32 && max_range_blk >= 64)
141 thres[blks] = max_thres_blk;
142
143 /* threshold rearrangement for deblocking
144 (blockiness annoying at DC dominant region) */
145 if (max_range_blk >= 16)
146 {
147 /* adaptive smoothing */
148 thr = thres[blks];
149
150 AdaptiveSmooth_NoMMX(Rec_Y, v0, h0, v_blk, h_blk,
151 thr, width, max_diff);
152 }
153 blks++;
154 }
155 } /* block level (Luminance) */
156
157 /* Rest of the macro-blocks */
158 for (MB_H = MBSIZE; MB_H < width; MB_H += MBSIZE)
159 {
160 max_diff = (QP_store[((((int32)MB_V*width)>>4)+MB_H)>>4] >> 2) + 4;
161
162 /* threshold determination */
163 max_range_blk = max_thres_blk = 0;
164 blks = 0;
165
166 mb_indx = (MB_V / 8) * (width / 8) + MB_H / 8;
167 for (BLK_V = 0; BLK_V < MBSIZE; BLK_V += BLKSIZE)
168 {
169 for (BLK_H = 0; BLK_H < MBSIZE; BLK_H += BLKSIZE)
170 {
171 blk_indx = mb_indx + (BLK_V / 8) * width / 8 + BLK_H / 8;
172 /* Update based on pp_mod only */
173 if ((pp_mod[blk_indx]&0x4) != 0)
174 {
175 ptr = &Rec_Y[(int32)(MB_V + BLK_V) * width + MB_H + BLK_H];
176 FindMaxMin(ptr, &min_blk, &max_blk, incr);
177 thres[blks] = (max_blk + min_blk + 1) >> 1;
178 range[blks] = max_blk - min_blk;
179
180 if (range[blks] >= max_range_blk)
181 {
182 max_range_blk = range[blks];
183 max_thres_blk = thres[blks];
184 }
185 }
186 blks++;
187 }
188 }
189
190 blks = 0;
191 for (v_blk = MB_V; v_blk < MB_V + MBSIZE; v_blk += BLKSIZE)
192 {
193 v0 = v_blk - 1;
194 mb_indx = (v_blk / 8) * (width / 8);
195 for (h_blk = MB_H; h_blk < MB_H + MBSIZE; h_blk += BLKSIZE)
196 {
197 h0 = h_blk - 1;
198 blk_indx = mb_indx + h_blk / 8;
199 if ((pp_mod[blk_indx]&0x4) != 0)
200 {
201 /* threshold rearrangement for flat region adjacent to non-flat region */
202 if (range[blks]<32 && max_range_blk >= 64)
203 thres[blks] = max_thres_blk;
204
205 /* threshold rearrangement for deblocking
206 (blockiness annoying at DC dominant region) */
207 if (max_range_blk >= 16)
208 {
209 /* adaptive smoothing */
210 thr = thres[blks];
211 #ifdef NoMMX
212 AdaptiveSmooth_NoMMX(Rec_Y, v0, h0, v_blk, h_blk,
213 thr, width, max_diff);
214 #else
215 DeringAdaptiveSmoothMMX(&Rec_Y[v0*width+h0],
216 width, thr, max_diff);
217 #endif
218 }
219 }
220 blks++;
221 }
222 } /* block level (Luminance) */
223 } /* macroblock level */
224 } /* macroblock level */
225
226 /*----------------------------------------------------------------------------
227 ; Return nothing or data or data pointer
228 ----------------------------------------------------------------------------*/
229 return;
230 }
231 #endif
232