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           h264bsdDecodeSeqParamSet
     27           GetDpbSize
     28           h264bsdCompareSeqParamSets
     29 
     30 ------------------------------------------------------------------------------*/
     31 
     32 /*------------------------------------------------------------------------------
     33     1. Include headers
     34 ------------------------------------------------------------------------------*/
     35 
     36 #include "h264bsd_seq_param_set.h"
     37 #include "h264bsd_util.h"
     38 #include "h264bsd_vlc.h"
     39 #include "h264bsd_vui.h"
     40 #include "h264bsd_cfg.h"
     41 
     42 /*------------------------------------------------------------------------------
     43     2. External compiler flags
     44 --------------------------------------------------------------------------------
     45 
     46 --------------------------------------------------------------------------------
     47     3. Module defines
     48 ------------------------------------------------------------------------------*/
     49 
     50 /* enumeration to indicate invalid return value from the GetDpbSize function */
     51 enum {INVALID_DPB_SIZE = 0x7FFFFFFF};
     52 
     53 /*------------------------------------------------------------------------------
     54     4. Local function prototypes
     55 ------------------------------------------------------------------------------*/
     56 
     57 static u32 GetDpbSize(u32 picSizeInMbs, u32 levelIdc);
     58 
     59 /*------------------------------------------------------------------------------
     60 
     61     Function name: h264bsdDecodeSeqParamSet
     62 
     63         Functional description:
     64             Decode sequence parameter set information from the stream.
     65 
     66             Function allocates memory for offsetForRefFrame array if
     67             picture order count type is 1 and numRefFramesInPicOrderCntCycle
     68             is greater than zero.
     69 
     70         Inputs:
     71             pStrmData       pointer to stream data structure
     72 
     73         Outputs:
     74             pSeqParamSet    decoded information is stored here
     75 
     76         Returns:
     77             HANTRO_OK       success
     78             HANTRO_NOK      failure, invalid information or end of stream
     79             MEMORY_ALLOCATION_ERROR for memory allocation failure
     80 
     81 ------------------------------------------------------------------------------*/
     82 
     83 u32 h264bsdDecodeSeqParamSet(strmData_t *pStrmData, seqParamSet_t *pSeqParamSet)
     84 {
     85 
     86 /* Variables */
     87 
     88     u32 tmp, i, value;
     89 
     90 /* Code */
     91 
     92     ASSERT(pStrmData);
     93     ASSERT(pSeqParamSet);
     94 
     95     H264SwDecMemset(pSeqParamSet, 0, sizeof(seqParamSet_t));
     96 
     97     /* profile_idc */
     98     tmp = h264bsdGetBits(pStrmData, 8);
     99     if (tmp == END_OF_STREAM)
    100         return(HANTRO_NOK);
    101     if (tmp != 66)
    102     {
    103         DEBUG(("NOT BASELINE PROFILE %d\n", tmp));
    104     }
    105     pSeqParamSet->profileIdc = tmp;
    106 
    107     /* constrained_set0_flag */
    108     tmp = h264bsdGetBits(pStrmData, 1);
    109     /* constrained_set1_flag */
    110     tmp = h264bsdGetBits(pStrmData, 1);
    111     /* constrained_set2_flag */
    112     tmp = h264bsdGetBits(pStrmData, 1);
    113 
    114     if (tmp == END_OF_STREAM)
    115         return(HANTRO_NOK);
    116 
    117     /* reserved_zero_5bits, values of these bits shall be ignored */
    118     tmp = h264bsdGetBits(pStrmData, 5);
    119     if (tmp == END_OF_STREAM)
    120         return(HANTRO_NOK);
    121 
    122     tmp = h264bsdGetBits(pStrmData, 8);
    123     if (tmp == END_OF_STREAM)
    124         return(HANTRO_NOK);
    125     pSeqParamSet->levelIdc = tmp;
    126 
    127     tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
    128         &pSeqParamSet->seqParameterSetId);
    129     if (tmp != HANTRO_OK)
    130         return(tmp);
    131     if (pSeqParamSet->seqParameterSetId >= MAX_NUM_SEQ_PARAM_SETS)
    132     {
    133         EPRINT("seq_param_set_id");
    134         return(HANTRO_NOK);
    135     }
    136 
    137     /* log2_max_frame_num_minus4 */
    138     tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
    139     if (tmp != HANTRO_OK)
    140         return(tmp);
    141     if (value > 12)
    142     {
    143         EPRINT("log2_max_frame_num_minus4");
    144         return(HANTRO_NOK);
    145     }
    146     /* maxFrameNum = 2^(log2_max_frame_num_minus4 + 4) */
    147     pSeqParamSet->maxFrameNum = 1 << (value+4);
    148 
    149     /* valid POC types are 0, 1 and 2 */
    150     tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
    151     if (tmp != HANTRO_OK)
    152         return(tmp);
    153     if (value > 2)
    154     {
    155         EPRINT("pic_order_cnt_type");
    156         return(HANTRO_NOK);
    157     }
    158     pSeqParamSet->picOrderCntType = value;
    159 
    160     if (pSeqParamSet->picOrderCntType == 0)
    161     {
    162         /* log2_max_pic_order_cnt_lsb_minus4 */
    163         tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
    164         if (tmp != HANTRO_OK)
    165             return(tmp);
    166         if (value > 12)
    167         {
    168             EPRINT("log2_max_pic_order_cnt_lsb_minus4");
    169             return(HANTRO_NOK);
    170         }
    171         /* maxPicOrderCntLsb = 2^(log2_max_pic_order_cnt_lsb_minus4 + 4) */
    172         pSeqParamSet->maxPicOrderCntLsb = 1 << (value+4);
    173     }
    174     else if (pSeqParamSet->picOrderCntType == 1)
    175     {
    176         tmp = h264bsdGetBits(pStrmData, 1);
    177         if (tmp == END_OF_STREAM)
    178             return(HANTRO_NOK);
    179         pSeqParamSet->deltaPicOrderAlwaysZeroFlag = (tmp == 1) ?
    180                                         HANTRO_TRUE : HANTRO_FALSE;
    181 
    182         tmp = h264bsdDecodeExpGolombSigned(pStrmData,
    183             &pSeqParamSet->offsetForNonRefPic);
    184         if (tmp != HANTRO_OK)
    185             return(tmp);
    186 
    187         tmp = h264bsdDecodeExpGolombSigned(pStrmData,
    188             &pSeqParamSet->offsetForTopToBottomField);
    189         if (tmp != HANTRO_OK)
    190             return(tmp);
    191 
    192         tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
    193             &pSeqParamSet->numRefFramesInPicOrderCntCycle);
    194         if (tmp != HANTRO_OK)
    195             return(tmp);
    196         if (pSeqParamSet->numRefFramesInPicOrderCntCycle > 255)
    197         {
    198             EPRINT("num_ref_frames_in_pic_order_cnt_cycle");
    199             return(HANTRO_NOK);
    200         }
    201 
    202         if (pSeqParamSet->numRefFramesInPicOrderCntCycle)
    203         {
    204             /* NOTE: This has to be freed somewhere! */
    205             ALLOCATE(pSeqParamSet->offsetForRefFrame,
    206                      pSeqParamSet->numRefFramesInPicOrderCntCycle, i32);
    207             if (pSeqParamSet->offsetForRefFrame == NULL)
    208                 return(MEMORY_ALLOCATION_ERROR);
    209 
    210             for (i = 0; i < pSeqParamSet->numRefFramesInPicOrderCntCycle; i++)
    211             {
    212                 tmp =  h264bsdDecodeExpGolombSigned(pStrmData,
    213                     pSeqParamSet->offsetForRefFrame + i);
    214                 if (tmp != HANTRO_OK)
    215                     return(tmp);
    216             }
    217         }
    218         else
    219         {
    220             pSeqParamSet->offsetForRefFrame = NULL;
    221         }
    222     }
    223 
    224     tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
    225         &pSeqParamSet->numRefFrames);
    226     if (tmp != HANTRO_OK)
    227         return(tmp);
    228     if (pSeqParamSet->numRefFrames > MAX_NUM_REF_PICS)
    229     {
    230         EPRINT("num_ref_frames");
    231         return(HANTRO_NOK);
    232     }
    233 
    234     tmp = h264bsdGetBits(pStrmData, 1);
    235     if (tmp == END_OF_STREAM)
    236         return(HANTRO_NOK);
    237     pSeqParamSet->gapsInFrameNumValueAllowedFlag = (tmp == 1) ?
    238                                         HANTRO_TRUE : HANTRO_FALSE;
    239 
    240     tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
    241     if (tmp != HANTRO_OK)
    242         return(tmp);
    243     pSeqParamSet->picWidthInMbs = value + 1;
    244 
    245     tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
    246     if (tmp != HANTRO_OK)
    247         return(tmp);
    248     pSeqParamSet->picHeightInMbs = value + 1;
    249 
    250     /* frame_mbs_only_flag, shall be 1 for baseline profile */
    251     tmp = h264bsdGetBits(pStrmData, 1);
    252     if (tmp == END_OF_STREAM)
    253         return(HANTRO_NOK);
    254     if (!tmp)
    255     {
    256         EPRINT("frame_mbs_only_flag");
    257         return(HANTRO_NOK);
    258     }
    259 
    260     /* direct_8x8_inference_flag */
    261     tmp = h264bsdGetBits(pStrmData, 1);
    262     if (tmp == END_OF_STREAM)
    263         return(HANTRO_NOK);
    264 
    265     tmp = h264bsdGetBits(pStrmData, 1);
    266     if (tmp == END_OF_STREAM)
    267         return(HANTRO_NOK);
    268     pSeqParamSet->frameCroppingFlag = (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
    269 
    270     if (pSeqParamSet->frameCroppingFlag)
    271     {
    272         tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
    273             &pSeqParamSet->frameCropLeftOffset);
    274         if (tmp != HANTRO_OK)
    275             return(tmp);
    276         tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
    277             &pSeqParamSet->frameCropRightOffset);
    278         if (tmp != HANTRO_OK)
    279             return(tmp);
    280         tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
    281             &pSeqParamSet->frameCropTopOffset);
    282         if (tmp != HANTRO_OK)
    283             return(tmp);
    284         tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
    285             &pSeqParamSet->frameCropBottomOffset);
    286         if (tmp != HANTRO_OK)
    287             return(tmp);
    288 
    289         /* check that frame cropping params are valid, parameters shall
    290          * specify non-negative area within the original picture */
    291         if ( ( (i32)pSeqParamSet->frameCropLeftOffset >
    292                ( 8 * (i32)pSeqParamSet->picWidthInMbs -
    293                  ((i32)pSeqParamSet->frameCropRightOffset + 1) ) ) ||
    294              ( (i32)pSeqParamSet->frameCropTopOffset >
    295                ( 8 * (i32)pSeqParamSet->picHeightInMbs -
    296                  ((i32)pSeqParamSet->frameCropBottomOffset + 1) ) ) )
    297         {
    298             EPRINT("frame_cropping");
    299             return(HANTRO_NOK);
    300         }
    301     }
    302 
    303     /* check that image dimensions and levelIdc match */
    304     tmp = pSeqParamSet->picWidthInMbs * pSeqParamSet->picHeightInMbs;
    305     value = GetDpbSize(tmp, pSeqParamSet->levelIdc);
    306     if (value == INVALID_DPB_SIZE || pSeqParamSet->numRefFrames > value)
    307     {
    308         DEBUG(("WARNING! Invalid DPB size based on SPS Level!\n"));
    309         DEBUG(("WARNING! Using num_ref_frames =%d for DPB size!\n",
    310                         pSeqParamSet->numRefFrames));
    311         value = pSeqParamSet->numRefFrames;
    312     }
    313     pSeqParamSet->maxDpbSize = value;
    314 
    315     tmp = h264bsdGetBits(pStrmData, 1);
    316     if (tmp == END_OF_STREAM)
    317         return(HANTRO_NOK);
    318     pSeqParamSet->vuiParametersPresentFlag = (tmp == 1) ?
    319                                 HANTRO_TRUE : HANTRO_FALSE;
    320 
    321     /* VUI */
    322     if (pSeqParamSet->vuiParametersPresentFlag)
    323     {
    324         ALLOCATE(pSeqParamSet->vuiParameters, 1, vuiParameters_t);
    325         if (pSeqParamSet->vuiParameters == NULL)
    326             return(MEMORY_ALLOCATION_ERROR);
    327         tmp = h264bsdDecodeVuiParameters(pStrmData,
    328             pSeqParamSet->vuiParameters);
    329         if (tmp != HANTRO_OK)
    330             return(tmp);
    331         /* check numReorderFrames and maxDecFrameBuffering */
    332         if (pSeqParamSet->vuiParameters->bitstreamRestrictionFlag)
    333         {
    334             if (pSeqParamSet->vuiParameters->numReorderFrames >
    335                     pSeqParamSet->vuiParameters->maxDecFrameBuffering ||
    336                 pSeqParamSet->vuiParameters->maxDecFrameBuffering <
    337                     pSeqParamSet->numRefFrames ||
    338                 pSeqParamSet->vuiParameters->maxDecFrameBuffering >
    339                     pSeqParamSet->maxDpbSize)
    340             {
    341                 return(HANTRO_NOK);
    342             }
    343 
    344             /* standard says that "the sequence shall not require a DPB with
    345              * size of more than max(1, maxDecFrameBuffering) */
    346             pSeqParamSet->maxDpbSize =
    347                 MAX(1, pSeqParamSet->vuiParameters->maxDecFrameBuffering);
    348         }
    349     }
    350 
    351     tmp = h264bsdRbspTrailingBits(pStrmData);
    352 
    353     /* ignore possible errors in trailing bits of parameters sets */
    354     return(HANTRO_OK);
    355 
    356 }
    357 
    358 /*------------------------------------------------------------------------------
    359 
    360     Function: GetDpbSize
    361 
    362         Functional description:
    363             Get size of the DPB in frames. Size is determined based on the
    364             picture size and MaxDPB for the specified level. These determine
    365             how many pictures may fit into to the buffer. However, the size
    366             is also limited to a maximum of 16 frames and therefore function
    367             returns the minimum of the determined size and 16.
    368 
    369         Inputs:
    370             picSizeInMbs    number of macroblocks in the picture
    371             levelIdc        indicates the level
    372 
    373         Outputs:
    374             none
    375 
    376         Returns:
    377             size of the DPB in frames
    378             INVALID_DPB_SIZE when invalid levelIdc specified or picSizeInMbs
    379             is higher than supported by the level in question
    380 
    381 ------------------------------------------------------------------------------*/
    382 
    383 u32 GetDpbSize(u32 picSizeInMbs, u32 levelIdc)
    384 {
    385 
    386 /* Variables */
    387 
    388     u32 tmp;
    389     u32 maxPicSizeInMbs;
    390 
    391 /* Code */
    392 
    393     ASSERT(picSizeInMbs);
    394 
    395     /* use tmp as the size of the DPB in bytes, computes as 1024 * MaxDPB
    396      * (from table A-1 in Annex A) */
    397     switch (levelIdc)
    398     {
    399         case 10:
    400             tmp = 152064;
    401             maxPicSizeInMbs = 99;
    402             break;
    403 
    404         case 11:
    405             tmp = 345600;
    406             maxPicSizeInMbs = 396;
    407             break;
    408 
    409         case 12:
    410             tmp = 912384;
    411             maxPicSizeInMbs = 396;
    412             break;
    413 
    414         case 13:
    415             tmp = 912384;
    416             maxPicSizeInMbs = 396;
    417             break;
    418 
    419         case 20:
    420             tmp = 912384;
    421             maxPicSizeInMbs = 396;
    422             break;
    423 
    424         case 21:
    425             tmp = 1824768;
    426             maxPicSizeInMbs = 792;
    427             break;
    428 
    429         case 22:
    430             tmp = 3110400;
    431             maxPicSizeInMbs = 1620;
    432             break;
    433 
    434         case 30:
    435             tmp = 3110400;
    436             maxPicSizeInMbs = 1620;
    437             break;
    438 
    439         case 31:
    440             tmp = 6912000;
    441             maxPicSizeInMbs = 3600;
    442             break;
    443 
    444         case 32:
    445             tmp = 7864320;
    446             maxPicSizeInMbs = 5120;
    447             break;
    448 
    449         case 40:
    450             tmp = 12582912;
    451             maxPicSizeInMbs = 8192;
    452             break;
    453 
    454         case 41:
    455             tmp = 12582912;
    456             maxPicSizeInMbs = 8192;
    457             break;
    458 
    459         case 42:
    460             tmp = 34816*384;
    461             maxPicSizeInMbs = 8704;
    462             break;
    463 
    464         case 50:
    465             /* standard says 42301440 here, but corrigendum "corrects" this to
    466              * 42393600 */
    467             tmp = 42393600;
    468             maxPicSizeInMbs = 22080;
    469             break;
    470 
    471         case 51:
    472             tmp = 70778880;
    473             maxPicSizeInMbs = 36864;
    474             break;
    475 
    476         default:
    477             return(INVALID_DPB_SIZE);
    478     }
    479 
    480     /* this is not "correct" return value! However, it results in error in
    481      * decoding and this was easiest place to check picture size */
    482     if (picSizeInMbs > maxPicSizeInMbs)
    483         return(INVALID_DPB_SIZE);
    484 
    485     tmp /= (picSizeInMbs*384);
    486 
    487     return(MIN(tmp, 16));
    488 
    489 }
    490 
    491 /*------------------------------------------------------------------------------
    492 
    493     Function name: h264bsdCompareSeqParamSets
    494 
    495         Functional description:
    496             Compare two sequence parameter sets.
    497 
    498         Inputs:
    499             pSps1   pointer to a sequence parameter set
    500             pSps2   pointer to another sequence parameter set
    501 
    502         Outputs:
    503             0       sequence parameter sets are equal
    504             1       otherwise
    505 
    506 ------------------------------------------------------------------------------*/
    507 
    508 u32 h264bsdCompareSeqParamSets(seqParamSet_t *pSps1, seqParamSet_t *pSps2)
    509 {
    510 
    511 /* Variables */
    512 
    513     u32 i;
    514 
    515 /* Code */
    516 
    517     ASSERT(pSps1);
    518     ASSERT(pSps2);
    519 
    520     /* first compare parameters whose existence does not depend on other
    521      * parameters and only compare the rest of the params if these are equal */
    522     if (pSps1->profileIdc        == pSps2->profileIdc &&
    523         pSps1->levelIdc          == pSps2->levelIdc &&
    524         pSps1->maxFrameNum       == pSps2->maxFrameNum &&
    525         pSps1->picOrderCntType   == pSps2->picOrderCntType &&
    526         pSps1->numRefFrames      == pSps2->numRefFrames &&
    527         pSps1->gapsInFrameNumValueAllowedFlag ==
    528             pSps2->gapsInFrameNumValueAllowedFlag &&
    529         pSps1->picWidthInMbs     == pSps2->picWidthInMbs &&
    530         pSps1->picHeightInMbs    == pSps2->picHeightInMbs &&
    531         pSps1->frameCroppingFlag == pSps2->frameCroppingFlag &&
    532         pSps1->vuiParametersPresentFlag == pSps2->vuiParametersPresentFlag)
    533     {
    534         if (pSps1->picOrderCntType == 0)
    535         {
    536             if (pSps1->maxPicOrderCntLsb != pSps2->maxPicOrderCntLsb)
    537                 return 1;
    538         }
    539         else if (pSps1->picOrderCntType == 1)
    540         {
    541             if (pSps1->deltaPicOrderAlwaysZeroFlag !=
    542                     pSps2->deltaPicOrderAlwaysZeroFlag ||
    543                 pSps1->offsetForNonRefPic != pSps2->offsetForNonRefPic ||
    544                 pSps1->offsetForTopToBottomField !=
    545                     pSps2->offsetForTopToBottomField ||
    546                 pSps1->numRefFramesInPicOrderCntCycle !=
    547                     pSps2->numRefFramesInPicOrderCntCycle)
    548             {
    549                 return 1;
    550             }
    551             else
    552             {
    553                 for (i = 0; i < pSps1->numRefFramesInPicOrderCntCycle; i++)
    554                     if (pSps1->offsetForRefFrame[i] !=
    555                         pSps2->offsetForRefFrame[i])
    556                     {
    557                         return 1;
    558                     }
    559             }
    560         }
    561         if (pSps1->frameCroppingFlag)
    562         {
    563             if (pSps1->frameCropLeftOffset   != pSps2->frameCropLeftOffset ||
    564                 pSps1->frameCropRightOffset  != pSps2->frameCropRightOffset ||
    565                 pSps1->frameCropTopOffset    != pSps2->frameCropTopOffset ||
    566                 pSps1->frameCropBottomOffset != pSps2->frameCropBottomOffset)
    567             {
    568                 return 1;
    569             }
    570         }
    571 
    572         return 0;
    573     }
    574 
    575     return 1;
    576 }
    577 
    578