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           h264bsdDecodeVuiParameters
     27           DecodeHrdParameters
     28 
     29 ------------------------------------------------------------------------------*/
     30 
     31 /*------------------------------------------------------------------------------
     32     1. Include headers
     33 ------------------------------------------------------------------------------*/
     34 
     35 #include "h264bsd_vui.h"
     36 #include "basetype.h"
     37 #include "h264bsd_vlc.h"
     38 #include "h264bsd_stream.h"
     39 #include "h264bsd_util.h"
     40 
     41 /*------------------------------------------------------------------------------
     42     2. External compiler flags
     43 --------------------------------------------------------------------------------
     44 
     45 --------------------------------------------------------------------------------
     46     3. Module defines
     47 ------------------------------------------------------------------------------*/
     48 
     49 #define MAX_DPB_SIZE 16
     50 #define MAX_BR       240000 /* for level 5.1 */
     51 #define MAX_CPB      240000 /* for level 5.1 */
     52 
     53 /*------------------------------------------------------------------------------
     54     4. Local function prototypes
     55 ------------------------------------------------------------------------------*/
     56 
     57 static u32 DecodeHrdParameters(
     58   strmData_t *pStrmData,
     59   hrdParameters_t *pHrdParameters);
     60 
     61 /*------------------------------------------------------------------------------
     62 
     63     Function: h264bsdDecodeVuiParameters
     64 
     65         Functional description:
     66             Decode VUI parameters from the stream. See standard for details.
     67 
     68         Inputs:
     69             pStrmData       pointer to stream data structure
     70 
     71         Outputs:
     72             pVuiParameters  decoded information is stored here
     73 
     74         Returns:
     75             HANTRO_OK       success
     76             HANTRO_NOK      invalid stream data or end of stream
     77 
     78 ------------------------------------------------------------------------------*/
     79 
     80 u32 h264bsdDecodeVuiParameters(strmData_t *pStrmData,
     81     vuiParameters_t *pVuiParameters)
     82 {
     83 
     84 /* Variables */
     85 
     86     u32 tmp;
     87 
     88 /* Code */
     89 
     90     ASSERT(pStrmData);
     91     ASSERT(pVuiParameters);
     92 
     93     H264SwDecMemset(pVuiParameters, 0, sizeof(vuiParameters_t));
     94 
     95     tmp = h264bsdGetBits(pStrmData, 1);
     96     if (tmp == END_OF_STREAM)
     97         return(HANTRO_NOK);
     98     pVuiParameters->aspectRatioPresentFlag = (tmp == 1) ?
     99                                 HANTRO_TRUE : HANTRO_FALSE;
    100 
    101     if (pVuiParameters->aspectRatioPresentFlag)
    102     {
    103         tmp = h264bsdGetBits(pStrmData, 8);
    104         if (tmp == END_OF_STREAM)
    105             return(HANTRO_NOK);
    106         pVuiParameters->aspectRatioIdc = tmp;
    107 
    108         if (pVuiParameters->aspectRatioIdc == ASPECT_RATIO_EXTENDED_SAR)
    109         {
    110             tmp = h264bsdGetBits(pStrmData, 16);
    111             if (tmp == END_OF_STREAM)
    112                 return(HANTRO_NOK);
    113             pVuiParameters->sarWidth = tmp;
    114 
    115             tmp = h264bsdGetBits(pStrmData, 16);
    116             if (tmp == END_OF_STREAM)
    117                 return(HANTRO_NOK);
    118             pVuiParameters->sarHeight = tmp;
    119         }
    120     }
    121 
    122     tmp = h264bsdGetBits(pStrmData, 1);
    123     if (tmp == END_OF_STREAM)
    124         return(HANTRO_NOK);
    125     pVuiParameters->overscanInfoPresentFlag = (tmp == 1) ?
    126                                 HANTRO_TRUE : HANTRO_FALSE;
    127 
    128     if (pVuiParameters->overscanInfoPresentFlag)
    129     {
    130         tmp = h264bsdGetBits(pStrmData, 1);
    131         if (tmp == END_OF_STREAM)
    132             return(HANTRO_NOK);
    133         pVuiParameters->overscanAppropriateFlag = (tmp == 1) ?
    134                                 HANTRO_TRUE : HANTRO_FALSE;
    135     }
    136 
    137     tmp = h264bsdGetBits(pStrmData, 1);
    138     if (tmp == END_OF_STREAM)
    139         return(HANTRO_NOK);
    140     pVuiParameters->videoSignalTypePresentFlag = (tmp == 1) ?
    141                                 HANTRO_TRUE : HANTRO_FALSE;
    142 
    143     if (pVuiParameters->videoSignalTypePresentFlag)
    144     {
    145         tmp = h264bsdGetBits(pStrmData, 3);
    146         if (tmp == END_OF_STREAM)
    147             return(HANTRO_NOK);
    148         pVuiParameters->videoFormat = tmp;
    149 
    150         tmp = h264bsdGetBits(pStrmData, 1);
    151         if (tmp == END_OF_STREAM)
    152             return(HANTRO_NOK);
    153         pVuiParameters->videoFullRangeFlag = (tmp == 1) ?
    154                                 HANTRO_TRUE : HANTRO_FALSE;
    155 
    156         tmp = h264bsdGetBits(pStrmData, 1);
    157         if (tmp == END_OF_STREAM)
    158             return(HANTRO_NOK);
    159         pVuiParameters->colourDescriptionPresentFlag =
    160             (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
    161 
    162         if (pVuiParameters->colourDescriptionPresentFlag)
    163         {
    164             tmp = h264bsdGetBits(pStrmData, 8);
    165             if (tmp == END_OF_STREAM)
    166                 return(HANTRO_NOK);
    167             pVuiParameters->colourPrimaries = tmp;
    168 
    169             tmp = h264bsdGetBits(pStrmData, 8);
    170             if (tmp == END_OF_STREAM)
    171                 return(HANTRO_NOK);
    172             pVuiParameters->transferCharacteristics = tmp;
    173 
    174             tmp = h264bsdGetBits(pStrmData, 8);
    175             if (tmp == END_OF_STREAM)
    176                 return(HANTRO_NOK);
    177             pVuiParameters->matrixCoefficients = tmp;
    178         }
    179         else
    180         {
    181             pVuiParameters->colourPrimaries         = 2;
    182             pVuiParameters->transferCharacteristics = 2;
    183             pVuiParameters->matrixCoefficients      = 2;
    184         }
    185     }
    186     else
    187     {
    188         pVuiParameters->videoFormat             = 5;
    189         pVuiParameters->colourPrimaries         = 2;
    190         pVuiParameters->transferCharacteristics = 2;
    191         pVuiParameters->matrixCoefficients      = 2;
    192     }
    193 
    194     tmp = h264bsdGetBits(pStrmData, 1);
    195     if (tmp == END_OF_STREAM)
    196         return(HANTRO_NOK);
    197     pVuiParameters->chromaLocInfoPresentFlag =
    198         (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
    199 
    200     if (pVuiParameters->chromaLocInfoPresentFlag)
    201     {
    202         tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
    203           &pVuiParameters->chromaSampleLocTypeTopField);
    204         if (tmp != HANTRO_OK)
    205             return(tmp);
    206         if (pVuiParameters->chromaSampleLocTypeTopField > 5)
    207             return(HANTRO_NOK);
    208 
    209         tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
    210           &pVuiParameters->chromaSampleLocTypeBottomField);
    211         if (tmp != HANTRO_OK)
    212             return(tmp);
    213         if (pVuiParameters->chromaSampleLocTypeBottomField > 5)
    214             return(HANTRO_NOK);
    215     }
    216 
    217     tmp = h264bsdGetBits(pStrmData, 1);
    218     if (tmp == END_OF_STREAM)
    219         return(HANTRO_NOK);
    220     pVuiParameters->timingInfoPresentFlag =
    221         (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
    222 
    223     if (pVuiParameters->timingInfoPresentFlag)
    224     {
    225         tmp = h264bsdShowBits32(pStrmData);
    226         if (h264bsdFlushBits(pStrmData, 32) == END_OF_STREAM)
    227             return(HANTRO_NOK);
    228         if (tmp == 0)
    229             return(HANTRO_NOK);
    230         pVuiParameters->numUnitsInTick = tmp;
    231 
    232         tmp = h264bsdShowBits32(pStrmData);
    233         if (h264bsdFlushBits(pStrmData, 32) == END_OF_STREAM)
    234             return(HANTRO_NOK);
    235         if (tmp == 0)
    236             return(HANTRO_NOK);
    237         pVuiParameters->timeScale = tmp;
    238 
    239         tmp = h264bsdGetBits(pStrmData, 1);
    240         if (tmp == END_OF_STREAM)
    241             return(HANTRO_NOK);
    242         pVuiParameters->fixedFrameRateFlag =
    243             (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
    244     }
    245 
    246     tmp = h264bsdGetBits(pStrmData, 1);
    247     if (tmp == END_OF_STREAM)
    248         return(HANTRO_NOK);
    249     pVuiParameters->nalHrdParametersPresentFlag =
    250         (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
    251 
    252     if (pVuiParameters->nalHrdParametersPresentFlag)
    253     {
    254         tmp = DecodeHrdParameters(pStrmData, &pVuiParameters->nalHrdParameters);
    255         if (tmp != HANTRO_OK)
    256             return(tmp);
    257     }
    258     else
    259     {
    260         pVuiParameters->nalHrdParameters.cpbCnt          = 1;
    261         /* MaxBR and MaxCPB should be the values correspondig to the levelIdc
    262          * in the SPS containing these VUI parameters. However, these values
    263          * are not used anywhere and maximum for any level will be used here */
    264         pVuiParameters->nalHrdParameters.bitRateValue[0] = 1200 * MAX_BR + 1;
    265         pVuiParameters->nalHrdParameters.cpbSizeValue[0] = 1200 * MAX_CPB + 1;
    266         pVuiParameters->nalHrdParameters.initialCpbRemovalDelayLength = 24;
    267         pVuiParameters->nalHrdParameters.cpbRemovalDelayLength        = 24;
    268         pVuiParameters->nalHrdParameters.dpbOutputDelayLength         = 24;
    269         pVuiParameters->nalHrdParameters.timeOffsetLength             = 24;
    270     }
    271 
    272     tmp = h264bsdGetBits(pStrmData, 1);
    273     if (tmp == END_OF_STREAM)
    274         return(HANTRO_NOK);
    275     pVuiParameters->vclHrdParametersPresentFlag =
    276         (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
    277 
    278     if (pVuiParameters->vclHrdParametersPresentFlag)
    279     {
    280         tmp = DecodeHrdParameters(pStrmData, &pVuiParameters->vclHrdParameters);
    281         if (tmp != HANTRO_OK)
    282             return(tmp);
    283     }
    284     else
    285     {
    286         pVuiParameters->vclHrdParameters.cpbCnt          = 1;
    287         /* MaxBR and MaxCPB should be the values correspondig to the levelIdc
    288          * in the SPS containing these VUI parameters. However, these values
    289          * are not used anywhere and maximum for any level will be used here */
    290         pVuiParameters->vclHrdParameters.bitRateValue[0] = 1000 * MAX_BR + 1;
    291         pVuiParameters->vclHrdParameters.cpbSizeValue[0] = 1000 * MAX_CPB + 1;
    292         pVuiParameters->vclHrdParameters.initialCpbRemovalDelayLength = 24;
    293         pVuiParameters->vclHrdParameters.cpbRemovalDelayLength        = 24;
    294         pVuiParameters->vclHrdParameters.dpbOutputDelayLength         = 24;
    295         pVuiParameters->vclHrdParameters.timeOffsetLength             = 24;
    296     }
    297 
    298     if (pVuiParameters->nalHrdParametersPresentFlag ||
    299       pVuiParameters->vclHrdParametersPresentFlag)
    300     {
    301         tmp = h264bsdGetBits(pStrmData, 1);
    302         if (tmp == END_OF_STREAM)
    303             return(HANTRO_NOK);
    304         pVuiParameters->lowDelayHrdFlag =
    305             (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
    306     }
    307 
    308     tmp = h264bsdGetBits(pStrmData, 1);
    309     if (tmp == END_OF_STREAM)
    310         return(HANTRO_NOK);
    311     pVuiParameters->picStructPresentFlag =
    312         (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
    313 
    314     tmp = h264bsdGetBits(pStrmData, 1);
    315     if (tmp == END_OF_STREAM)
    316         return(HANTRO_NOK);
    317     pVuiParameters->bitstreamRestrictionFlag =
    318         (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
    319 
    320     if (pVuiParameters->bitstreamRestrictionFlag)
    321     {
    322         tmp = h264bsdGetBits(pStrmData, 1);
    323         if (tmp == END_OF_STREAM)
    324             return(HANTRO_NOK);
    325         pVuiParameters->motionVectorsOverPicBoundariesFlag =
    326             (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
    327 
    328         tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
    329           &pVuiParameters->maxBytesPerPicDenom);
    330         if (tmp != HANTRO_OK)
    331             return(tmp);
    332         if (pVuiParameters->maxBytesPerPicDenom > 16)
    333             return(HANTRO_NOK);
    334 
    335         tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
    336           &pVuiParameters->maxBitsPerMbDenom);
    337         if (tmp != HANTRO_OK)
    338             return(tmp);
    339         if (pVuiParameters->maxBitsPerMbDenom > 16)
    340             return(HANTRO_NOK);
    341 
    342         tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
    343           &pVuiParameters->log2MaxMvLengthHorizontal);
    344         if (tmp != HANTRO_OK)
    345             return(tmp);
    346         if (pVuiParameters->log2MaxMvLengthHorizontal > 16)
    347             return(HANTRO_NOK);
    348 
    349         tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
    350           &pVuiParameters->log2MaxMvLengthVertical);
    351         if (tmp != HANTRO_OK)
    352             return(tmp);
    353         if (pVuiParameters->log2MaxMvLengthVertical > 16)
    354             return(HANTRO_NOK);
    355 
    356         tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
    357           &pVuiParameters->numReorderFrames);
    358         if (tmp != HANTRO_OK)
    359             return(tmp);
    360 
    361         tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
    362           &pVuiParameters->maxDecFrameBuffering);
    363         if (tmp != HANTRO_OK)
    364             return(tmp);
    365     }
    366     else
    367     {
    368         pVuiParameters->motionVectorsOverPicBoundariesFlag = HANTRO_TRUE;
    369         pVuiParameters->maxBytesPerPicDenom       = 2;
    370         pVuiParameters->maxBitsPerMbDenom         = 1;
    371         pVuiParameters->log2MaxMvLengthHorizontal = 16;
    372         pVuiParameters->log2MaxMvLengthVertical   = 16;
    373         pVuiParameters->numReorderFrames          = MAX_DPB_SIZE;
    374         pVuiParameters->maxDecFrameBuffering      = MAX_DPB_SIZE;
    375     }
    376 
    377     return(HANTRO_OK);
    378 
    379 }
    380 
    381 /*------------------------------------------------------------------------------
    382 
    383     Function: DecodeHrdParameters
    384 
    385         Functional description:
    386             Decode HRD parameters from the stream. See standard for details.
    387 
    388         Inputs:
    389             pStrmData       pointer to stream data structure
    390 
    391         Outputs:
    392             pHrdParameters  decoded information is stored here
    393 
    394         Returns:
    395             HANTRO_OK       success
    396             HANTRO_NOK      invalid stream data
    397 
    398 ------------------------------------------------------------------------------*/
    399 
    400 static u32 DecodeHrdParameters(
    401   strmData_t *pStrmData,
    402   hrdParameters_t *pHrdParameters)
    403 {
    404 
    405 /* Variables */
    406 
    407     u32 tmp, i;
    408 
    409 /* Code */
    410 
    411     ASSERT(pStrmData);
    412     ASSERT(pHrdParameters);
    413 
    414 
    415     tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &pHrdParameters->cpbCnt);
    416     if (tmp != HANTRO_OK)
    417         return(tmp);
    418     /* cpbCount = cpb_cnt_minus1 + 1 */
    419     pHrdParameters->cpbCnt++;
    420     if (pHrdParameters->cpbCnt > MAX_CPB_CNT)
    421         return(HANTRO_NOK);
    422 
    423     tmp = h264bsdGetBits(pStrmData, 4);
    424     if (tmp == END_OF_STREAM)
    425         return(HANTRO_NOK);
    426     pHrdParameters->bitRateScale = tmp;
    427 
    428     tmp = h264bsdGetBits(pStrmData, 4);
    429     if (tmp == END_OF_STREAM)
    430         return(HANTRO_NOK);
    431     pHrdParameters->cpbSizeScale = tmp;
    432 
    433     for (i = 0; i < pHrdParameters->cpbCnt; i++)
    434     {
    435         /* bit_rate_value_minus1 in the range [0, 2^32 - 2] */
    436         tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
    437           &pHrdParameters->bitRateValue[i]);
    438         if (tmp != HANTRO_OK)
    439             return(tmp);
    440         if (pHrdParameters->bitRateValue[i] > 4294967294U)
    441             return(HANTRO_NOK);
    442         pHrdParameters->bitRateValue[i]++;
    443         /* this may result in overflow, but this value is not used for
    444          * anything */
    445         pHrdParameters->bitRateValue[i] *=
    446             1 << (6 + pHrdParameters->bitRateScale);
    447 
    448         /* cpb_size_value_minus1 in the range [0, 2^32 - 2] */
    449         tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
    450           &pHrdParameters->cpbSizeValue[i]);
    451         if (tmp != HANTRO_OK)
    452             return(tmp);
    453         if (pHrdParameters->cpbSizeValue[i] > 4294967294U)
    454             return(HANTRO_NOK);
    455         pHrdParameters->cpbSizeValue[i]++;
    456         /* this may result in overflow, but this value is not used for
    457          * anything */
    458         pHrdParameters->cpbSizeValue[i] *=
    459             1 << (4 + pHrdParameters->cpbSizeScale);
    460 
    461         tmp = h264bsdGetBits(pStrmData, 1);
    462         if (tmp == END_OF_STREAM)
    463             return(HANTRO_NOK);
    464         pHrdParameters->cbrFlag[i] = (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
    465     }
    466 
    467     tmp = h264bsdGetBits(pStrmData, 5);
    468     if (tmp == END_OF_STREAM)
    469         return(HANTRO_NOK);
    470     pHrdParameters->initialCpbRemovalDelayLength = tmp + 1;
    471 
    472     tmp = h264bsdGetBits(pStrmData, 5);
    473     if (tmp == END_OF_STREAM)
    474         return(HANTRO_NOK);
    475     pHrdParameters->cpbRemovalDelayLength = tmp + 1;
    476 
    477     tmp = h264bsdGetBits(pStrmData, 5);
    478     if (tmp == END_OF_STREAM)
    479         return(HANTRO_NOK);
    480     pHrdParameters->dpbOutputDelayLength = tmp + 1;
    481 
    482     tmp = h264bsdGetBits(pStrmData, 5);
    483     if (tmp == END_OF_STREAM)
    484         return(HANTRO_NOK);
    485     pHrdParameters->timeOffsetLength = tmp;
    486 
    487     return(HANTRO_OK);
    488 
    489 }
    490 
    491