Home | History | Annotate | Download | only in source
      1 /*
      2  * Copyright (C) 2009 The Android Open Source Project
      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 express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 /*------------------------------------------------------------------------------
     18 
     19     Table of contents
     20 
     21      1. Include headers
     22      2. External compiler flags
     23      3. Module defines
     24      4. Local function prototypes
     25      5. Functions
     26           h264bsdDecodePicParamSet
     27 
     28 ------------------------------------------------------------------------------*/
     29 
     30 /*------------------------------------------------------------------------------
     31     1. Include headers
     32 ------------------------------------------------------------------------------*/
     33 
     34 #include "h264bsd_pic_param_set.h"
     35 #include "h264bsd_util.h"
     36 #include "h264bsd_vlc.h"
     37 #include "h264bsd_cfg.h"
     38 
     39 /*------------------------------------------------------------------------------
     40     2. External compiler flags
     41 --------------------------------------------------------------------------------
     42 
     43 --------------------------------------------------------------------------------
     44     3. Module defines
     45 ------------------------------------------------------------------------------*/
     46 
     47 /* lookup table for ceil(log2(numSliceGroups)), i.e. number of bits needed to
     48  * represent range [0, numSliceGroups)
     49  *
     50  * NOTE: if MAX_NUM_SLICE_GROUPS is higher than 8 this table has to be resized
     51  * accordingly */
     52 static const u32 CeilLog2NumSliceGroups[8] = {1, 1, 2, 2, 3, 3, 3, 3};
     53 
     54 /*------------------------------------------------------------------------------
     55     4. Local function prototypes
     56 ------------------------------------------------------------------------------*/
     57 
     58 /*------------------------------------------------------------------------------
     59 
     60     Function name: h264bsdDecodePicParamSet
     61 
     62         Functional description:
     63             Decode picture parameter set information from the stream.
     64 
     65             Function allocates memory for
     66                 - run lengths if slice group map type is 0
     67                 - top-left and bottom-right arrays if map type is 2
     68                 - for slice group ids if map type is 6
     69 
     70             Validity of some of the slice group mapping information depends
     71             on the image dimensions which are not known here. Therefore the
     72             validity has to be checked afterwards, currently in the parameter
     73             set activation phase.
     74 
     75         Inputs:
     76             pStrmData       pointer to stream data structure
     77 
     78         Outputs:
     79             pPicParamSet    decoded information is stored here
     80 
     81         Returns:
     82             HANTRO_OK       success
     83             HANTRO_NOK      failure, invalid information or end of stream
     84             MEMORY_ALLOCATION_ERROR for memory allocation failure
     85 
     86 
     87 ------------------------------------------------------------------------------*/
     88 
     89 u32 h264bsdDecodePicParamSet(strmData_t *pStrmData, picParamSet_t *pPicParamSet)
     90 {
     91 
     92 /* Variables */
     93 
     94     u32 tmp, i, value;
     95     i32 itmp;
     96 
     97 /* Code */
     98 
     99     ASSERT(pStrmData);
    100     ASSERT(pPicParamSet);
    101 
    102 
    103     H264SwDecMemset(pPicParamSet, 0, sizeof(picParamSet_t));
    104 
    105     tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
    106         &pPicParamSet->picParameterSetId);
    107     if (tmp != HANTRO_OK)
    108         return(tmp);
    109     if (pPicParamSet->picParameterSetId >= MAX_NUM_PIC_PARAM_SETS)
    110     {
    111         EPRINT("pic_parameter_set_id");
    112         return(HANTRO_NOK);
    113     }
    114 
    115     tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
    116         &pPicParamSet->seqParameterSetId);
    117     if (tmp != HANTRO_OK)
    118         return(tmp);
    119     if (pPicParamSet->seqParameterSetId >= MAX_NUM_SEQ_PARAM_SETS)
    120     {
    121         EPRINT("seq_param_set_id");
    122         return(HANTRO_NOK);
    123     }
    124 
    125     /* entropy_coding_mode_flag, shall be 0 for baseline profile */
    126     tmp = h264bsdGetBits(pStrmData, 1);
    127     if (tmp)
    128     {
    129         EPRINT("entropy_coding_mode_flag");
    130         return(HANTRO_NOK);
    131     }
    132 
    133     tmp = h264bsdGetBits(pStrmData, 1);
    134     if (tmp == END_OF_STREAM)
    135         return(HANTRO_NOK);
    136     pPicParamSet->picOrderPresentFlag = (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
    137 
    138     /* num_slice_groups_minus1 */
    139     tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
    140     if (tmp != HANTRO_OK)
    141         return(tmp);
    142     pPicParamSet->numSliceGroups = value + 1;
    143     if (pPicParamSet->numSliceGroups > MAX_NUM_SLICE_GROUPS)
    144     {
    145         EPRINT("num_slice_groups_minus1");
    146         return(HANTRO_NOK);
    147     }
    148 
    149     /* decode slice group mapping information if more than one slice groups */
    150     if (pPicParamSet->numSliceGroups > 1)
    151     {
    152         tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
    153             &pPicParamSet->sliceGroupMapType);
    154         if (tmp != HANTRO_OK)
    155             return(tmp);
    156         if (pPicParamSet->sliceGroupMapType > 6)
    157         {
    158             EPRINT("slice_group_map_type");
    159             return(HANTRO_NOK);
    160         }
    161 
    162         if (pPicParamSet->sliceGroupMapType == 0)
    163         {
    164             ALLOCATE(pPicParamSet->runLength,
    165                 pPicParamSet->numSliceGroups, u32);
    166             if (pPicParamSet->runLength == NULL)
    167                 return(MEMORY_ALLOCATION_ERROR);
    168             for (i = 0; i < pPicParamSet->numSliceGroups; i++)
    169             {
    170                 tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
    171                 if (tmp != HANTRO_OK)
    172                     return(tmp);
    173                 pPicParamSet->runLength[i] = value+1;
    174                 /* param values checked in CheckPps() */
    175             }
    176         }
    177         else if (pPicParamSet->sliceGroupMapType == 2)
    178         {
    179             ALLOCATE(pPicParamSet->topLeft,
    180                 pPicParamSet->numSliceGroups - 1, u32);
    181             ALLOCATE(pPicParamSet->bottomRight,
    182                 pPicParamSet->numSliceGroups - 1, u32);
    183             if (pPicParamSet->topLeft == NULL ||
    184                 pPicParamSet->bottomRight == NULL)
    185                 return(MEMORY_ALLOCATION_ERROR);
    186             for (i = 0; i < pPicParamSet->numSliceGroups - 1; i++)
    187             {
    188                 tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
    189                 if (tmp != HANTRO_OK)
    190                     return(tmp);
    191                 pPicParamSet->topLeft[i] = value;
    192                 tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
    193                 if (tmp != HANTRO_OK)
    194                     return(tmp);
    195                 pPicParamSet->bottomRight[i] = value;
    196                 /* param values checked in CheckPps() */
    197             }
    198         }
    199         else if ( (pPicParamSet->sliceGroupMapType == 3) ||
    200                   (pPicParamSet->sliceGroupMapType == 4) ||
    201                   (pPicParamSet->sliceGroupMapType == 5) )
    202         {
    203             tmp = h264bsdGetBits(pStrmData, 1);
    204             if (tmp == END_OF_STREAM)
    205                 return(HANTRO_NOK);
    206             pPicParamSet->sliceGroupChangeDirectionFlag =
    207                 (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
    208             tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
    209             if (tmp != HANTRO_OK)
    210                 return(tmp);
    211             pPicParamSet->sliceGroupChangeRate = value + 1;
    212             /* param value checked in CheckPps() */
    213         }
    214         else if (pPicParamSet->sliceGroupMapType == 6)
    215         {
    216             tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
    217             if (tmp != HANTRO_OK)
    218                 return(tmp);
    219             pPicParamSet->picSizeInMapUnits = value + 1;
    220 
    221             ALLOCATE(pPicParamSet->sliceGroupId,
    222                 pPicParamSet->picSizeInMapUnits, u32);
    223             if (pPicParamSet->sliceGroupId == NULL)
    224                 return(MEMORY_ALLOCATION_ERROR);
    225 
    226             /* determine number of bits needed to represent range
    227              * [0, numSliceGroups) */
    228             tmp = CeilLog2NumSliceGroups[pPicParamSet->numSliceGroups-1];
    229 
    230             for (i = 0; i < pPicParamSet->picSizeInMapUnits; i++)
    231             {
    232                 pPicParamSet->sliceGroupId[i] = h264bsdGetBits(pStrmData, tmp);
    233                 if ( pPicParamSet->sliceGroupId[i] >=
    234                      pPicParamSet->numSliceGroups )
    235                 {
    236                     EPRINT("slice_group_id");
    237                     return(HANTRO_NOK);
    238                 }
    239             }
    240         }
    241     }
    242 
    243     /* num_ref_idx_l0_active_minus1 */
    244     tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
    245     if (tmp != HANTRO_OK)
    246         return(tmp);
    247     if (value > 31)
    248     {
    249         EPRINT("num_ref_idx_l0_active_minus1");
    250         return(HANTRO_NOK);
    251     }
    252     pPicParamSet->numRefIdxL0Active = value + 1;
    253 
    254     /* num_ref_idx_l1_active_minus1 */
    255     tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
    256     if (tmp != HANTRO_OK)
    257         return(tmp);
    258     if (value > 31)
    259     {
    260         EPRINT("num_ref_idx_l1_active_minus1");
    261         return(HANTRO_NOK);
    262     }
    263 
    264     /* weighted_pred_flag, this shall be 0 for baseline profile */
    265     tmp = h264bsdGetBits(pStrmData, 1);
    266     if (tmp)
    267     {
    268         EPRINT("weighted_pred_flag");
    269         return(HANTRO_NOK);
    270     }
    271 
    272     /* weighted_bipred_idc */
    273     tmp = h264bsdGetBits(pStrmData, 2);
    274     if (tmp > 2)
    275     {
    276         EPRINT("weighted_bipred_idc");
    277         return(HANTRO_NOK);
    278     }
    279 
    280     /* pic_init_qp_minus26 */
    281     tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp);
    282     if (tmp != HANTRO_OK)
    283         return(tmp);
    284     if ((itmp < -26) || (itmp > 25))
    285     {
    286         EPRINT("pic_init_qp_minus26");
    287         return(HANTRO_NOK);
    288     }
    289     pPicParamSet->picInitQp = (u32)(itmp + 26);
    290 
    291     /* pic_init_qs_minus26 */
    292     tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp);
    293     if (tmp != HANTRO_OK)
    294         return(tmp);
    295     if ((itmp < -26) || (itmp > 25))
    296     {
    297         EPRINT("pic_init_qs_minus26");
    298         return(HANTRO_NOK);
    299     }
    300 
    301     tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp);
    302     if (tmp != HANTRO_OK)
    303         return(tmp);
    304     if ((itmp < -12) || (itmp > 12))
    305     {
    306         EPRINT("chroma_qp_index_offset");
    307         return(HANTRO_NOK);
    308     }
    309     pPicParamSet->chromaQpIndexOffset = itmp;
    310 
    311     tmp = h264bsdGetBits(pStrmData, 1);
    312     if (tmp == END_OF_STREAM)
    313         return(HANTRO_NOK);
    314     pPicParamSet->deblockingFilterControlPresentFlag =
    315         (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
    316 
    317     tmp = h264bsdGetBits(pStrmData, 1);
    318     if (tmp == END_OF_STREAM)
    319         return(HANTRO_NOK);
    320     pPicParamSet->constrainedIntraPredFlag = (tmp == 1) ?
    321                                     HANTRO_TRUE : HANTRO_FALSE;
    322 
    323     tmp = h264bsdGetBits(pStrmData, 1);
    324     if (tmp == END_OF_STREAM)
    325         return(HANTRO_NOK);
    326     pPicParamSet->redundantPicCntPresentFlag = (tmp == 1) ?
    327                                     HANTRO_TRUE : HANTRO_FALSE;
    328 
    329     tmp = h264bsdRbspTrailingBits(pStrmData);
    330 
    331     /* ignore possible errors in trailing bits of parameters sets */
    332     return(HANTRO_OK);
    333 
    334 }
    335 
    336