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 /*----------------------------------------------------------------------------
     20 ; INCLUDES
     21 ----------------------------------------------------------------------------*/
     22 #include "mp4dec_lib.h"
     23 #include "vlc_decode.h"
     24 #include "bitstream.h"
     25 #include "zigzag.h"
     26 #include "scaling.h"
     27 
     28 void    doDCACPrediction(
     29     VideoDecData *video,
     30     int comp,
     31     int16 *q_block,
     32     int *direction
     33 )
     34 {
     35     /*----------------------------------------------------------------------------
     36     ; Define all local variables
     37     ----------------------------------------------------------------------------*/
     38     int i;
     39     int mbnum = video->mbnum;
     40     int nMBPerRow = video->nMBPerRow;
     41     int x_pos = video->mbnum_col;
     42     int y_pos = video->mbnum_row;
     43     int16 *AC_tmp;
     44     int QP_tmp;
     45     int16 *QP_store = video->QPMB + mbnum;
     46     int QP = video->QPMB[mbnum];
     47     int QP_half = QP >> 1;
     48     int32 val;
     49     int flag_0 = FALSE, flag_1 = FALSE;
     50     uint8 *slice_nb = video->sliceNo;
     51     typeDCStore *DC_store = video->predDC + mbnum;
     52     typeDCACStore *DCAC_row = video->predDCAC_row + x_pos;
     53     typeDCACStore *DCAC_col = video->predDCAC_col;
     54 
     55     uint ACpred_flag = (uint) video->acPredFlag[mbnum];
     56 
     57     int left_bnd, up_bnd;
     58 
     59     static const int Xpos[6] = { -1, 0, -1, 0, -1, -1};
     60     static const int Ypos[6] = { -1, -1, 0, 0, -1, -1};
     61 
     62     static const int Xtab[6] = {1, 0, 3, 2, 4, 5};
     63     static const int Ytab[6] = {2, 3, 0, 1, 4, 5};
     64     static const int Ztab[6] = {3, 2, 1, 0, 4, 5};
     65 
     66     /* I added these to speed up comparisons */
     67     static const int Pos0[6] = { 1, 1, 0, 0, 1, 1};
     68     static const int Pos1[6] = { 1, 0, 1, 0, 1, 1};
     69 
     70     static const int B_Xtab[6] = {0, 1, 0, 1, 2, 3};
     71     static const int B_Ytab[6] = {0, 0, 1, 1, 2, 3};
     72 
     73 //  int *direction;     /* 0: HORIZONTAL, 1: VERTICAL */
     74     int block_A, block_B, block_C;
     75     int DC_pred;
     76     int y_offset, x_offset, x_tab, y_tab, z_tab;    /* speedup coefficients */
     77     int b_xtab, b_ytab;
     78 
     79     if (!comp && x_pos && !(video->headerInfo.Mode[mbnum-1]&INTRA_MASK)) /* not intra */
     80     {
     81         oscl_memset(DCAC_col, 0, sizeof(typeDCACStore));
     82     }
     83     if (!comp && y_pos && !(video->headerInfo.Mode[mbnum-nMBPerRow]&INTRA_MASK)) /* not intra */
     84     {
     85         oscl_memset(DCAC_row, 0, sizeof(typeDCACStore));
     86     }
     87 
     88     y_offset = Ypos[comp] * nMBPerRow;
     89     x_offset = Xpos[comp];
     90     x_tab = Xtab[comp];
     91     y_tab = Ytab[comp];
     92     z_tab = Ztab[comp];
     93 
     94     b_xtab = B_Xtab[comp];
     95     b_ytab = B_Ytab[comp];
     96 
     97     /*----------------------------------------------------------------------------
     98     ; Function body here
     99     ----------------------------------------------------------------------------*/
    100     /* Find the direction of prediction and the DC prediction */
    101 
    102     if (x_pos == 0 && y_pos == 0)
    103     {   /* top left corner */
    104         block_A = (comp == 1 || comp == 3) ? flag_0 = TRUE, DC_store[0][x_tab] : mid_gray;
    105         block_B = (comp == 3) ? DC_store[x_offset][z_tab] : mid_gray;
    106         block_C = (comp == 2 || comp == 3) ? flag_1 = TRUE, DC_store[0][y_tab] : mid_gray;
    107     }
    108     else if (x_pos == 0)
    109     {   /* left edge */
    110         up_bnd   = Pos0[comp] && slice_nb[mbnum] == slice_nb[mbnum-nMBPerRow];
    111 
    112         block_A = (comp == 1 || comp == 3) ? flag_0 = TRUE, DC_store[0][x_tab] : mid_gray;
    113         block_B = ((comp == 1 && up_bnd) || comp == 3) ?  DC_store[y_offset+x_offset][z_tab] : mid_gray;
    114         block_C = (comp == 2 || comp == 3 || up_bnd) ? flag_1 = TRUE, DC_store[y_offset][y_tab] : mid_gray;
    115     }
    116     else if (y_pos == 0)
    117     { /* top row */
    118         left_bnd = Pos1[comp] && slice_nb[mbnum] == slice_nb[mbnum-1];
    119 
    120         block_A = (comp == 1 || comp == 3 || left_bnd) ? flag_0 = TRUE, DC_store[x_offset][x_tab] : mid_gray;
    121         block_B = ((comp == 2 && left_bnd) || comp == 3) ? DC_store[y_offset + x_offset][z_tab] : mid_gray;
    122         block_C = (comp == 2 || comp == 3) ? flag_1 = TRUE, DC_store[y_offset][y_tab] : mid_gray;
    123     }
    124     else
    125     {
    126         up_bnd   = Pos0[comp] && slice_nb[mbnum] == slice_nb[mbnum-nMBPerRow];
    127         left_bnd = Pos1[comp] && slice_nb[mbnum] == slice_nb[mbnum-1];
    128 
    129         block_A = (comp == 1 || comp == 3 || left_bnd) ? flag_0 = TRUE, DC_store[x_offset][x_tab] : mid_gray;
    130         block_B = (((comp == 0 || comp == 4 || comp == 5) && slice_nb[mbnum] == slice_nb[mbnum-1-nMBPerRow]) ||
    131                    (comp == 1 && up_bnd) || (comp == 2 && left_bnd) || (comp == 3)) ? DC_store[y_offset+x_offset][z_tab] : mid_gray;
    132         block_C = (comp == 2 || comp == 3 || up_bnd) ? flag_1 = TRUE, DC_store[y_offset][y_tab] : mid_gray;
    133     }
    134 
    135 
    136     if ((PV_ABS((block_A - block_B))) < (PV_ABS((block_B - block_C))))
    137     {
    138         DC_pred = block_C;
    139         *direction = 1;
    140         if (ACpred_flag == 1)
    141         {
    142             if (flag_1)
    143             {
    144                 AC_tmp = DCAC_row[0][b_xtab];
    145                 QP_tmp = QP_store[y_offset];
    146                 if (QP_tmp == QP)
    147                 {
    148                     for (i = 1; i < 8; i++)
    149                     {
    150                         q_block[i] = *AC_tmp++;
    151                     }
    152                 }
    153                 else
    154                 {
    155                     for (i = 1; i < 8; i++)
    156                     {
    157                         val = (int32)(*AC_tmp++) * QP_tmp;
    158                         q_block[i] = (val < 0) ? (int16)((val - QP_half) / QP) : (int16)((val + QP_half) / QP);
    159                         /* Vertical, top ROW of block C */
    160                     }
    161                 }
    162             }
    163         }
    164     }
    165     else
    166     {
    167         DC_pred = block_A;
    168         *direction = 0;
    169         if (ACpred_flag == 1)
    170         {
    171             if (flag_0)
    172             {
    173                 AC_tmp = DCAC_col[0][b_ytab];
    174                 QP_tmp = QP_store[x_offset];
    175                 if (QP_tmp == QP)
    176                 {
    177                     for (i = 1; i < 8; i++)
    178                     {
    179                         q_block[i<<3] = *AC_tmp++;
    180                     }
    181                 }
    182                 else
    183                 {
    184                     for (i = 1; i < 8; i++)
    185                     {
    186                         val = (int32)(*AC_tmp++) * QP_tmp;
    187                         q_block[i<<3] = (val < 0) ? (int16)((val - QP_half) / QP) : (int16)((val + QP_half) / QP);
    188                         /* Vertical, top ROW of block C */
    189                     }
    190                 }
    191             }
    192         }
    193     }
    194 
    195     /* Now predict the DC coefficient */
    196     QP_tmp = (comp < 4) ? video->mblock->DCScalarLum : video->mblock->DCScalarChr;
    197     q_block[0] += (int16)((DC_pred + (QP_tmp >> 1)) * scale[QP_tmp] >> 18);
    198 //      q_block[0] += (DC_pred+(QP_tmp>>1))/QP_tmp;
    199 
    200     /*----------------------------------------------------------------------------
    201     ; Return nothing or data or data pointer
    202     ----------------------------------------------------------------------------*/
    203     return;
    204 }
    205 #ifdef PV_ANNEX_IJKT_SUPPORT
    206 void    doDCACPrediction_I(
    207     VideoDecData *video,
    208     int comp,
    209     int16 *q_block
    210 )
    211 {
    212     /*----------------------------------------------------------------------------
    213     ; Define all local variables
    214     ----------------------------------------------------------------------------*/
    215     int mbnum = video->mbnum;
    216     int nMBPerRow = video->nMBPerRow;
    217     int x_pos = video->mbnum_col;
    218     int y_pos = video->mbnum_row;
    219     int16 *AC_tmp;
    220     int flag_0 = FALSE, flag_1 = FALSE;
    221     uint8 *slice_nb = video->sliceNo;
    222     typeDCStore *DC_store = video->predDC + mbnum;
    223     typeDCACStore *DCAC_row = video->predDCAC_row + x_pos;
    224     typeDCACStore *DCAC_col = video->predDCAC_col;
    225     int left_bnd, up_bnd;
    226     uint8 *mode = video->headerInfo.Mode;
    227     uint ACpred_flag = (uint) video->acPredFlag[mbnum];
    228 
    229 
    230 
    231     static const int Xpos[6] = { -1, 0, -1, 0, -1, -1};
    232     static const int Ypos[6] = { -1, -1, 0, 0, -1, -1};
    233 
    234     static const int Xtab[6] = {1, 0, 3, 2, 4, 5};
    235     static const int Ytab[6] = {2, 3, 0, 1, 4, 5};
    236 
    237     /* I added these to speed up comparisons */
    238     static const int Pos0[6] = { 1, 1, 0, 0, 1, 1};
    239     static const int Pos1[6] = { 1, 0, 1, 0, 1, 1};
    240 
    241     static const int B_Xtab[6] = {0, 1, 0, 1, 2, 3};
    242     static const int B_Ytab[6] = {0, 0, 1, 1, 2, 3};
    243 
    244 //  int *direction;     /* 0: HORIZONTAL, 1: VERTICAL */
    245     int block_A, block_C;
    246     int y_offset, x_offset, x_tab, y_tab;   /* speedup coefficients */
    247     int b_xtab, b_ytab;
    248     y_offset = Ypos[comp] * nMBPerRow;
    249     x_offset = Xpos[comp];
    250     x_tab = Xtab[comp];
    251     y_tab = Ytab[comp];
    252 
    253     b_xtab = B_Xtab[comp];
    254     b_ytab = B_Ytab[comp];
    255 
    256     /*----------------------------------------------------------------------------
    257     ; Function body here
    258     ----------------------------------------------------------------------------*/
    259     /* Find the direction of prediction and the DC prediction */
    260 
    261     if (x_pos == 0 && y_pos == 0)
    262     {   /* top left corner */
    263         block_A = (comp == 1 || comp == 3) ? flag_0 = TRUE, DC_store[0][x_tab] : mid_gray;
    264         block_C = (comp == 2 || comp == 3) ? flag_1 = TRUE, DC_store[0][y_tab] : mid_gray;
    265     }
    266     else if (x_pos == 0)
    267     {   /* left edge */
    268         up_bnd   = (Pos0[comp] && slice_nb[mbnum] == slice_nb[mbnum-nMBPerRow])
    269                    && (mode[mbnum-nMBPerRow] == MODE_INTRA || mode[mbnum-nMBPerRow] == MODE_INTRA_Q);;
    270 
    271         block_A = (comp == 1 || comp == 3) ? flag_0 = TRUE, DC_store[0][x_tab] : mid_gray;
    272         block_C = (comp == 2 || comp == 3 || up_bnd) ? flag_1 = TRUE, DC_store[y_offset][y_tab] : mid_gray;
    273     }
    274     else if (y_pos == 0)
    275     { /* top row */
    276         left_bnd = (Pos1[comp] && slice_nb[mbnum] == slice_nb[mbnum-1])
    277                    && (mode[mbnum-1] == MODE_INTRA || mode[mbnum-1] == MODE_INTRA_Q);
    278 
    279         block_A = (comp == 1 || comp == 3 || left_bnd) ? flag_0 = TRUE, DC_store[x_offset][x_tab] : mid_gray;
    280         block_C = (comp == 2 || comp == 3) ? flag_1 = TRUE, DC_store[y_offset][y_tab] : mid_gray;
    281     }
    282     else
    283     {
    284         up_bnd   = (Pos0[comp] && slice_nb[mbnum] == slice_nb[mbnum-nMBPerRow])
    285                    && (mode[mbnum-nMBPerRow] == MODE_INTRA || mode[mbnum-nMBPerRow] == MODE_INTRA_Q);
    286         left_bnd = (Pos1[comp] && slice_nb[mbnum] == slice_nb[mbnum-1])
    287                    && (mode[mbnum-1] == MODE_INTRA || mode[mbnum-1] == MODE_INTRA_Q);
    288 
    289         block_A = (comp == 1 || comp == 3 || left_bnd) ? flag_0 = TRUE, DC_store[x_offset][x_tab] : mid_gray;
    290         block_C = (comp == 2 || comp == 3 || up_bnd) ? flag_1 = TRUE, DC_store[y_offset][y_tab] : mid_gray;
    291     }
    292 
    293     if (ACpred_flag == 0)
    294     {
    295         if (flag_0 == TRUE)
    296         {
    297             if (flag_1 == TRUE)
    298             {
    299                 q_block[0] = (int16)((block_A + block_C) >> 1);
    300             }
    301             else
    302             {
    303                 q_block[0] = (int16)block_A;
    304             }
    305         }
    306         else
    307         {
    308             if (flag_1 == TRUE)
    309             {
    310                 q_block[0] = (int16)block_C;
    311             }
    312             else
    313             {
    314                 q_block[0] = mid_gray;
    315             }
    316         }
    317 
    318     }
    319     else
    320     {
    321         if (video->mblock->direction == 1)
    322         {
    323             if (flag_1 == TRUE)
    324             {
    325                 q_block[0] = (int16)block_C;
    326 
    327                 AC_tmp = DCAC_row[0][b_xtab];
    328                 q_block[1] = AC_tmp[0];
    329                 q_block[2] = AC_tmp[1];
    330                 q_block[3] = AC_tmp[2];
    331                 q_block[4] = AC_tmp[3];
    332                 q_block[5] = AC_tmp[4];
    333                 q_block[6] = AC_tmp[5];
    334                 q_block[7] = AC_tmp[6];
    335             }
    336             else
    337             {
    338                 q_block[0] = mid_gray;
    339             }
    340         }
    341         else
    342         {
    343             if (flag_0 == TRUE)
    344             {
    345                 q_block[0] = (int16)block_A;
    346 
    347                 AC_tmp = DCAC_col[0][b_ytab];
    348                 q_block[8] = AC_tmp[0];
    349                 q_block[16] = AC_tmp[1];
    350                 q_block[24] = AC_tmp[2];
    351                 q_block[32] = AC_tmp[3];
    352                 q_block[40] = AC_tmp[4];
    353                 q_block[48] = AC_tmp[5];
    354                 q_block[56] = AC_tmp[6];
    355             }
    356             else
    357             {
    358                 q_block[0] = mid_gray;
    359             }
    360         }
    361     }
    362     /*----------------------------------------------------------------------------
    363     ; Return nothing or data or data pointer
    364     ----------------------------------------------------------------------------*/
    365     return;
    366 }
    367 #endif
    368 
    369