post_filter.cpp revision 3306cfee3bf38ab207a0504e49c2d492bb73ffbf
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
19#include    "mp4dec_lib.h"
20
21#ifdef PV_ANNEX_IJKT_SUPPORT
22#include    "motion_comp.h"
23#include "mbtype_mode.h"
24const static int STRENGTH_tab[] = {0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 12};
25#endif
26
27#ifdef PV_POSTPROC_ON
28/*----------------------------------------------------------------------------
29; FUNCTION CODE
30----------------------------------------------------------------------------*/
31void PostFilter(
32    VideoDecData *video,
33    int filter_type,
34    uint8 *output)
35{
36    /*----------------------------------------------------------------------------
37    ; Define all local variables
38    ----------------------------------------------------------------------------*/
39    uint8 *pp_mod;
40    int16 *QP_store;
41    int combined_with_deblock_filter;
42    int nTotalMB = video->nTotalMB;
43    int width, height;
44    int32 size;
45    int softDeblocking;
46    uint8 *decodedFrame = video->videoDecControls->outputFrame;
47    /*----------------------------------------------------------------------------
48    ; Function body here
49    ----------------------------------------------------------------------------*/
50    width = video->width;
51    height = video->height;
52    size = (int32)width * height;
53
54    oscl_memcpy(output, decodedFrame, size);
55    oscl_memcpy(output + size, decodedFrame + size, (size >> 2));
56    oscl_memcpy(output + size + (size >> 2), decodedFrame + size + (size >> 2), (size >> 2));
57
58    if (filter_type == 0)
59        return;
60
61    /* The softDecoding cutoff corresponds to ~93000 bps for QCIF 15fps clip  */
62    if (PVGetDecBitrate(video->videoDecControls) > (100*video->frameRate*(size >> 12)))  // MC_sofDeblock
63        softDeblocking = FALSE;
64    else
65        softDeblocking = TRUE;
66
67    combined_with_deblock_filter = filter_type & PV_DEBLOCK;
68    QP_store = video->QPMB;
69
70    /* Luma */
71    pp_mod = video->pstprcTypCur;
72
73    if ((filter_type & PV_DEBLOCK) && (filter_type & PV_DERING))
74    {
75        CombinedHorzVertRingFilter(output, width, height, QP_store, 0, pp_mod);
76    }
77    else
78    {
79        if (filter_type & PV_DEBLOCK)
80        {
81            if (softDeblocking)
82            {
83                CombinedHorzVertFilter(output, width, height,
84                                       QP_store, 0, pp_mod);
85            }
86            else
87            {
88                CombinedHorzVertFilter_NoSoftDeblocking(output, width, height,
89                                                        QP_store, 0, pp_mod);
90            }
91        }
92        if (filter_type & PV_DERING)
93        {
94            Deringing_Luma(output, width, height, QP_store,
95                           combined_with_deblock_filter, pp_mod);
96
97        }
98    }
99
100    /* Chroma */
101
102    pp_mod += (nTotalMB << 2);
103    output += size;
104
105    if ((filter_type & PV_DEBLOCK) && (filter_type & PV_DERING))
106    {
107        CombinedHorzVertRingFilter(output, (int)(width >> 1), (int)(height >> 1), QP_store, (int) 1, pp_mod);
108    }
109    else
110    {
111        if (filter_type & PV_DEBLOCK)
112        {
113            if (softDeblocking)
114            {
115                CombinedHorzVertFilter(output, (int)(width >> 1),
116                                       (int)(height >> 1), QP_store, (int) 1, pp_mod);
117            }
118            else
119            {
120                CombinedHorzVertFilter_NoSoftDeblocking(output, (int)(width >> 1),
121                                                        (int)(height >> 1), QP_store, (int) 1, pp_mod);
122            }
123        }
124        if (filter_type & PV_DERING)
125        {
126            Deringing_Chroma(output, (int)(width >> 1),
127                             (int)(height >> 1), QP_store,
128                             combined_with_deblock_filter, pp_mod);
129        }
130    }
131
132    pp_mod += nTotalMB;
133    output += (size >> 2);
134
135    if ((filter_type & PV_DEBLOCK) && (filter_type & PV_DERING))
136    {
137        CombinedHorzVertRingFilter(output, (int)(width >> 1), (int)(height >> 1), QP_store, (int) 1, pp_mod);
138    }
139    else
140    {
141        if (filter_type & PV_DEBLOCK)
142        {
143            if (softDeblocking)
144            {
145                CombinedHorzVertFilter(output, (int)(width >> 1),
146                                       (int)(height >> 1), QP_store, (int) 1, pp_mod);
147            }
148            else
149            {
150                CombinedHorzVertFilter_NoSoftDeblocking(output, (int)(width >> 1),
151                                                        (int)(height >> 1), QP_store, (int) 1, pp_mod);
152            }
153        }
154        if (filter_type & PV_DERING)
155        {
156            Deringing_Chroma(output, (int)(width >> 1),
157                             (int)(height >> 1), QP_store,
158                             combined_with_deblock_filter, pp_mod);
159        }
160    }
161
162    /*  swap current pp_mod to prev_frame pp_mod */
163    pp_mod = video->pstprcTypCur;
164    video->pstprcTypCur = video->pstprcTypPrv;
165    video->pstprcTypPrv = pp_mod;
166
167    /*----------------------------------------------------------------------------
168    ; Return nothing or data or data pointer
169    ----------------------------------------------------------------------------*/
170    return;
171}
172#endif
173
174
175#ifdef PV_ANNEX_IJKT_SUPPORT
176void H263_Deblock(uint8 *rec,
177                  int width,
178                  int height,
179                  int16 *QP_store,
180                  uint8 *mode,
181                  int chr, int annex_T)
182{
183    /*----------------------------------------------------------------------------
184    ; Define all local variables
185    ----------------------------------------------------------------------------*/
186    int i, j, k;
187    uint8 *rec_y;
188    int tmpvar;
189    int mbnum, strength, A_D, d1_2, d1, d2, A, B, C, D, b_size;
190    int d, offset, nMBPerRow, nMBPerCol, width2 = (width << 1);
191    /* MAKE SURE I-VOP INTRA MACROBLOCKS ARE SET TO NON-SKIPPED MODE*/
192    mbnum = 0;
193
194    if (chr)
195    {
196        nMBPerRow = width >> 3;
197        nMBPerCol = height >> 3;
198        b_size = 8;
199    }
200    else
201    {
202        nMBPerRow = width >> 4;
203        nMBPerCol = height >> 4;
204        b_size = 16;
205    }
206
207
208    /********************************* VERTICAL FILTERING ****************************/
209    /* vertical filtering of mid sections no need to check neighboring QP's etc */
210    if (!chr)
211    {
212        rec_y = rec + (width << 3);
213        for (i = 0; i < (height >> 4); i++)
214        {
215            for (j = 0; j < (width >> 4); j++)
216            {
217                if (mode[mbnum] != MODE_SKIPPED)
218                {
219                    k = 16;
220                    strength = STRENGTH_tab[QP_store[mbnum]];
221                    while (k--)
222                    {
223                        A =  *(rec_y - width2);
224                        D = *(rec_y + width);
225                        A_D = A - D;
226                        C = *rec_y;
227                        B = *(rec_y - width);
228                        d = (((C - B) << 2) + A_D);
229
230                        if (d < 0)
231                        {
232                            d1 = -(-d >> 3);
233                            if (d1 < -(strength << 1))
234                            {
235                                d1 = 0;
236                            }
237                            else if (d1 < -strength)
238                            {
239                                d1 = -d1 - (strength << 1);
240                            }
241                            d1_2 = -d1 >> 1;
242                        }
243                        else
244                        {
245                            d1 = d >> 3;
246                            if (d1 > (strength << 1))
247                            {
248                                d1 = 0;
249                            }
250                            else if (d1 > strength)
251                            {
252                                d1 = (strength << 1) - d1;
253                            }
254                            d1_2 = d1 >> 1;
255                        }
256
257                        if (A_D < 0)
258                        {
259                            d2 = -(-A_D >> 2);
260                            if (d2 < -d1_2)
261                            {
262                                d2 = -d1_2;
263                            }
264                        }
265                        else
266                        {
267                            d2 = A_D >> 2;
268                            if (d2 > d1_2)
269                            {
270                                d2 = d1_2;
271                            }
272                        }
273
274                        *(rec_y - width2) = A - d2;
275                        tmpvar = B + d1;
276                        CLIP_RESULT(tmpvar)
277                        *(rec_y - width) = tmpvar;
278                        tmpvar = C - d1;
279                        CLIP_RESULT(tmpvar)
280                        *rec_y = tmpvar;
281                        *(rec_y + width) = D + d2;
282                        rec_y++;
283                    }
284                }
285                else
286                {
287                    rec_y += b_size;
288                }
289                mbnum++;
290            }
291            rec_y += (15 * width);
292
293        }
294    }
295
296    /* VERTICAL boundary blocks */
297
298
299    rec_y = rec + width * b_size;
300
301    mbnum = nMBPerRow;
302    for (i = 0; i < nMBPerCol - 1; i++)
303    {
304        for (j = 0; j < nMBPerRow; j++)
305        {
306            if (mode[mbnum] != MODE_SKIPPED || mode[mbnum - nMBPerRow] != MODE_SKIPPED)
307            {
308                k = b_size;
309                if (mode[mbnum] != MODE_SKIPPED)
310                {
311                    strength = STRENGTH_tab[(annex_T ?  MQ_chroma_QP_table[QP_store[mbnum]] : QP_store[mbnum])];
312                }
313                else
314                {
315                    strength = STRENGTH_tab[(annex_T ?  MQ_chroma_QP_table[QP_store[mbnum - nMBPerRow]] : QP_store[mbnum - nMBPerRow])];
316                }
317
318                while (k--)
319                {
320                    A =  *(rec_y - width2);
321                    D =  *(rec_y + width);
322                    A_D = A - D;
323                    C = *rec_y;
324                    B = *(rec_y - width);
325                    d = (((C - B) << 2) + A_D);
326
327                    if (d < 0)
328                    {
329                        d1 = -(-d >> 3);
330                        if (d1 < -(strength << 1))
331                        {
332                            d1 = 0;
333                        }
334                        else if (d1 < -strength)
335                        {
336                            d1 = -d1 - (strength << 1);
337                        }
338                        d1_2 = -d1 >> 1;
339                    }
340                    else
341                    {
342                        d1 = d >> 3;
343                        if (d1 > (strength << 1))
344                        {
345                            d1 = 0;
346                        }
347                        else if (d1 > strength)
348                        {
349                            d1 = (strength << 1) - d1;
350                        }
351                        d1_2 = d1 >> 1;
352                    }
353
354                    if (A_D < 0)
355                    {
356                        d2 = -(-A_D >> 2);
357                        if (d2 < -d1_2)
358                        {
359                            d2 = -d1_2;
360                        }
361                    }
362                    else
363                    {
364                        d2 = A_D >> 2;
365                        if (d2 > d1_2)
366                        {
367                            d2 = d1_2;
368                        }
369                    }
370
371                    *(rec_y - width2) = A - d2;
372                    tmpvar = B + d1;
373                    CLIP_RESULT(tmpvar)
374                    *(rec_y - width) = tmpvar;
375                    tmpvar = C - d1;
376                    CLIP_RESULT(tmpvar)
377                    *rec_y = tmpvar;
378                    *(rec_y + width) = D + d2;
379                    rec_y++;
380                }
381            }
382            else
383            {
384                rec_y += b_size;
385            }
386            mbnum++;
387        }
388        rec_y += ((b_size - 1) * width);
389
390    }
391
392
393    /***************************HORIZONTAL FILTERING ********************************************/
394    mbnum = 0;
395    /* HORIZONTAL INNER */
396    if (!chr)
397    {
398        rec_y = rec + 8;
399        offset = width * b_size - b_size;
400
401        for (i = 0; i < nMBPerCol; i++)
402        {
403            for (j = 0; j < nMBPerRow; j++)
404            {
405                if (mode[mbnum] != MODE_SKIPPED)
406                {
407                    k = 16;
408                    strength = STRENGTH_tab[QP_store[mbnum]];
409                    while (k--)
410                    {
411                        A =  *(rec_y - 2);
412                        D =  *(rec_y + 1);
413                        A_D = A - D;
414                        C = *rec_y;
415                        B = *(rec_y - 1);
416                        d = (((C - B) << 2) + A_D);
417
418                        if (d < 0)
419                        {
420                            d1 = -(-d >> 3);
421                            if (d1 < -(strength << 1))
422                            {
423                                d1 = 0;
424                            }
425                            else if (d1 < -strength)
426                            {
427                                d1 = -d1 - (strength << 1);
428                            }
429                            d1_2 = -d1 >> 1;
430                        }
431                        else
432                        {
433                            d1 = d >> 3;
434                            if (d1 > (strength << 1))
435                            {
436                                d1 = 0;
437                            }
438                            else if (d1 > strength)
439                            {
440                                d1 = (strength << 1) - d1;
441                            }
442                            d1_2 = d1 >> 1;
443                        }
444
445                        if (A_D < 0)
446                        {
447                            d2 = -(-A_D >> 2);
448                            if (d2 < -d1_2)
449                            {
450                                d2 = -d1_2;
451                            }
452                        }
453                        else
454                        {
455                            d2 = A_D >> 2;
456                            if (d2 > d1_2)
457                            {
458                                d2 = d1_2;
459                            }
460                        }
461
462                        *(rec_y - 2) = A - d2;
463                        tmpvar = B + d1;
464                        CLIP_RESULT(tmpvar)
465                        *(rec_y - 1) = tmpvar;
466                        tmpvar = C - d1;
467                        CLIP_RESULT(tmpvar)
468                        *rec_y = tmpvar;
469                        *(rec_y + 1) = D + d2;
470                        rec_y += width;
471                    }
472                    rec_y -= offset;
473                }
474                else
475                {
476                    rec_y += b_size;
477                }
478                mbnum++;
479            }
480            rec_y += (15 * width);
481
482        }
483    }
484
485
486
487    /* HORIZONTAL EDGE */
488    rec_y = rec + b_size;
489    offset = width * b_size - b_size;
490    mbnum = 1;
491    for (i = 0; i < nMBPerCol; i++)
492    {
493        for (j = 0; j < nMBPerRow - 1; j++)
494        {
495            if (mode[mbnum] != MODE_SKIPPED || mode[mbnum-1] != MODE_SKIPPED)
496            {
497                k = b_size;
498                if (mode[mbnum] != MODE_SKIPPED)
499                {
500                    strength = STRENGTH_tab[(annex_T ?  MQ_chroma_QP_table[QP_store[mbnum]] : QP_store[mbnum])];
501                }
502                else
503                {
504                    strength = STRENGTH_tab[(annex_T ?  MQ_chroma_QP_table[QP_store[mbnum - 1]] : QP_store[mbnum - 1])];
505                }
506
507                while (k--)
508                {
509                    A =  *(rec_y - 2);
510                    D =  *(rec_y + 1);
511                    A_D = A - D;
512                    C = *rec_y;
513                    B = *(rec_y - 1);
514                    d = (((C - B) << 2) + A_D);
515
516                    if (d < 0)
517                    {
518                        d1 = -(-d >> 3);
519                        if (d1 < -(strength << 1))
520                        {
521                            d1 = 0;
522                        }
523                        else if (d1 < -strength)
524                        {
525                            d1 = -d1 - (strength << 1);
526                        }
527                        d1_2 = -d1 >> 1;
528                    }
529                    else
530                    {
531                        d1 = d >> 3;
532                        if (d1 > (strength << 1))
533                        {
534                            d1 = 0;
535                        }
536                        else if (d1 > strength)
537                        {
538                            d1 = (strength << 1) - d1;
539                        }
540                        d1_2 = d1 >> 1;
541                    }
542
543                    if (A_D < 0)
544                    {
545                        d2 = -(-A_D >> 2);
546                        if (d2 < -d1_2)
547                        {
548                            d2 = -d1_2;
549                        }
550                    }
551                    else
552                    {
553                        d2 = A_D >> 2;
554                        if (d2 > d1_2)
555                        {
556                            d2 = d1_2;
557                        }
558                    }
559
560                    *(rec_y - 2) = A - d2;
561                    tmpvar = B + d1;
562                    CLIP_RESULT(tmpvar)
563                    *(rec_y - 1) = tmpvar;
564                    tmpvar = C - d1;
565                    CLIP_RESULT(tmpvar)
566                    *rec_y = tmpvar;
567                    *(rec_y + 1) = D + d2;
568                    rec_y += width;
569                }
570                rec_y -= offset;
571            }
572            else
573            {
574                rec_y += b_size;
575            }
576            mbnum++;
577        }
578        rec_y += ((width * (b_size - 1)) + b_size);
579        mbnum++;
580    }
581
582    return;
583}
584#endif
585
586