Home | History | Annotate | Download | only in src
      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"
     24 const 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 ----------------------------------------------------------------------------*/
     31 void 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
    176 void 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