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
23void 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