You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
492 lines
17 KiB
492 lines
17 KiB
/*
|
|
* Copyright (C) 2009 The Android Open Source Project
|
|
* Modified for use by h264bsd standalone library
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
/*------------------------------------------------------------------------------
|
|
|
|
Table of contents
|
|
|
|
1. Include headers
|
|
2. External compiler flags
|
|
3. Module defines
|
|
4. Local function prototypes
|
|
5. Functions
|
|
h264bsdDecodeVuiParameters
|
|
DecodeHrdParameters
|
|
|
|
------------------------------------------------------------------------------*/
|
|
|
|
/*------------------------------------------------------------------------------
|
|
1. Include headers
|
|
------------------------------------------------------------------------------*/
|
|
|
|
#include "h264bsd_vui.h"
|
|
#include "basetype.h"
|
|
#include "h264bsd_vlc.h"
|
|
#include "h264bsd_stream.h"
|
|
#include "h264bsd_cfg.h"
|
|
#include "h264bsd_util.h"
|
|
|
|
/*------------------------------------------------------------------------------
|
|
2. External compiler flags
|
|
--------------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------------
|
|
3. Module defines
|
|
------------------------------------------------------------------------------*/
|
|
|
|
#define MAX_DPB_SIZE 16
|
|
#define MAX_BR 240000 /* for level 5.1 */
|
|
#define MAX_CPB 240000 /* for level 5.1 */
|
|
|
|
/*------------------------------------------------------------------------------
|
|
4. Local function prototypes
|
|
------------------------------------------------------------------------------*/
|
|
|
|
static u32 DecodeHrdParameters(
|
|
strmData_t *pStrmData,
|
|
hrdParameters_t *pHrdParameters);
|
|
|
|
/*------------------------------------------------------------------------------
|
|
|
|
Function: h264bsdDecodeVuiParameters
|
|
|
|
Functional description:
|
|
Decode VUI parameters from the stream. See standard for details.
|
|
|
|
Inputs:
|
|
pStrmData pointer to stream data structure
|
|
|
|
Outputs:
|
|
pVuiParameters decoded information is stored here
|
|
|
|
Returns:
|
|
HANTRO_OK success
|
|
HANTRO_NOK invalid stream data or end of stream
|
|
|
|
------------------------------------------------------------------------------*/
|
|
|
|
u32 h264bsdDecodeVuiParameters(strmData_t *pStrmData,
|
|
vuiParameters_t *pVuiParameters)
|
|
{
|
|
|
|
/* Variables */
|
|
|
|
u32 tmp;
|
|
|
|
/* Code */
|
|
|
|
ASSERT(pStrmData);
|
|
ASSERT(pVuiParameters);
|
|
|
|
memset(pVuiParameters, 0, sizeof(vuiParameters_t));
|
|
|
|
tmp = h264bsdGetBits(pStrmData, 1);
|
|
if (tmp == END_OF_STREAM)
|
|
return(HANTRO_NOK);
|
|
pVuiParameters->aspectRatioPresentFlag = (tmp == 1) ?
|
|
HANTRO_TRUE : HANTRO_FALSE;
|
|
|
|
if (pVuiParameters->aspectRatioPresentFlag)
|
|
{
|
|
tmp = h264bsdGetBits(pStrmData, 8);
|
|
if (tmp == END_OF_STREAM)
|
|
return(HANTRO_NOK);
|
|
pVuiParameters->aspectRatioIdc = tmp;
|
|
|
|
if (pVuiParameters->aspectRatioIdc == ASPECT_RATIO_EXTENDED_SAR)
|
|
{
|
|
tmp = h264bsdGetBits(pStrmData, 16);
|
|
if (tmp == END_OF_STREAM)
|
|
return(HANTRO_NOK);
|
|
pVuiParameters->sarWidth = tmp;
|
|
|
|
tmp = h264bsdGetBits(pStrmData, 16);
|
|
if (tmp == END_OF_STREAM)
|
|
return(HANTRO_NOK);
|
|
pVuiParameters->sarHeight = tmp;
|
|
}
|
|
}
|
|
|
|
tmp = h264bsdGetBits(pStrmData, 1);
|
|
if (tmp == END_OF_STREAM)
|
|
return(HANTRO_NOK);
|
|
pVuiParameters->overscanInfoPresentFlag = (tmp == 1) ?
|
|
HANTRO_TRUE : HANTRO_FALSE;
|
|
|
|
if (pVuiParameters->overscanInfoPresentFlag)
|
|
{
|
|
tmp = h264bsdGetBits(pStrmData, 1);
|
|
if (tmp == END_OF_STREAM)
|
|
return(HANTRO_NOK);
|
|
pVuiParameters->overscanAppropriateFlag = (tmp == 1) ?
|
|
HANTRO_TRUE : HANTRO_FALSE;
|
|
}
|
|
|
|
tmp = h264bsdGetBits(pStrmData, 1);
|
|
if (tmp == END_OF_STREAM)
|
|
return(HANTRO_NOK);
|
|
pVuiParameters->videoSignalTypePresentFlag = (tmp == 1) ?
|
|
HANTRO_TRUE : HANTRO_FALSE;
|
|
|
|
if (pVuiParameters->videoSignalTypePresentFlag)
|
|
{
|
|
tmp = h264bsdGetBits(pStrmData, 3);
|
|
if (tmp == END_OF_STREAM)
|
|
return(HANTRO_NOK);
|
|
pVuiParameters->videoFormat = tmp;
|
|
|
|
tmp = h264bsdGetBits(pStrmData, 1);
|
|
if (tmp == END_OF_STREAM)
|
|
return(HANTRO_NOK);
|
|
pVuiParameters->videoFullRangeFlag = (tmp == 1) ?
|
|
HANTRO_TRUE : HANTRO_FALSE;
|
|
|
|
tmp = h264bsdGetBits(pStrmData, 1);
|
|
if (tmp == END_OF_STREAM)
|
|
return(HANTRO_NOK);
|
|
pVuiParameters->colourDescriptionPresentFlag =
|
|
(tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
|
|
|
|
if (pVuiParameters->colourDescriptionPresentFlag)
|
|
{
|
|
tmp = h264bsdGetBits(pStrmData, 8);
|
|
if (tmp == END_OF_STREAM)
|
|
return(HANTRO_NOK);
|
|
pVuiParameters->colourPrimaries = tmp;
|
|
|
|
tmp = h264bsdGetBits(pStrmData, 8);
|
|
if (tmp == END_OF_STREAM)
|
|
return(HANTRO_NOK);
|
|
pVuiParameters->transferCharacteristics = tmp;
|
|
|
|
tmp = h264bsdGetBits(pStrmData, 8);
|
|
if (tmp == END_OF_STREAM)
|
|
return(HANTRO_NOK);
|
|
pVuiParameters->matrixCoefficients = tmp;
|
|
}
|
|
else
|
|
{
|
|
pVuiParameters->colourPrimaries = 2;
|
|
pVuiParameters->transferCharacteristics = 2;
|
|
pVuiParameters->matrixCoefficients = 2;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pVuiParameters->videoFormat = 5;
|
|
pVuiParameters->colourPrimaries = 2;
|
|
pVuiParameters->transferCharacteristics = 2;
|
|
pVuiParameters->matrixCoefficients = 2;
|
|
}
|
|
|
|
tmp = h264bsdGetBits(pStrmData, 1);
|
|
if (tmp == END_OF_STREAM)
|
|
return(HANTRO_NOK);
|
|
pVuiParameters->chromaLocInfoPresentFlag =
|
|
(tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
|
|
|
|
if (pVuiParameters->chromaLocInfoPresentFlag)
|
|
{
|
|
tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
|
|
&pVuiParameters->chromaSampleLocTypeTopField);
|
|
if (tmp != HANTRO_OK)
|
|
return(tmp);
|
|
if (pVuiParameters->chromaSampleLocTypeTopField > 5)
|
|
return(HANTRO_NOK);
|
|
|
|
tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
|
|
&pVuiParameters->chromaSampleLocTypeBottomField);
|
|
if (tmp != HANTRO_OK)
|
|
return(tmp);
|
|
if (pVuiParameters->chromaSampleLocTypeBottomField > 5)
|
|
return(HANTRO_NOK);
|
|
}
|
|
|
|
tmp = h264bsdGetBits(pStrmData, 1);
|
|
if (tmp == END_OF_STREAM)
|
|
return(HANTRO_NOK);
|
|
pVuiParameters->timingInfoPresentFlag =
|
|
(tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
|
|
|
|
if (pVuiParameters->timingInfoPresentFlag)
|
|
{
|
|
tmp = h264bsdShowBits32(pStrmData);
|
|
if (h264bsdFlushBits(pStrmData, 32) == END_OF_STREAM)
|
|
return(HANTRO_NOK);
|
|
if (tmp == 0)
|
|
return(HANTRO_NOK);
|
|
pVuiParameters->numUnitsInTick = tmp;
|
|
|
|
tmp = h264bsdShowBits32(pStrmData);
|
|
if (h264bsdFlushBits(pStrmData, 32) == END_OF_STREAM)
|
|
return(HANTRO_NOK);
|
|
if (tmp == 0)
|
|
return(HANTRO_NOK);
|
|
pVuiParameters->timeScale = tmp;
|
|
|
|
tmp = h264bsdGetBits(pStrmData, 1);
|
|
if (tmp == END_OF_STREAM)
|
|
return(HANTRO_NOK);
|
|
pVuiParameters->fixedFrameRateFlag =
|
|
(tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
|
|
}
|
|
|
|
tmp = h264bsdGetBits(pStrmData, 1);
|
|
if (tmp == END_OF_STREAM)
|
|
return(HANTRO_NOK);
|
|
pVuiParameters->nalHrdParametersPresentFlag =
|
|
(tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
|
|
|
|
if (pVuiParameters->nalHrdParametersPresentFlag)
|
|
{
|
|
tmp = DecodeHrdParameters(pStrmData, &pVuiParameters->nalHrdParameters);
|
|
if (tmp != HANTRO_OK)
|
|
return(tmp);
|
|
}
|
|
else
|
|
{
|
|
pVuiParameters->nalHrdParameters.cpbCnt = 1;
|
|
/* MaxBR and MaxCPB should be the values correspondig to the levelIdc
|
|
* in the SPS containing these VUI parameters. However, these values
|
|
* are not used anywhere and maximum for any level will be used here */
|
|
pVuiParameters->nalHrdParameters.bitRateValue[0] = 1200 * MAX_BR + 1;
|
|
pVuiParameters->nalHrdParameters.cpbSizeValue[0] = 1200 * MAX_CPB + 1;
|
|
pVuiParameters->nalHrdParameters.initialCpbRemovalDelayLength = 24;
|
|
pVuiParameters->nalHrdParameters.cpbRemovalDelayLength = 24;
|
|
pVuiParameters->nalHrdParameters.dpbOutputDelayLength = 24;
|
|
pVuiParameters->nalHrdParameters.timeOffsetLength = 24;
|
|
}
|
|
|
|
tmp = h264bsdGetBits(pStrmData, 1);
|
|
if (tmp == END_OF_STREAM)
|
|
return(HANTRO_NOK);
|
|
pVuiParameters->vclHrdParametersPresentFlag =
|
|
(tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
|
|
|
|
if (pVuiParameters->vclHrdParametersPresentFlag)
|
|
{
|
|
tmp = DecodeHrdParameters(pStrmData, &pVuiParameters->vclHrdParameters);
|
|
if (tmp != HANTRO_OK)
|
|
return(tmp);
|
|
}
|
|
else
|
|
{
|
|
pVuiParameters->vclHrdParameters.cpbCnt = 1;
|
|
/* MaxBR and MaxCPB should be the values correspondig to the levelIdc
|
|
* in the SPS containing these VUI parameters. However, these values
|
|
* are not used anywhere and maximum for any level will be used here */
|
|
pVuiParameters->vclHrdParameters.bitRateValue[0] = 1000 * MAX_BR + 1;
|
|
pVuiParameters->vclHrdParameters.cpbSizeValue[0] = 1000 * MAX_CPB + 1;
|
|
pVuiParameters->vclHrdParameters.initialCpbRemovalDelayLength = 24;
|
|
pVuiParameters->vclHrdParameters.cpbRemovalDelayLength = 24;
|
|
pVuiParameters->vclHrdParameters.dpbOutputDelayLength = 24;
|
|
pVuiParameters->vclHrdParameters.timeOffsetLength = 24;
|
|
}
|
|
|
|
if (pVuiParameters->nalHrdParametersPresentFlag ||
|
|
pVuiParameters->vclHrdParametersPresentFlag)
|
|
{
|
|
tmp = h264bsdGetBits(pStrmData, 1);
|
|
if (tmp == END_OF_STREAM)
|
|
return(HANTRO_NOK);
|
|
pVuiParameters->lowDelayHrdFlag =
|
|
(tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
|
|
}
|
|
|
|
tmp = h264bsdGetBits(pStrmData, 1);
|
|
if (tmp == END_OF_STREAM)
|
|
return(HANTRO_NOK);
|
|
pVuiParameters->picStructPresentFlag =
|
|
(tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
|
|
|
|
tmp = h264bsdGetBits(pStrmData, 1);
|
|
if (tmp == END_OF_STREAM)
|
|
return(HANTRO_NOK);
|
|
pVuiParameters->bitstreamRestrictionFlag =
|
|
(tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
|
|
|
|
if (pVuiParameters->bitstreamRestrictionFlag)
|
|
{
|
|
tmp = h264bsdGetBits(pStrmData, 1);
|
|
if (tmp == END_OF_STREAM)
|
|
return(HANTRO_NOK);
|
|
pVuiParameters->motionVectorsOverPicBoundariesFlag =
|
|
(tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
|
|
|
|
tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
|
|
&pVuiParameters->maxBytesPerPicDenom);
|
|
if (tmp != HANTRO_OK)
|
|
return(tmp);
|
|
if (pVuiParameters->maxBytesPerPicDenom > 16)
|
|
return(HANTRO_NOK);
|
|
|
|
tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
|
|
&pVuiParameters->maxBitsPerMbDenom);
|
|
if (tmp != HANTRO_OK)
|
|
return(tmp);
|
|
if (pVuiParameters->maxBitsPerMbDenom > 16)
|
|
return(HANTRO_NOK);
|
|
|
|
tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
|
|
&pVuiParameters->log2MaxMvLengthHorizontal);
|
|
if (tmp != HANTRO_OK)
|
|
return(tmp);
|
|
if (pVuiParameters->log2MaxMvLengthHorizontal > 16)
|
|
return(HANTRO_NOK);
|
|
|
|
tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
|
|
&pVuiParameters->log2MaxMvLengthVertical);
|
|
if (tmp != HANTRO_OK)
|
|
return(tmp);
|
|
if (pVuiParameters->log2MaxMvLengthVertical > 16)
|
|
return(HANTRO_NOK);
|
|
|
|
tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
|
|
&pVuiParameters->numReorderFrames);
|
|
if (tmp != HANTRO_OK)
|
|
return(tmp);
|
|
|
|
tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
|
|
&pVuiParameters->maxDecFrameBuffering);
|
|
if (tmp != HANTRO_OK)
|
|
return(tmp);
|
|
}
|
|
else
|
|
{
|
|
pVuiParameters->motionVectorsOverPicBoundariesFlag = HANTRO_TRUE;
|
|
pVuiParameters->maxBytesPerPicDenom = 2;
|
|
pVuiParameters->maxBitsPerMbDenom = 1;
|
|
pVuiParameters->log2MaxMvLengthHorizontal = 16;
|
|
pVuiParameters->log2MaxMvLengthVertical = 16;
|
|
pVuiParameters->numReorderFrames = MAX_DPB_SIZE;
|
|
pVuiParameters->maxDecFrameBuffering = MAX_DPB_SIZE;
|
|
}
|
|
|
|
return(HANTRO_OK);
|
|
|
|
}
|
|
|
|
/*------------------------------------------------------------------------------
|
|
|
|
Function: DecodeHrdParameters
|
|
|
|
Functional description:
|
|
Decode HRD parameters from the stream. See standard for details.
|
|
|
|
Inputs:
|
|
pStrmData pointer to stream data structure
|
|
|
|
Outputs:
|
|
pHrdParameters decoded information is stored here
|
|
|
|
Returns:
|
|
HANTRO_OK success
|
|
HANTRO_NOK invalid stream data
|
|
|
|
------------------------------------------------------------------------------*/
|
|
|
|
static u32 DecodeHrdParameters(
|
|
strmData_t *pStrmData,
|
|
hrdParameters_t *pHrdParameters)
|
|
{
|
|
|
|
/* Variables */
|
|
|
|
u32 tmp, i;
|
|
|
|
/* Code */
|
|
|
|
ASSERT(pStrmData);
|
|
ASSERT(pHrdParameters);
|
|
|
|
|
|
tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &pHrdParameters->cpbCnt);
|
|
if (tmp != HANTRO_OK)
|
|
return(tmp);
|
|
/* cpbCount = cpb_cnt_minus1 + 1 */
|
|
pHrdParameters->cpbCnt++;
|
|
if (pHrdParameters->cpbCnt > MAX_CPB_CNT)
|
|
return(HANTRO_NOK);
|
|
|
|
tmp = h264bsdGetBits(pStrmData, 4);
|
|
if (tmp == END_OF_STREAM)
|
|
return(HANTRO_NOK);
|
|
pHrdParameters->bitRateScale = tmp;
|
|
|
|
tmp = h264bsdGetBits(pStrmData, 4);
|
|
if (tmp == END_OF_STREAM)
|
|
return(HANTRO_NOK);
|
|
pHrdParameters->cpbSizeScale = tmp;
|
|
|
|
for (i = 0; i < pHrdParameters->cpbCnt; i++)
|
|
{
|
|
/* bit_rate_value_minus1 in the range [0, 2^32 - 2] */
|
|
tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
|
|
&pHrdParameters->bitRateValue[i]);
|
|
if (tmp != HANTRO_OK)
|
|
return(tmp);
|
|
if (pHrdParameters->bitRateValue[i] > 4294967294U)
|
|
return(HANTRO_NOK);
|
|
pHrdParameters->bitRateValue[i]++;
|
|
/* this may result in overflow, but this value is not used for
|
|
* anything */
|
|
pHrdParameters->bitRateValue[i] *=
|
|
1 << (6 + pHrdParameters->bitRateScale);
|
|
|
|
/* cpb_size_value_minus1 in the range [0, 2^32 - 2] */
|
|
tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
|
|
&pHrdParameters->cpbSizeValue[i]);
|
|
if (tmp != HANTRO_OK)
|
|
return(tmp);
|
|
if (pHrdParameters->cpbSizeValue[i] > 4294967294U)
|
|
return(HANTRO_NOK);
|
|
pHrdParameters->cpbSizeValue[i]++;
|
|
/* this may result in overflow, but this value is not used for
|
|
* anything */
|
|
pHrdParameters->cpbSizeValue[i] *=
|
|
1 << (4 + pHrdParameters->cpbSizeScale);
|
|
|
|
tmp = h264bsdGetBits(pStrmData, 1);
|
|
if (tmp == END_OF_STREAM)
|
|
return(HANTRO_NOK);
|
|
pHrdParameters->cbrFlag[i] = (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
|
|
}
|
|
|
|
tmp = h264bsdGetBits(pStrmData, 5);
|
|
if (tmp == END_OF_STREAM)
|
|
return(HANTRO_NOK);
|
|
pHrdParameters->initialCpbRemovalDelayLength = tmp + 1;
|
|
|
|
tmp = h264bsdGetBits(pStrmData, 5);
|
|
if (tmp == END_OF_STREAM)
|
|
return(HANTRO_NOK);
|
|
pHrdParameters->cpbRemovalDelayLength = tmp + 1;
|
|
|
|
tmp = h264bsdGetBits(pStrmData, 5);
|
|
if (tmp == END_OF_STREAM)
|
|
return(HANTRO_NOK);
|
|
pHrdParameters->dpbOutputDelayLength = tmp + 1;
|
|
|
|
tmp = h264bsdGetBits(pStrmData, 5);
|
|
if (tmp == END_OF_STREAM)
|
|
return(HANTRO_NOK);
|
|
pHrdParameters->timeOffsetLength = tmp;
|
|
|
|
return(HANTRO_OK);
|
|
|
|
}
|
|
|
|
|