• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
CombinedHorzVertRingFilter(uint8 * rec,int width,int height,int16 * QP_store,int chr,uint8 * pp_mod)23 void CombinedHorzVertRingFilter(
24     uint8 *rec,
25     int width,
26     int height,
27     int16 *QP_store,
28     int chr,
29     uint8 *pp_mod)
30 {
31 
32     /*----------------------------------------------------------------------------
33     ; Define all local variables
34     ----------------------------------------------------------------------------*/
35     int index, counter;
36     int br, bc, incr, mbr, mbc;
37     int QP = 1;
38     int v[5];
39     uint8 *ptr, *ptr_c, *ptr_n;
40     int w1, w2, w3, w4;
41     int pp_w, pp_h, brwidth;
42     int sum, delta;
43     int a3_0, a3_1, a3_2, A3_0;
44     /* for Deringing Threshold approach (MPEG4)*/
45     int max_diff, thres, v0, h0, min_blk, max_blk;
46     int cnthflag;
47 
48     /*----------------------------------------------------------------------------
49     ; Function body here
50     ----------------------------------------------------------------------------*/
51     /* Calculate the width and height of the area in blocks (divide by 8) */
52     pp_w = (width >> 3);
53     pp_h = (height >> 3);
54 
55     /* Set up various values needed for updating pointers into rec */
56     w1 = width;             /* Offset to next row in pixels */
57     w2 = width << 1;        /* Offset to two rows in pixels */
58     w3 = w1 + w2;           /* Offset to three rows in pixels */
59     w4 = w2 << 1;           /* Offset to four rows in pixels */
60     incr = width - BLKSIZE; /* Offset to next row after processing block */
61 
62     /* Work through the area hortizontally by two rows per step */
63     for (mbr = 0; mbr < pp_h; mbr += 2)
64     {
65         /* brwidth contains the block number of the leftmost block
66          * of the current row */
67         brwidth = mbr * pp_w;
68 
69         /* Work through the area vertically by two columns per step */
70         for (mbc = 0; mbc < pp_w; mbc += 2)
71         {
72             /* if the data is luminance info, get the correct
73                     * quantization paramenter. One parameter per macroblock */
74             if (!chr)
75             {
76                 /* brwidth/4 is the macroblock number and mbc/2 is the macroblock col number*/
77                 QP = QP_store[(brwidth>>2) + (mbc>>1)];
78             }
79 
80             /****************** Horiz. Filtering ********************/
81             /* Process four blocks for the filtering        */
82             /********************************************************/
83             /* Loop over two rows of blocks */
84             for (br = mbr + 1; br < mbr + 3; br++)    /* br is the row counter in blocks */
85             {
86                 /* Set brwidth to the first (leftmost) block number of the next row */
87                 /* brwidth is used as an index when counting blocks */
88                 brwidth += pp_w;
89 
90                 /* Loop over two columns of blocks in the row */
91                 for (bc = mbc; bc < mbc + 2; bc++)    /* bc is the column counter in blocks */
92                 {
93                     /****** check boundary for deblocking ************/
94                     /* Execute if the row and column counters are within the area */
95                     if (br < pp_h && bc < pp_w)
96                     {
97                         /* Set the ptr to the first pixel of the first block of the second row
98                         * brwidth * 64 is the pixel row offset
99                         * bc * 8 is the pixel column offset */
100                         ptr = rec + (brwidth << 6) + (bc << 3);
101 
102                         /* Set the index to the current block of the second row counting in blocks */
103                         index = brwidth + bc;
104 
105                         /* if the data is chrominance info, get the correct
106                          * quantization paramenter. One parameter per block. */
107                         if (chr)
108                         {
109                             QP = QP_store[index];
110                         }
111 
112                         /* Execute hard horizontal filter if semaphore for horizontal deblocking
113                           * is set for the current block and block immediately above it */
114                         if (((pp_mod[index]&0x02) != 0) && ((pp_mod[index-pp_w]&0x02) != 0))
115                         {   /* Hard filter */
116 
117                             /* Set HorzHflag (bit 4) in the pp_mod location */
118                             pp_mod[index-pp_w] |= 0x10; /*  4/26/00 reuse pp_mod for HorzHflag*/
119 
120                             /* Filter across the 8 pixels of the block */
121                             for (index = BLKSIZE; index > 0; index--)
122                             {
123                                 /* Difference between the current pixel and the pixel above it */
124                                 a3_0 = *ptr - *(ptr - w1);
125 
126                                 /* if the magnitude of the difference is greater than the KThH threshold
127                                  * and within the quantization parameter, apply hard filter */
128                                 if ((a3_0 > KThH || a3_0 < -KThH) && a3_0<QP && a3_0> -QP)
129                                 {
130                                     ptr_c = ptr - w3;   /* Points to pixel three rows above */
131                                     ptr_n = ptr + w1;   /* Points to pixel one row below */
132                                     v[0] = (int)(*(ptr_c - w3));
133                                     v[1] = (int)(*(ptr_c - w2));
134                                     v[2] = (int)(*(ptr_c - w1));
135                                     v[3] = (int)(*ptr_c);
136                                     v[4] = (int)(*(ptr_c + w1));
137 
138                                     sum = v[0]
139                                           + v[1]
140                                           + v[2]
141                                           + *ptr_c
142                                           + v[4]
143                                           + (*(ptr_c + w2))
144                                           + (*(ptr_c + w3));  /* Current pixel */
145 
146                                     delta = (sum + *ptr_c + 4) >> 3;   /* Average pixel values with rounding */
147                                     *(ptr_c) = (uint8) delta;
148 
149                                     /* Move pointer down one row of pixels (points to pixel two rows
150                                      * above current pixel) */
151                                     ptr_c += w1;
152 
153                                     for (counter = 0; counter < 5; counter++)
154                                     {
155                                         /* Subtract off highest pixel and add in pixel below */
156                                         sum = sum - v[counter] + *ptr_n;
157                                         /* Average the pixel values with rounding */
158                                         delta = (sum + *ptr_c + 4) >> 3;
159                                         *ptr_c = (uint8)(delta);
160 
161                                         /* Increment pointers to next pixel row */
162                                         ptr_c += w1;
163                                         ptr_n += w1;
164                                     }
165                                 }
166                                 /* Increment pointer to next pixel */
167                                 ++ptr;
168                             } /* index*/
169                         }
170                         else
171                         { /* soft filter*/
172 
173                             /* Clear HorzHflag (bit 4) in the pp_mod location */
174                             pp_mod[index-pp_w] &= 0xef; /* reset 1110,1111 */
175 
176                             for (index = BLKSIZE; index > 0; index--)
177                             {
178                                 /* Difference between the current pixel and the pixel above it */
179                                 a3_0 = *(ptr) - *(ptr - w1);
180 
181                                 /* if the magnitude of the difference is greater than the KTh threshold,
182                                  * apply soft filter */
183                                 if ((a3_0 > KTh || a3_0 < -KTh))
184                                 {
185 
186                                     /* Sum of weighted differences */
187                                     a3_0 += ((*(ptr - w2) - *(ptr + w1)) << 1) + (a3_0 << 2);
188 
189                                     /* Check if sum is less than the quantization parameter */
190                                     if (PV_ABS(a3_0) < (QP << 3))
191                                     {
192                                         a3_1 = *(ptr - w2) - *(ptr - w3);
193                                         a3_1 += ((*(ptr - w4) - *(ptr - w1)) << 1) + (a3_1 << 2);
194 
195                                         a3_2  = *(ptr + w2) - *(ptr + w1);
196                                         a3_2 += ((*(ptr) - *(ptr + w3)) << 1) + (a3_2 << 2);
197 
198                                         A3_0 = PV_ABS(a3_0) - PV_MIN(PV_ABS(a3_1), PV_ABS(a3_2));
199 
200                                         if (A3_0 > 0)
201                                         {
202                                             A3_0 += A3_0 << 2;
203                                             A3_0 = (A3_0 + 32) >> 6;
204                                             if (a3_0 > 0)
205                                             {
206                                                 A3_0 = -A3_0;
207                                             }
208 
209                                             delta = (*(ptr - w1) - *(ptr)) >> 1;
210                                             if (delta >= 0)
211                                             {
212                                                 if (delta >= A3_0)
213                                                 {
214                                                     delta = PV_MAX(A3_0, 0);
215                                                 }
216                                             }
217                                             else
218                                             {
219                                                 if (A3_0 > 0)
220                                                 {
221                                                     delta = 0;
222                                                 }
223                                                 else
224                                                 {
225                                                     delta = PV_MAX(A3_0, delta);
226                                                 }
227                                             }
228 
229                                             *(ptr - w1) = (uint8)(*(ptr - w1) - delta);
230                                             *(ptr) = (uint8)(*(ptr) + delta);
231                                         }
232                                     } /*threshold*/
233                                 }
234                                 /* Increment pointer to next pixel */
235                                 ++ptr;
236                             } /*index*/
237                         } /* Soft filter*/
238                     }/* boundary checking*/
239                 }/*bc*/
240             }/*br*/
241             brwidth -= (pp_w << 1);
242 
243 
244             /****************** Vert. Filtering *********************/
245             /* Process four blocks for the filtering        */
246             /********************************************************/
247             /* Loop over two rows of blocks */
248             for (br = mbr; br < mbr + 2; br++)      /* br is the row counter in blocks */
249             {
250                 for (bc = mbc + 1; bc < mbc + 3; bc++)  /* bc is the column counter in blocks */
251                 {
252                     /****** check boundary for deblocking ************/
253                     /* Execute if the row and column counters are within the area */
254                     if (br < pp_h && bc < pp_w)
255                     {
256                         /* Set the ptr to the first pixel of the first block of the second row
257                         * brwidth * 64 is the pixel row offset
258                         * bc * 8 is the pixel column offset */
259                         ptr = rec + (brwidth << 6) + (bc << 3);
260 
261                         /* Set the index to the current block of the second row counting in blocks */
262                         index = brwidth + bc;
263 
264                         /* if the data is chrominance info, get the correct
265                          * quantization paramenter. One parameter per block. */
266                         if (chr)
267                         {
268                             QP = QP_store[index];
269                         }
270 
271                         /* Execute hard vertical filter if semaphore for vertical deblocking
272                           * is set for the current block and block immediately left of it */
273                         if (((pp_mod[index-1]&0x01) != 0) && ((pp_mod[index]&0x01) != 0))
274                         {   /* Hard filter */
275 
276                             /* Set VertHflag (bit 5) in the pp_mod location of previous block*/
277                             pp_mod[index-1] |= 0x20; /*  4/26/00 reuse pp_mod for VertHflag*/
278 
279                             /* Filter across the 8 pixels of the block */
280                             for (index = BLKSIZE; index > 0; index--)
281                             {
282                                 /* Difference between the current pixel
283                                 * and the pixel to left of it */
284                                 a3_0 = *ptr - *(ptr - 1);
285 
286                                 /* if the magnitude of the difference is greater than the KThH threshold
287                                  * and within the quantization parameter, apply hard filter */
288                                 if ((a3_0 > KThH || a3_0 < -KThH) && a3_0<QP && a3_0> -QP)
289                                 {
290                                     ptr_c = ptr - 3;
291                                     ptr_n = ptr + 1;
292                                     v[0] = (int)(*(ptr_c - 3));
293                                     v[1] = (int)(*(ptr_c - 2));
294                                     v[2] = (int)(*(ptr_c - 1));
295                                     v[3] = (int)(*ptr_c);
296                                     v[4] = (int)(*(ptr_c + 1));
297 
298                                     sum = v[0]
299                                           + v[1]
300                                           + v[2]
301                                           + *ptr_c
302                                           + v[4]
303                                           + (*(ptr_c + 2))
304                                           + (*(ptr_c + 3));
305 
306                                     delta = (sum + *ptr_c + 4) >> 3;
307                                     *(ptr_c) = (uint8) delta;
308 
309                                     /* Move pointer down one pixel to the right */
310                                     ptr_c += 1;
311                                     for (counter = 0; counter < 5; counter++)
312                                     {
313                                         /* Subtract off highest pixel and add in pixel below */
314                                         sum = sum - v[counter] + *ptr_n;
315                                         /* Average the pixel values with rounding */
316                                         delta = (sum + *ptr_c + 4) >> 3;
317                                         *ptr_c = (uint8)(delta);
318 
319                                         /* Increment pointers to next pixel */
320                                         ptr_c += 1;
321                                         ptr_n += 1;
322                                     }
323                                 }
324                                 /* Increment pointers to next pixel row */
325                                 ptr += w1;
326                             } /* index*/
327                         }
328                         else
329                         { /* soft filter*/
330 
331                             /* Clear VertHflag (bit 5) in the pp_mod location */
332                             pp_mod[index-1] &= 0xdf; /* reset 1101,1111 */
333                             for (index = BLKSIZE; index > 0; index--)
334                             {
335                                 /* Difference between the current pixel and the pixel above it */
336                                 a3_0 = *(ptr) - *(ptr - 1);
337 
338                                 /* if the magnitude of the difference is greater than the KTh threshold,
339                                  * apply soft filter */
340                                 if ((a3_0 > KTh || a3_0 < -KTh))
341                                 {
342 
343                                     /* Sum of weighted differences */
344                                     a3_0 += ((*(ptr - 2) - *(ptr + 1)) << 1) + (a3_0 << 2);
345 
346                                     /* Check if sum is less than the quantization parameter */
347                                     if (PV_ABS(a3_0) < (QP << 3))
348                                     {
349                                         a3_1 = *(ptr - 2) - *(ptr - 3);
350                                         a3_1 += ((*(ptr - 4) - *(ptr - 1)) << 1) + (a3_1 << 2);
351 
352                                         a3_2  = *(ptr + 2) - *(ptr + 1);
353                                         a3_2 += ((*(ptr) - *(ptr + 3)) << 1) + (a3_2 << 2);
354 
355                                         A3_0 = PV_ABS(a3_0) - PV_MIN(PV_ABS(a3_1), PV_ABS(a3_2));
356 
357                                         if (A3_0 > 0)
358                                         {
359                                             A3_0 += A3_0 << 2;
360                                             A3_0 = (A3_0 + 32) >> 6;
361                                             if (a3_0 > 0)
362                                             {
363                                                 A3_0 = -A3_0;
364                                             }
365 
366                                             delta = (*(ptr - 1) - *(ptr)) >> 1;
367                                             if (delta >= 0)
368                                             {
369                                                 if (delta >= A3_0)
370                                                 {
371                                                     delta = PV_MAX(A3_0, 0);
372                                                 }
373                                             }
374                                             else
375                                             {
376                                                 if (A3_0 > 0)
377                                                 {
378                                                     delta = 0;
379                                                 }
380                                                 else
381                                                 {
382                                                     delta = PV_MAX(A3_0, delta);
383                                                 }
384                                             }
385 
386                                             *(ptr - 1) = (uint8)(*(ptr - 1) - delta);
387                                             *(ptr) = (uint8)(*(ptr) + delta);
388                                         }
389                                     } /*threshold*/
390                                 }
391                                 ptr += w1;
392                             } /*index*/
393                         } /* Soft filter*/
394                     } /* boundary*/
395                 } /*bc*/
396                 /* Increment pointer to next row of pixels */
397                 brwidth += pp_w;
398             }/*br*/
399             brwidth -= (pp_w << 1);
400 
401             /****************** Deringing ***************************/
402             /* Process four blocks for the filtering        */
403             /********************************************************/
404             /* Loop over two rows of blocks */
405             for (br = mbr; br < mbr + 2; br++)
406             {
407                 /* Loop over two columns of blocks in the row */
408                 for (bc = mbc; bc < mbc + 2; bc++)
409                 {
410                     /* Execute if the row and column counters are within the area */
411                     if (br < pp_h && bc < pp_w)
412                     {
413                         /* Set the index to the current block */
414                         index = brwidth + bc;
415 
416                         /* Execute deringing if semaphore for deringing (bit-3 of pp_mod)
417                          * is set for the current block */
418                         if ((pp_mod[index]&0x04) != 0)
419                         {
420                             /* Don't process deringing if on an edge block */
421                             if (br > 0 && bc > 0 && br < pp_h - 1 && bc < pp_w - 1)
422                             {
423                                 /* cnthflag = weighted average of HorzHflag of current,
424                                  * one above, previous blocks*/
425                                 cnthflag = ((pp_mod[index] & 0x10) +
426                                             (pp_mod[index-pp_w] & 0x10) +
427                                             ((pp_mod[index-1] >> 1) & 0x10) +
428                                             ((pp_mod[index] >> 1) & 0x10)) >> 4; /* 4/26/00*/
429 
430                                 /* Do the deringing if decision flags indicate it's necessary */
431                                 if (cnthflag < 3)
432                                 {
433                                     /* if the data is chrominance info, get the correct
434                                      * quantization paramenter. One parameter per block. */
435                                     if (chr)
436                                     {
437                                         QP = QP_store[index];
438                                     }
439 
440                                     /* Set amount to change luminance if it needs to be changed
441                                      * based on quantization parameter */
442                                     max_diff = (QP >> 2) + 4;
443 
444                                     /* Set pointer to first pixel of current block */
445                                     ptr = rec + (brwidth << 6) + (bc << 3);
446 
447                                     /* Find minimum and maximum value of pixel block */
448                                     FindMaxMin(ptr, &min_blk, &max_blk, incr);
449 
450                                     /* threshold determination */
451                                     thres = (max_blk + min_blk + 1) >> 1;
452 
453                                     /* If pixel range is greater or equal than DERING_THR, smooth the region */
454                                     if ((max_blk - min_blk) >= DERING_THR) /*smooth 8x8 region*/
455 #ifndef NoMMX
456                                     {
457                                         /* smooth all pixels in the block*/
458                                         DeringAdaptiveSmoothMMX(ptr, width, thres, max_diff);
459                                     }
460 #else
461                                     {
462                                         /* Setup the starting point of the region to smooth */
463                                         v0 = (br << 3) - 1;
464                                         h0 = (bc << 3) - 1;
465 
466                                         /*smooth 8x8 region*/
467                                         AdaptiveSmooth_NoMMX(rec, v0, h0, v0 + 1, h0 + 1, thres, width, max_diff);
468                                     }
469 #endif
470                                 }/*cnthflag*/
471                             } /*dering br==1 or bc==1 (boundary block)*/
472                             else    /* Process the boundary blocks */
473                             {
474                                 /* Decide to perform deblocking based on the semaphore flags
475                                    * of the neighboring blocks in each case. A certain number of
476                                  * hard filtering flags have to be set in order to signal need
477                                  * for smoothing */
478                                 if (br > 0 && br < pp_h - 1)
479                                 {
480                                     if (bc > 0)
481                                     {
482                                         cnthflag = ((pp_mod[index-pp_w] & 0x10) +
483                                                     (pp_mod[index] & 0x10) +
484                                                     ((pp_mod[index-1] >> 1) & 0x10)) >> 4;
485                                     }
486                                     else
487                                     {
488                                         cnthflag = ((pp_mod[index] & 0x10) +
489                                                     (pp_mod[index-pp_w] & 0x10) +
490                                                     ((pp_mod[index] >> 1) & 0x10)) >> 4;
491                                     }
492                                 }
493                                 else if (bc > 0 && bc < pp_w - 1)
494                                 {
495                                     if (br > 0)
496                                     {
497                                         cnthflag = ((pp_mod[index-pp_w] & 0x10) +
498                                                     ((pp_mod[index-1] >> 1) & 0x10) +
499                                                     ((pp_mod[index] >> 1) & 0x10)) >> 4;
500                                     }
501                                     else
502                                     {
503                                         cnthflag = ((pp_mod[index] & 0x10) +
504                                                     ((pp_mod[index-1] >> 1) & 0x10) +
505                                                     ((pp_mod[index] >> 1) & 0x10)) >> 4;
506                                     }
507                                 }
508                                 else /* at the corner do default*/
509                                 {
510                                     cnthflag = 0;
511                                 }
512 
513                                 /* Do the deringing if decision flags indicate it's necessary */
514                                 if (cnthflag < 2)
515                                 {
516 
517                                     /* if the data is chrominance info, get the correct
518                                                          * quantization paramenter. One parameter per block. */
519                                     if (chr)
520                                     {
521                                         QP = QP_store[index];
522                                     }
523 
524                                     /* Set amount to change luminance if it needs to be changed
525                                      * based on quantization parameter */
526                                     max_diff = (QP >> 2) + 4;
527 
528                                     /* Set pointer to first pixel of current block */
529                                     ptr = rec + (brwidth << 6) + (bc << 3);
530 
531                                     /* Find minimum and maximum value of pixel block */
532                                     FindMaxMin(ptr, &min_blk, &max_blk, incr);
533 
534                                     /* threshold determination */
535                                     thres = (max_blk + min_blk + 1) >> 1;
536 
537                                     /* Setup the starting point of the region to smooth
538                                      * This is going to be a 4x4 region */
539                                     v0 = (br << 3) + 1;
540                                     h0 = (bc << 3) + 1;
541 
542                                     /* If pixel range is greater or equal than DERING_THR, smooth the region */
543                                     if ((max_blk - min_blk) >= DERING_THR)
544                                     {
545                                         /* Smooth 4x4 region */
546                                         AdaptiveSmooth_NoMMX(rec, v0, h0, v0 - 3, h0 - 3, thres, width, max_diff);
547                                     }
548                                 }/*cnthflag*/
549                             } /* br==0, bc==0*/
550                         }  /* dering*/
551                     } /*boundary condition*/
552                 }/*bc*/
553                 brwidth += pp_w;
554             }/*br*/
555             brwidth -= (pp_w << 1);
556         }/*mbc*/
557         brwidth += (pp_w << 1);
558     }/*mbr*/
559 
560     /*----------------------------------------------------------------------------
561     ; Return nothing or data or data pointer
562     ----------------------------------------------------------------------------*/
563     return ;
564 }
565 #endif
566