Beispiel #1
0
static u32 DecodeBufferingPeriod(
  strmData_t *pStrmData,
  seiBufferingPeriod_t *pBufferingPeriod,
  u32 cpbCnt,
  u32 initialCpbRemovalDelayLength,
  u32 nalHrdBpPresentFlag,
  u32 vclHrdBpPresentFlag)
{

/* Variables */

    u32 tmp, i;

/* Code */

    ASSERT(pStrmData);
    ASSERT(pBufferingPeriod);
    ASSERT(cpbCnt);
    ASSERT(initialCpbRemovalDelayLength);


    tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
      &pBufferingPeriod->seqParameterSetId);
    if (tmp != HANTRO_OK)
        return(tmp);
    if (pBufferingPeriod->seqParameterSetId > 31)
        return(HANTRO_NOK);

    if (nalHrdBpPresentFlag)
    {
        for (i = 0; i < cpbCnt; i++)
        {
            tmp = h264bsdGetBits(pStrmData, initialCpbRemovalDelayLength);
            if (tmp == END_OF_STREAM)
                return(HANTRO_NOK);
            if (tmp == 0)
                return(HANTRO_NOK);
            pBufferingPeriod->initialCpbRemovalDelay[i] = tmp;

            tmp = h264bsdGetBits(pStrmData, initialCpbRemovalDelayLength);
            if (tmp == END_OF_STREAM)
                return(HANTRO_NOK);
            pBufferingPeriod->initialCpbRemovalDelayOffset[i] = tmp;
        }
    }

    if (vclHrdBpPresentFlag)
    {
        for (i = 0; i < cpbCnt; i++)
        {
            tmp = h264bsdGetBits(pStrmData, initialCpbRemovalDelayLength);
            if (tmp == END_OF_STREAM)
                return(HANTRO_NOK);
            pBufferingPeriod->initialCpbRemovalDelay[i] = tmp;

            tmp = h264bsdGetBits(pStrmData, initialCpbRemovalDelayLength);
            if (tmp == END_OF_STREAM)
                return(HANTRO_NOK);
            pBufferingPeriod->initialCpbRemovalDelayOffset[i] = tmp;
        }
    }

    return(HANTRO_OK);

}
Beispiel #2
0
static u32 DecodePictureTiming(
  strmData_t *pStrmData,
  seiPicTiming_t *pPicTiming,
  u32 cpbRemovalDelayLength,
  u32 dpbOutputDelayLength,
  u32 timeOffsetLength,
  u32 cpbDpbDelaysPresentFlag,
  u32 picStructPresentFlag)
{

/* Variables */

    u32 tmp, i;
    i32 itmp;

/* Code */

    ASSERT(pStrmData);
    ASSERT(pPicTiming);


    if (cpbDpbDelaysPresentFlag)
    {
        tmp = h264bsdGetBits(pStrmData, cpbRemovalDelayLength);
        if (tmp == END_OF_STREAM)
            return(HANTRO_NOK);
        pPicTiming->cpbRemovalDelay = tmp;

        tmp = h264bsdGetBits(pStrmData, dpbOutputDelayLength);
        if (tmp == END_OF_STREAM)
            return(HANTRO_NOK);
        pPicTiming->dpbOutputDelay = tmp;
    }

    if (picStructPresentFlag)
    {
        tmp = h264bsdGetBits(pStrmData, 4);
        if (tmp == END_OF_STREAM)
            return(HANTRO_NOK);
        if (tmp > 8)
            return(HANTRO_NOK);
        pPicTiming->picStruct = tmp;

        for (i = 0; i < numClockTS[pPicTiming->picStruct]; i++)
        {
            tmp = h264bsdGetBits(pStrmData, 1);
            if (tmp == END_OF_STREAM)
                return(HANTRO_NOK);
            pPicTiming->clockTimeStampFlag[i] = tmp == 1 ?
                                    HANTRO_TRUE : HANTRO_FALSE;

            if (pPicTiming->clockTimeStampFlag[i])
            {
                tmp = h264bsdGetBits(pStrmData, 2);
                if (tmp == END_OF_STREAM)
                    return(HANTRO_NOK);
                pPicTiming->ctType[i] = tmp;

                tmp = h264bsdGetBits(pStrmData, 1);
                if (tmp == END_OF_STREAM)
                    return(HANTRO_NOK);
                pPicTiming->nuitFieldBasedFlag[i] = tmp == 1 ?
                                    HANTRO_TRUE : HANTRO_FALSE;

                tmp = h264bsdGetBits(pStrmData, 5);
                if (tmp == END_OF_STREAM)
                    return(HANTRO_NOK);
                if (tmp > 6)
                    return(HANTRO_NOK);
                pPicTiming->countingType[i] = tmp;

                tmp = h264bsdGetBits(pStrmData, 1);
                if (tmp == END_OF_STREAM)
                    return(HANTRO_NOK);
                pPicTiming->fullTimeStampFlag[i] = tmp == 1 ?
                                    HANTRO_TRUE : HANTRO_FALSE;

                tmp = h264bsdGetBits(pStrmData, 1);
                if (tmp == END_OF_STREAM)
                    return(HANTRO_NOK);
                pPicTiming->discontinuityFlag[i] = tmp == 1 ?
                                    HANTRO_TRUE : HANTRO_FALSE;

                tmp = h264bsdGetBits(pStrmData, 1);
                if (tmp == END_OF_STREAM)
                    return(HANTRO_NOK);
                pPicTiming->cntDroppedFlag[i] = tmp == 1 ?
                                    HANTRO_TRUE : HANTRO_FALSE;

                tmp = h264bsdGetBits(pStrmData, 8);
                if (tmp == END_OF_STREAM)
                    return(HANTRO_NOK);
                pPicTiming->nFrames[i] = tmp;

                if (pPicTiming->fullTimeStampFlag[i])
                {
                    tmp = h264bsdGetBits(pStrmData, 6);
                    if (tmp == END_OF_STREAM)
                        return(HANTRO_NOK);
                    if (tmp > 59)
                        return(HANTRO_NOK);
                    pPicTiming->secondsValue[i] = tmp;

                    tmp = h264bsdGetBits(pStrmData, 6);
                    if (tmp == END_OF_STREAM)
                        return(HANTRO_NOK);
                    if (tmp > 59)
                        return(HANTRO_NOK);
                    pPicTiming->minutesValue[i] = tmp;

                    tmp = h264bsdGetBits(pStrmData, 5);
                    if (tmp == END_OF_STREAM)
                        return(HANTRO_NOK);
                    if (tmp > 23)
                        return(HANTRO_NOK);
                    pPicTiming->hoursValue[i] = tmp;
                }
                else
                {
                    tmp = h264bsdGetBits(pStrmData, 1);
                    if (tmp == END_OF_STREAM)
                        return(HANTRO_NOK);
                    pPicTiming->secondsFlag[i] = tmp == 1 ?
                                    HANTRO_TRUE : HANTRO_FALSE;

                    if (pPicTiming->secondsFlag[i])
                    {
                        tmp = h264bsdGetBits(pStrmData, 6);
                        if (tmp == END_OF_STREAM)
                            return(HANTRO_NOK);
                        if (tmp > 59)
                            return(HANTRO_NOK);
                        pPicTiming->secondsValue[i] = tmp;

                        tmp = h264bsdGetBits(pStrmData, 1);
                        if (tmp == END_OF_STREAM)
                            return(HANTRO_NOK);
                        pPicTiming->minutesFlag[i] = tmp == 1 ?
                                    HANTRO_TRUE : HANTRO_FALSE;

                        if (pPicTiming->minutesFlag[i])
                        {
                            tmp = h264bsdGetBits(pStrmData, 6);
                            if (tmp == END_OF_STREAM)
                                return(HANTRO_NOK);
                            if (tmp > 59)
                                return(HANTRO_NOK);
                            pPicTiming->minutesValue[i] = tmp;

                            tmp = h264bsdGetBits(pStrmData, 1);
                            if (tmp == END_OF_STREAM)
                                return(HANTRO_NOK);
                            pPicTiming->hoursFlag[i] = tmp == 1 ?
                                    HANTRO_TRUE : HANTRO_FALSE;

                            if (pPicTiming->hoursFlag[i])
                            {
                                tmp = h264bsdGetBits(pStrmData, 5);
                                if (tmp == END_OF_STREAM)
                                    return(HANTRO_NOK);
                                if (tmp > 23)
                                    return(HANTRO_NOK);
                                pPicTiming->hoursValue[i] = tmp;
                            }
                        }
                    }
                }
                if (timeOffsetLength)
                {
                    tmp = h264bsdGetBits(pStrmData, timeOffsetLength);
                    if (tmp == END_OF_STREAM)
                        return(HANTRO_NOK);
                    itmp = (i32)tmp;
                    /* following "converts" timeOffsetLength-bit signed
                     * integer into i32 */
                    /*lint -save -e701 -e702 */
                    itmp <<= (32 - timeOffsetLength);
                    itmp >>= (32 - timeOffsetLength);
                    /*lint -restore */
                    pPicTiming->timeOffset[i] = itmp;
                                    }
                else
                    pPicTiming->timeOffset[i] = 0;
            }
        }
u32 DecodeMvcExtension(strmData_t *pStrmData, seqParamSet_t *pSeqParamSet)
{

/* Variables */

    u32 tmp, i, j, k;
    u32 value, tmpCount, tmpCount1, tmpCount2;
    hrdParameters_t hrdParams;

/* Code */

    ASSERT(pStrmData);
    ASSERT(pSeqParamSet);

    tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
    if (tmp != HANTRO_OK)
        return(tmp);
    pSeqParamSet->mvc.numViews = value + 1;

    if (pSeqParamSet->mvc.numViews > MAX_NUM_VIEWS)
        return(HANTRO_NOK);

    /* view_id */
    for (i = 0; i < pSeqParamSet->mvc.numViews; i++)
    {
        tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
        if (tmp != HANTRO_OK)
            return(tmp);
        if (i < MAX_NUM_VIEWS)
            pSeqParamSet->mvc.viewId[i] = value;
    }

    for (i = 1; i < pSeqParamSet->mvc.numViews; i++)
    {
        tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
        if (tmp != HANTRO_OK)
            return(tmp);
        /*pSeqParamSet->mvc.numAnchorRefsL0[i] = value;*/
        tmpCount = value;
        for (j = 0; j < tmpCount; j++)
        {
            tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
            if (tmp != HANTRO_OK)
                return(tmp);
            /*pSeqParamSet->mvc.anchorRefL0[i][j] = value;*/
        }

        tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
        if (tmp != HANTRO_OK)
            return(tmp);
        /*pSeqParamSet->mvc.numNonAnchorRefsL0[i] = value;*/
        tmpCount = value;
        for (j = 0; j < tmpCount; j++)
        {
            tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
            if (tmp != HANTRO_OK)
                return(tmp);
            /*pSeqParamSet->mvc.nonAnchorRefL0[i][j] = value;*/
        }
    }

    for (i = 1; i < pSeqParamSet->mvc.numViews; i++)
    {
        tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
        if (tmp != HANTRO_OK)
            return(tmp);
        /*pSeqParamSet->mvc.numAnchorRefsL1[i] = value;*/
        tmpCount = value;
        for (j = 0; j < tmpCount; j++)
        {
            tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
            if (tmp != HANTRO_OK)
                return(tmp);
            /*pSeqParamSet->mvc.anchorRefL1[i][j] = value;*/
        }

        tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
        if (tmp != HANTRO_OK)
            return(tmp);
        /*pSeqParamSet->mvc.numNonAnchorRefsL1[i] = value;*/
        tmpCount = value;
        for (j = 0; j < tmpCount; j++)
        {
            tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
            if (tmp != HANTRO_OK)
                return(tmp);
            /*pSeqParamSet->mvc.nonAnchorRefL1[i][j] = value;*/
        }
    }

    /* num_level_values_signalled_minus1 */
    tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
    if (tmp != HANTRO_OK)
        return(tmp);
    tmpCount = value + 1;
    for (i = 0; i < tmpCount; i++)
    {
        /* level_idc */
        tmp = h264bsdGetBits(pStrmData, 8); 
        /* num_applicable_ops_minus1 */
        tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
        if (tmp != HANTRO_OK)
            return(tmp);
        tmpCount1 = value + 1;
        for (j = 0; j < tmpCount1; j++)
        {
            /* applicable_op_temporal_id  */
            tmp = h264bsdGetBits(pStrmData, 3); 
            /* applicable_op_num_target_views_minus1 */
            tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
            if (tmp != HANTRO_OK)
                return(tmp);
            tmpCount2 = value + 1;
            for (k = 0; k < tmpCount2; k++)
            {
                /* applicable_op_target_view_id */
                tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
            }
            /* applicable_op_num_views_minus1 */
            tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
            if (tmp != HANTRO_OK)
                return(tmp);
        }
    }

    /* mvc_vui_parameters_present_flag */
    tmp = h264bsdGetBits(pStrmData, 1);
    if (tmp == 1)
    {
        /* vui_mvc_num_ops_minus1 */
        tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
        if (tmp != HANTRO_OK)
            return(tmp);
        tmpCount = value + 1;
        for (i = 0; i < tmpCount; i++)
        {
            /* vui_mvc_temporal_id  */
            tmp = h264bsdGetBits(pStrmData, 3); 
            /* vui_mvc_num_target_output_views_minus1 */
            tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
            if (tmp != HANTRO_OK)
                return(tmp);
            tmpCount1 = value + 1;
            for (k = 0; k < tmpCount1; k++)
            {
                /* vui_mvc_view_id */
                tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
            }
            /* vui_mvc_timing_info_present_flag  */
            tmp = h264bsdGetBits(pStrmData, 1); 
            if (tmp == 1)
            {
                /* vui_mvc_num_units_in_tick  */
                tmp = h264bsdShowBits(pStrmData,32);
                if (h264bsdFlushBits(pStrmData, 32) == END_OF_STREAM)
                    return(END_OF_STREAM);
                /* vui_mvc_time_scale  */
                tmp = h264bsdShowBits(pStrmData,32);
                if (h264bsdFlushBits(pStrmData, 32) == END_OF_STREAM)
                    return(END_OF_STREAM);
                /* vui_mvc_fixed_frame_rate_flag */
                tmp = h264bsdGetBits(pStrmData, 1); 
            }

            j = 0;
            /* vui_mvc_nal_hrd_parameters_present_flag */
            tmp = h264bsdGetBits(pStrmData, 1); 
            if (tmp == 1)
            {
                j = 1;
                tmp = h264bsdDecodeHrdParameters(pStrmData, &hrdParams);
            }

            /* vui_mvc_vcl_hrd_parameters_present_flag */
            tmp = h264bsdGetBits(pStrmData, 1); 
            if (tmp == 1)
            {
                j = 1;
                tmp = h264bsdDecodeHrdParameters(pStrmData, &hrdParams);
            }

            if (j)
            {
                /* vui_mvc_low_delay_hrd_flag */
                tmp = h264bsdGetBits(pStrmData, 1); 
            }
            /* vui_mvc_pic_struct_present_flag */
            tmp = h264bsdGetBits(pStrmData, 1); 
        }

    }

    return(HANTRO_OK);

}
Beispiel #4
0
u32 h264bsdDecodeSeiMessage(
  strmData_t *pStrmData,
  seqParamSet_t *pSeqParamSet,
  seiMessage_t *pSeiMessage,
  u32 numSliceGroups)
{

/* Variables */

    u32 tmp, payloadType, payloadSize, status;

/* Code */

    ASSERT(pStrmData);
    ASSERT(pSeiMessage);


    H264SwDecMemset(pSeiMessage, 0, sizeof(seiMessage_t));

    do
    {
        payloadType = 0;
        while((tmp = h264bsdGetBits(pStrmData, 8)) == 0xFF)
        {
            payloadType += 255;
                    }
        if (tmp == END_OF_STREAM)
            return(HANTRO_NOK);
        payloadType += tmp;

        payloadSize = 0;
        while((tmp = h264bsdGetBits(pStrmData, 8)) == 0xFF)
        {
            payloadSize += 255;
        }
        if (tmp == END_OF_STREAM)
            return(HANTRO_NOK);
        payloadSize += tmp;

        pSeiMessage->payloadType = payloadType;

        switch (payloadType)
        {
            case 0:
                ASSERT(pSeqParamSet);
                status = DecodeBufferingPeriod(
                  pStrmData,
                  &pSeiMessage->bufferingPeriod,
                  pSeqParamSet->vuiParameters->vclHrdParameters.cpbCnt,
                  pSeqParamSet->vuiParameters->vclHrdParameters.
                  initialCpbRemovalDelayLength,
                  pSeqParamSet->vuiParameters->nalHrdParametersPresentFlag,
                  pSeqParamSet->vuiParameters->vclHrdParametersPresentFlag);
                break;

            case 1:
                ASSERT(pSeqParamSet->vuiParametersPresentFlag);
                status = DecodePictureTiming(
                  pStrmData,
                  &pSeiMessage->picTiming,
                  pSeqParamSet->vuiParameters->vclHrdParameters.
                      cpbRemovalDelayLength,
                  pSeqParamSet->vuiParameters->vclHrdParameters.
                      dpbOutputDelayLength,
                  pSeqParamSet->vuiParameters->vclHrdParameters.
                    timeOffsetLength,
                  pSeqParamSet->vuiParameters->nalHrdParametersPresentFlag ||
                  pSeqParamSet->vuiParameters->vclHrdParametersPresentFlag ?
                  HANTRO_TRUE : HANTRO_FALSE,
                  pSeqParamSet->vuiParameters->picStructPresentFlag);
                break;

            case 2:
                status = DecodePanScanRectangle(
                  pStrmData,
                  &pSeiMessage->panScanRect);
                break;

            case 3:
                status = DecodeFillerPayload(pStrmData, payloadSize);
                break;

            case 4:
                status = DecodeUserDataRegisteredITuTT35(
                  pStrmData,
                  &pSeiMessage->userDataRegisteredItuTT35,
                  payloadSize);
                break;

            case 5:
                status = DecodeUserDataUnregistered(
                  pStrmData,
                  &pSeiMessage->userDataUnregistered,
                  payloadSize);
                break;

            case 6:
                status = DecodeRecoveryPoint(
                  pStrmData,
                  &pSeiMessage->recoveryPoint);
                break;

            case 7:
                status = DecodeDecRefPicMarkingRepetition(
                  pStrmData,
                  &pSeiMessage->decRefPicMarkingRepetition,
                  pSeqParamSet->numRefFrames);
                break;

            case 8:
                ASSERT(pSeqParamSet);
                status = DecodeSparePic(
                  pStrmData,
                  &pSeiMessage->sparePic,
                  pSeqParamSet->picWidthInMbs * pSeqParamSet->picHeightInMbs);
                break;

            case 9:
                status = DecodeSceneInfo(
                  pStrmData,
                  &pSeiMessage->sceneInfo);
                break;

            case 10:
                status = DecodeSubSeqInfo(
                  pStrmData,
                  &pSeiMessage->subSeqInfo);
                break;

            case 11:
                status = DecodeSubSeqLayerCharacteristics(
                  pStrmData,
                  &pSeiMessage->subSeqLayerCharacteristics);
                break;

            case 12:
                status = DecodeSubSeqCharacteristics(
                  pStrmData,
                  &pSeiMessage->subSeqCharacteristics);
                break;

            case 13:
                status = DecodeFullFrameFreeze(
                  pStrmData,
                  &pSeiMessage->fullFrameFreeze);
                break;

            case 14: /* This SEI does not contain data, what to do ??? */
                status = HANTRO_OK;
                break;

            case 15:
                status = DecodeFullFrameSnapshot(
                  pStrmData,
                  &pSeiMessage->fullFrameSnapshot);
                break;

            case 16:
                status = DecodeProgressiveRefinementSegmentStart(
                  pStrmData,
                  &pSeiMessage->progressiveRefinementSegmentStart);
                break;

            case 17:
                status = DecodeProgressiveRefinementSegmentEnd(
                  pStrmData,
                  &pSeiMessage->progressiveRefinementSegmentEnd);
                break;

            case 18:
                ASSERT(numSliceGroups);
                status = DecodeMotionConstrainedSliceGroupSet(
                  pStrmData,
                  &pSeiMessage->motionConstrainedSliceGroupSet,
                  numSliceGroups);
                break;

            default:
                status = DecodeReservedSeiMessage(
                  pStrmData,
                  &pSeiMessage->reservedSeiMessage,
                  payloadSize);
                break;
        }

        if (status != HANTRO_OK)
            return(status);

        while (!h264bsdIsByteAligned(pStrmData))
        {
            if (h264bsdGetBits(pStrmData, 1) != 1)
                return(HANTRO_NOK);
            while (!h264bsdIsByteAligned(pStrmData))
            {
                if (h264bsdGetBits(pStrmData, 1) != 0)
                    return(HANTRO_NOK);
            }
        }
    } while (h264bsdMoreRbspData(pStrmData));

    return(h264bsdRbspTrailingBits(pStrmData));

}
u32 h264bsdDecodeSliceHeader(strmData_t *pStrmData, sliceHeader_t *pSliceHeader,
    seqParamSet_t *pSeqParamSet, picParamSet_t *pPicParamSet,
    nalUnit_t *pNalUnit)
{

/* Variables */

    u32 tmp, i, value;
    i32 itmp;
    u32 picSizeInMbs;

/* Code */

    ASSERT(pStrmData);
    ASSERT(pSliceHeader);
    ASSERT(pSeqParamSet);
    ASSERT(pPicParamSet);
    ASSERT( pNalUnit->nalUnitType == NAL_CODED_SLICE ||
            pNalUnit->nalUnitType == NAL_CODED_SLICE_IDR );


    H264SwDecMemset(pSliceHeader, 0, sizeof(sliceHeader_t));

    picSizeInMbs = pSeqParamSet->picWidthInMbs * pSeqParamSet->picHeightInMbs;
    tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
    if (tmp != HANTRO_OK)
        return(tmp);
    pSliceHeader->firstMbInSlice = value;
    if (value >= picSizeInMbs)
    {
        EPRINT("first_mb_in_slice");
        return(HANTRO_NOK);
    }

    tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
    if (tmp != HANTRO_OK)
        return(tmp);
    pSliceHeader->sliceType = value;
    /* slice type has to be either I or P slice. P slice is not allowed when
     * current NAL unit is an IDR NAL unit or num_ref_frames is 0 */
    if ( !IS_I_SLICE(pSliceHeader->sliceType) &&
         ( !IS_P_SLICE(pSliceHeader->sliceType) ||
           IS_IDR_NAL_UNIT(pNalUnit) ||
           !pSeqParamSet->numRefFrames ) )
    {
        EPRINT("slice_type");
        return(HANTRO_NOK);
    }

    tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
    if (tmp != HANTRO_OK)
        return(tmp);
    pSliceHeader->picParameterSetId = value;
    if (pSliceHeader->picParameterSetId != pPicParamSet->picParameterSetId)
    {
        EPRINT("pic_parameter_set_id");
        return(HANTRO_NOK);
    }

    /* log2(maxFrameNum) -> num bits to represent frame_num */
    i = 0;
    while (pSeqParamSet->maxFrameNum >> i)
        i++;
    i--;

    tmp = h264bsdGetBits(pStrmData, i);
    if (tmp == END_OF_STREAM)
        return(HANTRO_NOK);
    if (IS_IDR_NAL_UNIT(pNalUnit) && tmp != 0)
    {
        EPRINT("frame_num");
        return(HANTRO_NOK);
    }
    pSliceHeader->frameNum = tmp;

    if (IS_IDR_NAL_UNIT(pNalUnit))
    {
        tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
        if (tmp != HANTRO_OK)
            return(tmp);
        pSliceHeader->idrPicId = value;
        if (value > 65535)
        {
            EPRINT("idr_pic_id");
            return(HANTRO_NOK);
        }
    }

    if (pSeqParamSet->picOrderCntType == 0)
    {
        /* log2(maxPicOrderCntLsb) -> num bits to represent pic_order_cnt_lsb */
        i = 0;
        while (pSeqParamSet->maxPicOrderCntLsb >> i)
            i++;
        i--;

        tmp = h264bsdGetBits(pStrmData, i);
        if (tmp == END_OF_STREAM)
            return(HANTRO_NOK);
        pSliceHeader->picOrderCntLsb = tmp;

        if (pPicParamSet->picOrderPresentFlag)
        {
            tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp);
            if (tmp != HANTRO_OK)
                return(tmp);
            pSliceHeader->deltaPicOrderCntBottom = itmp;
        }

        /* check that picOrderCnt for IDR picture will be zero. See
         * DecodePicOrderCnt function to understand the logic here */
        if ( IS_IDR_NAL_UNIT(pNalUnit) &&
             ( (pSliceHeader->picOrderCntLsb >
                pSeqParamSet->maxPicOrderCntLsb/2) ||
                MIN((i32)pSliceHeader->picOrderCntLsb,
                    (i32)pSliceHeader->picOrderCntLsb +
                    pSliceHeader->deltaPicOrderCntBottom) != 0 ) )
        {
            return(HANTRO_NOK);
        }
    }
u32 h264bsdDecodeSeqParamSet(strmData_t *pStrmData, seqParamSet_t *pSeqParamSet,
    u32 mvcFlag)
{

/* Variables */

    u32 tmp, i, value;

/* Code */

    ASSERT(pStrmData);
    ASSERT(pSeqParamSet);

    (void)DWLmemset(pSeqParamSet, 0, sizeof(seqParamSet_t));

    /* profile_idc */
    tmp = h264bsdGetBits(pStrmData, 8);
    if (tmp == END_OF_STREAM)
        return(HANTRO_NOK);
    if (tmp != 66)
    {
        DEBUG_PRINT(("NOT BASELINE PROFILE %d\n", tmp));
    }
    #ifdef ASIC_TRACE_SUPPORT 
    if (tmp==66)
        trace_h264DecodingTools.profileType.baseline = 1;
    if (tmp==77)
       	trace_h264DecodingTools.profileType.main = 1;
    if (tmp == 100)
	    trace_h264DecodingTools.profileType.high = 1;
    #endif 
    pSeqParamSet->profileIdc = tmp;

    /* constrained_set0_flag */
    tmp = h264bsdGetBits(pStrmData, 1);
    pSeqParamSet->constrained_set0_flag = tmp;
    /* constrained_set1_flag */
    tmp = h264bsdGetBits(pStrmData, 1);
    pSeqParamSet->constrained_set1_flag = tmp;
    /* constrained_set2_flag */
    tmp = h264bsdGetBits(pStrmData, 1);
    pSeqParamSet->constrained_set2_flag = tmp;
    /* constrained_set3_flag */
    tmp = h264bsdGetBits(pStrmData, 1);
    pSeqParamSet->constrained_set3_flag = tmp;
    if (tmp == END_OF_STREAM)
        return(HANTRO_NOK);

    /* reserved_zero_4bits, values of these bits shall be ignored */
    tmp = h264bsdGetBits(pStrmData, 4);
    if (tmp == END_OF_STREAM)
    {
        ERROR_PRINT("reserved_zero_4bits");
        return(HANTRO_NOK);
    }

    tmp = h264bsdGetBits(pStrmData, 8);
    if (tmp == END_OF_STREAM)
    {
        ERROR_PRINT("level_idc");
        return(HANTRO_NOK);
    }
    pSeqParamSet->levelIdc = tmp;

    tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
        &pSeqParamSet->seqParameterSetId);
    if (tmp != HANTRO_OK)
        return(tmp);
    if (pSeqParamSet->seqParameterSetId >= MAX_NUM_SEQ_PARAM_SETS)
    {
        ERROR_PRINT("seq_param_set_id");
        return(HANTRO_NOK);
    }

    if( pSeqParamSet->profileIdc >= 100 )
    {
        /* chroma_format_idc */
        tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
            &value);
        if (tmp != HANTRO_OK)
            return(tmp);
        if( tmp > 1 )
            return(HANTRO_NOK);
        pSeqParamSet->chromaFormatIdc = value;
        if (pSeqParamSet->chromaFormatIdc == 0)
            pSeqParamSet->monoChrome = 1;
        /* residual_colour_transform_flag (skipped) */

        /* bit_depth_luma_minus8 */
        tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
            &value);
        if (tmp != HANTRO_OK)
            return(tmp);

        /* bit_depth_chroma_minus8 */
        tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
            &value);
        if (tmp != HANTRO_OK)
            return(tmp);

        /* qpprime_y_zero_transform_bypass_flag */
        tmp = h264bsdGetBits(pStrmData, 1);
        if (tmp == END_OF_STREAM)
            return(HANTRO_NOK);

        /* seq_scaling_matrix_present_flag */
        tmp = h264bsdGetBits(pStrmData, 1);
	#ifdef ASIC_TRACE_SUPPORT 
        if (tmp)
        trace_h264DecodingTools.scalingMatrixPresentType.seq = 1;
        #endif 
        if (tmp == END_OF_STREAM)
            return(HANTRO_NOK);
        pSeqParamSet->scalingMatrixPresentFlag = tmp;
        if (tmp)
        {
            for (i = 0; i < 8; i++)
            {
                tmp = h264bsdGetBits(pStrmData, 1);
                pSeqParamSet->scalingListPresent[i] = tmp;
                if (tmp)
                {
                    ScalingList(pSeqParamSet->scalingList, pStrmData, i);
                }
                else
                    FallbackScaling(pSeqParamSet->scalingList, i);
            }
        }

    }
    else
    {
        pSeqParamSet->chromaFormatIdc = 1; /* 4:2:0 */
        pSeqParamSet->scalingMatrixPresentFlag = 0;
    }

    /* log2_max_frame_num_minus4 */
    tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
    if (tmp != HANTRO_OK)
    {
        ERROR_PRINT("log2_max_frame_num_minus4");
        return(tmp);
    }
    if (value > 12)
    {
        ERROR_PRINT("log2_max_frame_num_minus4");
        return(HANTRO_NOK);
    }
    /* maxFrameNum = 2^(log2_max_frame_num_minus4 + 4) */
    pSeqParamSet->maxFrameNum = 1 << (value+4);

    /* valid POC types are 0, 1 and 2 */
    tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
    if (tmp != HANTRO_OK)
    {
        ERROR_PRINT("pic_order_cnt_type");
        return(tmp);
    }
    if (value > 2)
    {
        ERROR_PRINT("pic_order_cnt_type");
        return(HANTRO_NOK);
    }
    pSeqParamSet->picOrderCntType = value;

    if (pSeqParamSet->picOrderCntType == 0)
    {
        /* log2_max_pic_order_cnt_lsb_minus4 */
        tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
        if (tmp != HANTRO_OK)
            return(tmp);
        if (value > 12)
        {
            ERROR_PRINT("log2_max_pic_order_cnt_lsb_minus4");
            return(HANTRO_NOK);
        }
        /* maxPicOrderCntLsb = 2^(log2_max_pic_order_cnt_lsb_minus4 + 4) */
        pSeqParamSet->maxPicOrderCntLsb = 1 << (value+4);
    }
    else if (pSeqParamSet->picOrderCntType == 1)
    {
        tmp = h264bsdGetBits(pStrmData, 1);
        if (tmp == END_OF_STREAM)
            return(HANTRO_NOK);
        pSeqParamSet->deltaPicOrderAlwaysZeroFlag = (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;

        tmp = h264bsdDecodeExpGolombSigned(pStrmData,
            &pSeqParamSet->offsetForNonRefPic);
        if (tmp != HANTRO_OK)
            return(tmp);

        tmp = h264bsdDecodeExpGolombSigned(pStrmData,
            &pSeqParamSet->offsetForTopToBottomField);
        if (tmp != HANTRO_OK)
            return(tmp);

        tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
            &pSeqParamSet->numRefFramesInPicOrderCntCycle);
        if (tmp != HANTRO_OK)
            return(tmp);
        if (pSeqParamSet->numRefFramesInPicOrderCntCycle > 255)
        {
            ERROR_PRINT("num_ref_frames_in_pic_order_cnt_cycle");
            return(HANTRO_NOK);
        }

        if (pSeqParamSet->numRefFramesInPicOrderCntCycle)
        {
            /* NOTE: This has to be freed somewhere! */
            ALLOCATE(pSeqParamSet->offsetForRefFrame,
                     pSeqParamSet->numRefFramesInPicOrderCntCycle, i32);
            if (pSeqParamSet->offsetForRefFrame == NULL)
                return(MEMORY_ALLOCATION_ERROR);

            for (i = 0; i < pSeqParamSet->numRefFramesInPicOrderCntCycle; i++)
            {
                tmp =  h264bsdDecodeExpGolombSigned(pStrmData,
                    pSeqParamSet->offsetForRefFrame + i);
                if (tmp != HANTRO_OK)
                    return(tmp);
            }
        }
        else
        {
            pSeqParamSet->offsetForRefFrame = NULL;
        }
    }

    tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
        &pSeqParamSet->numRefFrames);
    if (tmp != HANTRO_OK)
        return(tmp);
    if (pSeqParamSet->numRefFrames > MAX_NUM_REF_PICS ||
        /* max num ref frames in mvc stereo high profile is actually 8, but
         * here we just check that it is less than 15 (base 15 used for 
         * inter view reference picture) */
        (mvcFlag && (pSeqParamSet->numRefFrames > 15)))
    {
        ERROR_PRINT("num_ref_frames");
        return(HANTRO_NOK);
    }

    tmp = h264bsdGetBits(pStrmData, 1);
    if (tmp == END_OF_STREAM)
        return(HANTRO_NOK);
    pSeqParamSet->gapsInFrameNumValueAllowedFlag = (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;

    tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
    if (tmp != HANTRO_OK)
        return(tmp);
    pSeqParamSet->picWidthInMbs = value + 1;

    tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
    if (tmp != HANTRO_OK)
        return(tmp);
    pSeqParamSet->picHeightInMbs = value + 1;

    /* frame_mbs_only_flag, shall be 1 for baseline profile */
    tmp = h264bsdGetBits(pStrmData, 1);
    if (tmp == END_OF_STREAM)
        return(HANTRO_NOK);
    pSeqParamSet->frameMbsOnlyFlag = tmp;

    if (!pSeqParamSet->frameMbsOnlyFlag)
    {
        pSeqParamSet->mbAdaptiveFrameFieldFlag =
            h264bsdGetBits(pStrmData, 1);
        pSeqParamSet->picHeightInMbs *= 2;
    }

    /* direct_8x8_inference_flag */
    tmp = h264bsdGetBits(pStrmData, 1);
    if (tmp == END_OF_STREAM)
        return(HANTRO_NOK);
    pSeqParamSet->direct8x8InferenceFlag = tmp;

    tmp = h264bsdGetBits(pStrmData, 1);
    if (tmp == END_OF_STREAM)
        return(HANTRO_NOK);
    pSeqParamSet->frameCroppingFlag = (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
    
#ifdef ASIC_TRACE_SUPPORT
    if (tmp)
        trace_h264DecodingTools.imageCropping = 1;
#endif

    if (pSeqParamSet->frameCroppingFlag)
    {
        tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
            &pSeqParamSet->frameCropLeftOffset);
        if (tmp != HANTRO_OK)
            return(tmp);
        tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
            &pSeqParamSet->frameCropRightOffset);
        if (tmp != HANTRO_OK)
            return(tmp);
        tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
            &pSeqParamSet->frameCropTopOffset);
        if (tmp != HANTRO_OK)
            return(tmp);
        tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
            &pSeqParamSet->frameCropBottomOffset);
        if (tmp != HANTRO_OK)
            return(tmp);

        /* check that frame cropping params are valid, parameters shall
         * specify non-negative area within the original picture */
        if ( ( (i32)pSeqParamSet->frameCropLeftOffset >
               ( 8 * (i32)pSeqParamSet->picWidthInMbs -
                 ((i32)pSeqParamSet->frameCropRightOffset + 1) ) ) ||
             ( (i32)pSeqParamSet->frameCropTopOffset >
               ( 8 * (i32)pSeqParamSet->picHeightInMbs -
                 ((i32)pSeqParamSet->frameCropBottomOffset + 1) ) ) )
        {
            ERROR_PRINT("frame_cropping");
            return(HANTRO_NOK);
        }
    }

    /* check that image dimensions and levelIdc match */
    tmp = pSeqParamSet->picWidthInMbs * pSeqParamSet->picHeightInMbs;
    value = GetDpbSize(tmp, pSeqParamSet->levelIdc);
    if (value == INVALID_DPB_SIZE || pSeqParamSet->numRefFrames > value)
    {
        DEBUG_PRINT(("WARNING! Invalid DPB size based on SPS Level!\n"));
        DEBUG_PRINT(("WARNING! Using num_ref_frames =%d for DPB size!\n",
                        pSeqParamSet->numRefFrames));
        /* set maxDpbSize to 1 if numRefFrames is zero */
        value = pSeqParamSet->numRefFrames ? pSeqParamSet->numRefFrames : 1;
    }
    pSeqParamSet->maxDpbSize = value;

    tmp = h264bsdGetBits(pStrmData, 1);
    if (tmp == END_OF_STREAM)
        return(HANTRO_NOK);
    pSeqParamSet->vuiParametersPresentFlag = (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;

    /* VUI */
    if (pSeqParamSet->vuiParametersPresentFlag)
    {
        ALLOCATE(pSeqParamSet->vuiParameters, 1, vuiParameters_t);
        if (pSeqParamSet->vuiParameters == NULL)
            return(MEMORY_ALLOCATION_ERROR);
        tmp = h264bsdDecodeVuiParameters(pStrmData,
            pSeqParamSet->vuiParameters);
        if (tmp == END_OF_STREAM)
        {
            pSeqParamSet->vuiParameters->bitstreamRestrictionFlag |= 1;
            pSeqParamSet->vuiParameters->maxDecFrameBuffering =
                pSeqParamSet->maxDpbSize;
        }
        else if (tmp != HANTRO_OK)
            return(tmp);
        /* check numReorderFrames and maxDecFrameBuffering */
        if (pSeqParamSet->vuiParameters->bitstreamRestrictionFlag)
        {
            if (pSeqParamSet->vuiParameters->numReorderFrames >
                    pSeqParamSet->vuiParameters->maxDecFrameBuffering ||
                pSeqParamSet->vuiParameters->maxDecFrameBuffering <
                    pSeqParamSet->numRefFrames ||
                pSeqParamSet->vuiParameters->maxDecFrameBuffering >
                    pSeqParamSet->maxDpbSize)
            {
                ERROR_PRINT("Not valid vuiParameters->bitstreamRestriction");
                return(HANTRO_NOK);
            }

            /* standard says that "the sequence shall not require a DPB with
             * size of more than max(1, maxDecFrameBuffering) */
            pSeqParamSet->maxDpbSize =
                MAX(1, pSeqParamSet->vuiParameters->maxDecFrameBuffering);
        }
    }

    if (mvcFlag)
    {
        if (pSeqParamSet->profileIdc == 118 || pSeqParamSet->profileIdc == 128)
        {
            /* bit_equal_to_one */
            tmp = h264bsdGetBits(pStrmData, 1);
            tmp = DecodeMvcExtension(pStrmData, pSeqParamSet);
            if (tmp != HANTRO_OK)
                return tmp;
        }

        /* additional_extension2_flag, shall be zero */
        tmp = h264bsdGetBits(pStrmData, 1);
        /* TODO: skip rest of the stuff if equal to 1 */
    }

    tmp = h264bsdRbspTrailingBits(pStrmData);

    /* ignore possible errors in trailing bits of parameters sets */
    return(HANTRO_OK);

}
u32 h264bsdDecodePicParamSet(strmData_t *pStrmData, picParamSet_t *pPicParamSet)
{

/* Variables */

    u32 tmp, i, value;
    i32 itmp;

/* Code */

    ASSERT(pStrmData);
    ASSERT(pPicParamSet);


    H264SwDecMemset(pPicParamSet, 0, sizeof(picParamSet_t));

    tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
        &pPicParamSet->picParameterSetId);
    if (tmp != HANTRO_OK)
        return(tmp);
    if (pPicParamSet->picParameterSetId >= MAX_NUM_PIC_PARAM_SETS)
    {
        EPRINT("pic_parameter_set_id");
        return(HANTRO_NOK);
    }

    tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
        &pPicParamSet->seqParameterSetId);
    if (tmp != HANTRO_OK)
        return(tmp);
    if (pPicParamSet->seqParameterSetId >= MAX_NUM_SEQ_PARAM_SETS)
    {
        EPRINT("seq_param_set_id");
        return(HANTRO_NOK);
    }

    /* entropy_coding_mode_flag, shall be 0 for baseline profile */
    tmp = h264bsdGetBits(pStrmData, 1);
    if (tmp)
    {
        EPRINT("entropy_coding_mode_flag");
        return(HANTRO_NOK);
    }

    tmp = h264bsdGetBits(pStrmData, 1);
    if (tmp == END_OF_STREAM)
        return(HANTRO_NOK);
    pPicParamSet->picOrderPresentFlag = (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;

    /* num_slice_groups_minus1 */
    tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
    if (tmp != HANTRO_OK)
        return(tmp);
    pPicParamSet->numSliceGroups = value + 1;
    if (pPicParamSet->numSliceGroups > MAX_NUM_SLICE_GROUPS)
    {
        EPRINT("num_slice_groups_minus1");
        return(HANTRO_NOK);
    }

    /* decode slice group mapping information if more than one slice groups */
    if (pPicParamSet->numSliceGroups > 1)
    {
        tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
            &pPicParamSet->sliceGroupMapType);
        if (tmp != HANTRO_OK)
            return(tmp);
        if (pPicParamSet->sliceGroupMapType > 6)
        {
            EPRINT("slice_group_map_type");
            return(HANTRO_NOK);
        }

        if (pPicParamSet->sliceGroupMapType == 0)
        {
            ALLOCATE(pPicParamSet->runLength,
                pPicParamSet->numSliceGroups, u32);
            if (pPicParamSet->runLength == NULL)
                return(MEMORY_ALLOCATION_ERROR);
            for (i = 0; i < pPicParamSet->numSliceGroups; i++)
            {
                tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
                if (tmp != HANTRO_OK)
                    return(tmp);
                pPicParamSet->runLength[i] = value+1;
                /* param values checked in CheckPps() */
            }
        }
        else if (pPicParamSet->sliceGroupMapType == 2)
        {
            ALLOCATE(pPicParamSet->topLeft,
                pPicParamSet->numSliceGroups - 1, u32);
            ALLOCATE(pPicParamSet->bottomRight,
                pPicParamSet->numSliceGroups - 1, u32);
            if (pPicParamSet->topLeft == NULL ||
                pPicParamSet->bottomRight == NULL)
                return(MEMORY_ALLOCATION_ERROR);
            for (i = 0; i < pPicParamSet->numSliceGroups - 1; i++)
            {
                tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
                if (tmp != HANTRO_OK)
                    return(tmp);
                pPicParamSet->topLeft[i] = value;
                tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
                if (tmp != HANTRO_OK)
                    return(tmp);
                pPicParamSet->bottomRight[i] = value;
                /* param values checked in CheckPps() */
            }
        }
        else if ( (pPicParamSet->sliceGroupMapType == 3) ||
                  (pPicParamSet->sliceGroupMapType == 4) ||
                  (pPicParamSet->sliceGroupMapType == 5) )
        {
            tmp = h264bsdGetBits(pStrmData, 1);
            if (tmp == END_OF_STREAM)
                return(HANTRO_NOK);
            pPicParamSet->sliceGroupChangeDirectionFlag =
                (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
            tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
            if (tmp != HANTRO_OK)
                return(tmp);
            pPicParamSet->sliceGroupChangeRate = value + 1;
            /* param value checked in CheckPps() */
        }
        else if (pPicParamSet->sliceGroupMapType == 6)
        {
            tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
            if (tmp != HANTRO_OK)
                return(tmp);
            pPicParamSet->picSizeInMapUnits = value + 1;

            ALLOCATE(pPicParamSet->sliceGroupId,
                pPicParamSet->picSizeInMapUnits, u32);
            if (pPicParamSet->sliceGroupId == NULL)
                return(MEMORY_ALLOCATION_ERROR);

            /* determine number of bits needed to represent range
             * [0, numSliceGroups) */
            tmp = CeilLog2NumSliceGroups[pPicParamSet->numSliceGroups-1];

            for (i = 0; i < pPicParamSet->picSizeInMapUnits; i++)
            {
                pPicParamSet->sliceGroupId[i] = h264bsdGetBits(pStrmData, tmp);
                if ( pPicParamSet->sliceGroupId[i] >=
                     pPicParamSet->numSliceGroups )
                {
                    EPRINT("slice_group_id");
                    return(HANTRO_NOK);
                }
            }
        }
    }

    /* num_ref_idx_l0_active_minus1 */
    tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
    if (tmp != HANTRO_OK)
        return(tmp);
    if (value > 31)
    {
        EPRINT("num_ref_idx_l0_active_minus1");
        return(HANTRO_NOK);
    }
    pPicParamSet->numRefIdxL0Active = value + 1;

    /* num_ref_idx_l1_active_minus1 */
    tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
    if (tmp != HANTRO_OK)
        return(tmp);
    if (value > 31)
    {
        EPRINT("num_ref_idx_l1_active_minus1");
        return(HANTRO_NOK);
    }

    /* weighted_pred_flag, this shall be 0 for baseline profile */
    tmp = h264bsdGetBits(pStrmData, 1);
    if (tmp)
    {
        EPRINT("weighted_pred_flag");
        return(HANTRO_NOK);
    }

    /* weighted_bipred_idc */
    tmp = h264bsdGetBits(pStrmData, 2);
    if (tmp > 2)
    {
        EPRINT("weighted_bipred_idc");
        return(HANTRO_NOK);
    }

    /* pic_init_qp_minus26 */
    tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp);
    if (tmp != HANTRO_OK)
        return(tmp);
    if ((itmp < -26) || (itmp > 25))
    {
        EPRINT("pic_init_qp_minus26");
        return(HANTRO_NOK);
    }
    pPicParamSet->picInitQp = (u32)(itmp + 26);

    /* pic_init_qs_minus26 */
    tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp);
    if (tmp != HANTRO_OK)
        return(tmp);
    if ((itmp < -26) || (itmp > 25))
    {
        EPRINT("pic_init_qs_minus26");
        return(HANTRO_NOK);
    }

    tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp);
    if (tmp != HANTRO_OK)
        return(tmp);
    if ((itmp < -12) || (itmp > 12))
    {
        EPRINT("chroma_qp_index_offset");
        return(HANTRO_NOK);
    }
    pPicParamSet->chromaQpIndexOffset = itmp;

    tmp = h264bsdGetBits(pStrmData, 1);
    if (tmp == END_OF_STREAM)
        return(HANTRO_NOK);
    pPicParamSet->deblockingFilterControlPresentFlag =
        (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;

    tmp = h264bsdGetBits(pStrmData, 1);
    if (tmp == END_OF_STREAM)
        return(HANTRO_NOK);
    pPicParamSet->constrainedIntraPredFlag = (tmp == 1) ?
                                    HANTRO_TRUE : HANTRO_FALSE;

    tmp = h264bsdGetBits(pStrmData, 1);
    if (tmp == END_OF_STREAM)
        return(HANTRO_NOK);
    pPicParamSet->redundantPicCntPresentFlag = (tmp == 1) ?
                                    HANTRO_TRUE : HANTRO_FALSE;

    tmp = h264bsdRbspTrailingBits(pStrmData);

    /* ignore possible errors in trailing bits of parameters sets */
    return(HANTRO_OK);

}
u32 h264bsdDecodeMacroblockLayer(strmData_t *pStrmData,
    macroblockLayer_t *pMbLayer, mbStorage_t *pMb, u32 sliceType,
    u32 numRefIdxActive)
{

/* Variables */

    u32 tmp, i, value;
    i32 itmp;
    mbPartPredMode_e partMode;

/* Code */

    ASSERT(pStrmData);
    ASSERT(pMbLayer);

#ifdef H264DEC_NEON
    h264bsdClearMbLayer(pMbLayer, ((sizeof(macroblockLayer_t) + 63) & ~0x3F));
#else
    H264SwDecMemset(pMbLayer, 0, sizeof(macroblockLayer_t));
#endif

    tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);

    if (IS_I_SLICE(sliceType))
    {
        if ((value + 6) > 31 || tmp != HANTRO_OK)
            return(HANTRO_NOK);
        pMbLayer->mbType = (mbType_e)(value + 6);
    }
    else
    {
        if ((value + 1) > 31 || tmp != HANTRO_OK)
            return(HANTRO_NOK);
        pMbLayer->mbType = (mbType_e)(value + 1);
    }

    if (pMbLayer->mbType == I_PCM)
    {
        i32 *level;
        while( !h264bsdIsByteAligned(pStrmData) )
        {
            /* pcm_alignment_zero_bit */
            tmp = h264bsdGetBits(pStrmData, 1);
            if (tmp)
                return(HANTRO_NOK);
        }

        level = pMbLayer->residual.level[0];
        for (i = 0; i < 384; i++)
        {
            value = h264bsdGetBits(pStrmData, 8);
            if (value == END_OF_STREAM)
                return(HANTRO_NOK);
            *level++ = (i32)value;
        }
    }
    else
    {
        partMode = h264bsdMbPartPredMode(pMbLayer->mbType);
        if ( (partMode == PRED_MODE_INTER) &&
             (h264bsdNumMbPart(pMbLayer->mbType) == 4) )
        {
            tmp = DecodeSubMbPred(pStrmData, &pMbLayer->subMbPred,
                pMbLayer->mbType, numRefIdxActive);
        }
        else
        {
            tmp = DecodeMbPred(pStrmData, &pMbLayer->mbPred,
                pMbLayer->mbType, numRefIdxActive);
        }
        if (tmp != HANTRO_OK)
            return(tmp);

        if (partMode != PRED_MODE_INTRA16x16)
        {
            tmp = h264bsdDecodeExpGolombMapped(pStrmData, &value,
                (u32)(partMode == PRED_MODE_INTRA4x4));
            if (tmp != HANTRO_OK)
                return(tmp);
            pMbLayer->codedBlockPattern = value;
        }
        else
        {
            pMbLayer->codedBlockPattern = CbpIntra16x16(pMbLayer->mbType);
        }

        if ( pMbLayer->codedBlockPattern ||
             (partMode == PRED_MODE_INTRA16x16) )
        {
            tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp);
            if (tmp != HANTRO_OK || (itmp < -26) || (itmp > 25) )
                return(HANTRO_NOK);
            pMbLayer->mbQpDelta = itmp;

            tmp = DecodeResidual(pStrmData, &pMbLayer->residual, pMb,
                pMbLayer->mbType, pMbLayer->codedBlockPattern);

            pStrmData->strmBuffReadBits =
                (u32)(pStrmData->pStrmCurrPos - pStrmData->pStrmBuffStart) * 8 +
                pStrmData->bitPosInWord;

            if (tmp != HANTRO_OK)
                return(tmp);
        }
    }

    return(HANTRO_OK);

}
u32 h264bsdDecodeSeqParamSet(strmData_t *pStrmData, seqParamSet_t *pSeqParamSet)
{

/* Variables */

    u32 tmp, i, value;

/* Code */

    ASSERT(pStrmData);
    ASSERT(pSeqParamSet);

    memset(pSeqParamSet, 0, sizeof(seqParamSet_t));

    /* profile_idc */
    tmp = h264bsdGetBits(pStrmData, 8);
    if (tmp == END_OF_STREAM)
        return(HANTRO_NOK);
    if (tmp != 66)
    {
        DEBUG(("NOT BASELINE PROFILE %d\n", tmp));
    }
    pSeqParamSet->profileIdc = tmp;

    /* constrained_set0_flag */
    tmp = h264bsdGetBits(pStrmData, 1);
    /* constrained_set1_flag */
    tmp = h264bsdGetBits(pStrmData, 1);
    /* constrained_set2_flag */
    tmp = h264bsdGetBits(pStrmData, 1);

    if (tmp == END_OF_STREAM)
        return(HANTRO_NOK);

    /* reserved_zero_5bits, values of these bits shall be ignored */
    tmp = h264bsdGetBits(pStrmData, 5);
    if (tmp == END_OF_STREAM)
        return(HANTRO_NOK);

    tmp = h264bsdGetBits(pStrmData, 8);
    if (tmp == END_OF_STREAM)
        return(HANTRO_NOK);
    pSeqParamSet->levelIdc = tmp;

    tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
        &pSeqParamSet->seqParameterSetId);
    if (tmp != HANTRO_OK)
        return(tmp);
    if (pSeqParamSet->seqParameterSetId >= MAX_NUM_SEQ_PARAM_SETS)
    {
        EPRINT("seq_param_set_id");
        return(HANTRO_NOK);
    }

    /* log2_max_frame_num_minus4 */
    tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
    if (tmp != HANTRO_OK)
        return(tmp);
    if (value > 12)
    {
        EPRINT("log2_max_frame_num_minus4");
        return(HANTRO_NOK);
    }
    /* maxFrameNum = 2^(log2_max_frame_num_minus4 + 4) */
    pSeqParamSet->maxFrameNum = 1 << (value+4);

    /* valid POC types are 0, 1 and 2 */
    tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
    if (tmp != HANTRO_OK)
        return(tmp);
    if (value > 2)
    {
        EPRINT("pic_order_cnt_type");
        return(HANTRO_NOK);
    }
    pSeqParamSet->picOrderCntType = value;

    if (pSeqParamSet->picOrderCntType == 0)
    {
        /* log2_max_pic_order_cnt_lsb_minus4 */
        tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
        if (tmp != HANTRO_OK)
            return(tmp);
        if (value > 12)
        {
            EPRINT("log2_max_pic_order_cnt_lsb_minus4");
            return(HANTRO_NOK);
        }
        /* maxPicOrderCntLsb = 2^(log2_max_pic_order_cnt_lsb_minus4 + 4) */
        pSeqParamSet->maxPicOrderCntLsb = 1 << (value+4);
    }
    else if (pSeqParamSet->picOrderCntType == 1)
    {
        tmp = h264bsdGetBits(pStrmData, 1);
        if (tmp == END_OF_STREAM)
            return(HANTRO_NOK);
        pSeqParamSet->deltaPicOrderAlwaysZeroFlag = (tmp == 1) ?
                                        HANTRO_TRUE : HANTRO_FALSE;

        tmp = h264bsdDecodeExpGolombSigned(pStrmData,
            &pSeqParamSet->offsetForNonRefPic);
        if (tmp != HANTRO_OK)
            return(tmp);

        tmp = h264bsdDecodeExpGolombSigned(pStrmData,
            &pSeqParamSet->offsetForTopToBottomField);
        if (tmp != HANTRO_OK)
            return(tmp);

        tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
            &pSeqParamSet->numRefFramesInPicOrderCntCycle);
        if (tmp != HANTRO_OK)
            return(tmp);
        if (pSeqParamSet->numRefFramesInPicOrderCntCycle > 255)
        {
            EPRINT("num_ref_frames_in_pic_order_cnt_cycle");
            return(HANTRO_NOK);
        }

        if (pSeqParamSet->numRefFramesInPicOrderCntCycle)
        {
            /* NOTE: This has to be freed somewhere! */
            ALLOCATE(pSeqParamSet->offsetForRefFrame,
                     pSeqParamSet->numRefFramesInPicOrderCntCycle, i32);
            if (pSeqParamSet->offsetForRefFrame == NULL)
                return(MEMORY_ALLOCATION_ERROR);

            for (i = 0; i < pSeqParamSet->numRefFramesInPicOrderCntCycle; i++)
            {
                tmp =  h264bsdDecodeExpGolombSigned(pStrmData,
                    pSeqParamSet->offsetForRefFrame + i);
                if (tmp != HANTRO_OK)
                    return(tmp);
            }
        }
        else
        {
            pSeqParamSet->offsetForRefFrame = NULL;
        }
    }

    tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
        &pSeqParamSet->numRefFrames);
    if (tmp != HANTRO_OK)
        return(tmp);
    if (pSeqParamSet->numRefFrames > MAX_NUM_REF_PICS)
    {
        EPRINT("num_ref_frames");
        return(HANTRO_NOK);
    }

    tmp = h264bsdGetBits(pStrmData, 1);
    if (tmp == END_OF_STREAM)
        return(HANTRO_NOK);
    pSeqParamSet->gapsInFrameNumValueAllowedFlag = (tmp == 1) ?
                                        HANTRO_TRUE : HANTRO_FALSE;

    tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
    if (tmp != HANTRO_OK)
        return(tmp);
    pSeqParamSet->picWidthInMbs = value + 1;

    tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
    if (tmp != HANTRO_OK)
        return(tmp);
    pSeqParamSet->picHeightInMbs = value + 1;

    /* frame_mbs_only_flag, shall be 1 for baseline profile */
    tmp = h264bsdGetBits(pStrmData, 1);
    if (tmp == END_OF_STREAM)
        return(HANTRO_NOK);
    if (!tmp)
    {
        EPRINT("frame_mbs_only_flag");
        return(HANTRO_NOK);
    }

    /* direct_8x8_inference_flag */
    tmp = h264bsdGetBits(pStrmData, 1);
    if (tmp == END_OF_STREAM)
        return(HANTRO_NOK);

    tmp = h264bsdGetBits(pStrmData, 1);
    if (tmp == END_OF_STREAM)
        return(HANTRO_NOK);
    pSeqParamSet->frameCroppingFlag = (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;

    if (pSeqParamSet->frameCroppingFlag)
    {
        tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
            &pSeqParamSet->frameCropLeftOffset);
        if (tmp != HANTRO_OK)
            return(tmp);
        tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
            &pSeqParamSet->frameCropRightOffset);
        if (tmp != HANTRO_OK)
            return(tmp);
        tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
            &pSeqParamSet->frameCropTopOffset);
        if (tmp != HANTRO_OK)
            return(tmp);
        tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
            &pSeqParamSet->frameCropBottomOffset);
        if (tmp != HANTRO_OK)
            return(tmp);

        /* check that frame cropping params are valid, parameters shall
         * specify non-negative area within the original picture */
        if ( ( (i32)pSeqParamSet->frameCropLeftOffset >
               ( 8 * (i32)pSeqParamSet->picWidthInMbs -
                 ((i32)pSeqParamSet->frameCropRightOffset + 1) ) ) ||
             ( (i32)pSeqParamSet->frameCropTopOffset >
               ( 8 * (i32)pSeqParamSet->picHeightInMbs -
                 ((i32)pSeqParamSet->frameCropBottomOffset + 1) ) ) )
        {
            EPRINT("frame_cropping");
            return(HANTRO_NOK);
        }
    }

    /* check that image dimensions and levelIdc match */
    tmp = pSeqParamSet->picWidthInMbs * pSeqParamSet->picHeightInMbs;
    value = GetDpbSize(tmp, pSeqParamSet->levelIdc);
    if (value == INVALID_DPB_SIZE || pSeqParamSet->numRefFrames > value)
    {
        DEBUG(("WARNING! Invalid DPB size based on SPS Level!\n"));
        DEBUG(("WARNING! Using num_ref_frames =%d for DPB size!\n",
                        pSeqParamSet->numRefFrames));
        value = pSeqParamSet->numRefFrames;
    }
    pSeqParamSet->maxDpbSize = value;

    tmp = h264bsdGetBits(pStrmData, 1);
    if (tmp == END_OF_STREAM)
        return(HANTRO_NOK);
    pSeqParamSet->vuiParametersPresentFlag = (tmp == 1) ?
                                HANTRO_TRUE : HANTRO_FALSE;

    /* VUI */
    if (pSeqParamSet->vuiParametersPresentFlag)
    {
        ALLOCATE(pSeqParamSet->vuiParameters, 1, vuiParameters_t);
        if (pSeqParamSet->vuiParameters == NULL)
            return(MEMORY_ALLOCATION_ERROR);
        tmp = h264bsdDecodeVuiParameters(pStrmData,
            pSeqParamSet->vuiParameters);
        if (tmp != HANTRO_OK)
            return(tmp);
        /* check numReorderFrames and maxDecFrameBuffering */
        if (pSeqParamSet->vuiParameters->bitstreamRestrictionFlag)
        {
            if (pSeqParamSet->vuiParameters->numReorderFrames >
                    pSeqParamSet->vuiParameters->maxDecFrameBuffering ||
                pSeqParamSet->vuiParameters->maxDecFrameBuffering <
                    pSeqParamSet->numRefFrames ||
                pSeqParamSet->vuiParameters->maxDecFrameBuffering >
                    pSeqParamSet->maxDpbSize)
            {
                return(HANTRO_NOK);
            }

            /* standard says that "the sequence shall not require a DPB with
             * size of more than max(1, maxDecFrameBuffering) */
            pSeqParamSet->maxDpbSize =
                MAX(1, pSeqParamSet->vuiParameters->maxDecFrameBuffering);
        }
    }

    tmp = h264bsdRbspTrailingBits(pStrmData);

    /* ignore possible errors in trailing bits of parameters sets */
    return(HANTRO_OK);

}
u32 h264bsdDecodeMacroblockLayerCavlc(strmData_t * pStrmData,
                                      macroblockLayer_t * pMbLayer,
                                      mbStorage_t * pMb,
                                      const sliceHeader_t * pSliceHdr )
{

/* Variables */

    u32 tmp, i, value;
    i32 itmp;
    mbPartPredMode_e partMode;

/* Code */

    ASSERT(pStrmData);
    ASSERT(pMbLayer);

    (void)DWLmemset(pMbLayer->residual.totalCoeff, 0, 24);

    tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);

    if(IS_I_SLICE(pSliceHdr->sliceType))
    {
        if((value + 6) > 31 || tmp != HANTRO_OK)
            return (HANTRO_NOK);
        pMbLayer->mbType = (mbType_e) (value + 6);
    }
    else
    {
        if((value + 1) > 31 || tmp != HANTRO_OK)
            return (HANTRO_NOK);
        pMbLayer->mbType = (mbType_e) (value + 1);
    }

    if(pMbLayer->mbType == I_PCM)
    {
        u8 *level;

        while(!h264bsdIsByteAligned(pStrmData))
        {
            /* pcm_alignment_zero_bit */
            tmp = h264bsdGetBits(pStrmData, 1);
            if(tmp)
                return (HANTRO_NOK);
        }

        level = (u8 *) pMbLayer->residual.rlc;
        for(i = 384; i > 0; i--)
        {
            value = h264bsdGetBits(pStrmData, 8);
            if(value == END_OF_STREAM)
                return (HANTRO_NOK);
            *level++ = (u8) value;
        }
    }
    else
    {
        partMode = h264bsdMbPartPredMode(pMbLayer->mbType);
        if((partMode == PRED_MODE_INTER) &&
           (h264bsdNumMbPart(pMbLayer->mbType) == 4))
        {
            tmp = DecodeSubMbPred(pStrmData, &pMbLayer->subMbPred,
                                  pMbLayer->mbType,
                                  pSliceHdr->numRefIdxL0Active,
                                  pMb );
        }
        else
        {
            tmp = DecodeMbPred(pStrmData, &pMbLayer->mbPred,
                               pMbLayer->mbType, pSliceHdr->numRefIdxL0Active,
                               pMb );
        }
        if(tmp != HANTRO_OK)
            return (tmp);

        if(partMode != PRED_MODE_INTRA16x16)
        {
            tmp = h264bsdDecodeExpGolombMapped(pStrmData, &value,
                                               (u32) (partMode ==
                                                       PRED_MODE_INTRA4x4));
            if(tmp != HANTRO_OK)
                return (tmp);
            pMbLayer->codedBlockPattern = value;
        }
        else
        {
            pMbLayer->codedBlockPattern = CbpIntra16x16(pMbLayer->mbType);
        }

        if(pMbLayer->codedBlockPattern || (partMode == PRED_MODE_INTRA16x16))
        {
            tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp);
            if(tmp != HANTRO_OK ||
               (u32) (itmp + 26) > 51U /*(itmp >= -26) || (itmp < 26) */ )
                return (HANTRO_NOK);

            pMbLayer->mbQpDelta = itmp;

            tmp = DecodeResidual(pStrmData, pMbLayer, pMb);

            if(tmp != HANTRO_OK)
                return (tmp);
        }
    }

    return (HANTRO_OK);
}
u32 h264bsdDecodeNalUnit(strmData_t *pStrmData, nalUnit_t *pNalUnit)
{

    /* Variables */

    u32 tmp;

    /* Code */

    ASSERT(pStrmData);
    ASSERT(pNalUnit);
    ASSERT(pStrmData->bitPosInWord == 0);

    memset(pNalUnit, 0, sizeof(nalUnit_t));

    /* forbidden_zero_bit (not checked to be zero, errors ignored) */
    tmp = h264bsdGetBits(pStrmData, 1);
    /* Assuming that NAL unit starts from byte boundary ­> don't have to check
     * following 7 bits for END_OF_STREAM */
    if (tmp == END_OF_STREAM)
        return(HANTRO_NOK);

    tmp = h264bsdGetBits(pStrmData, 2);
    pNalUnit->nalRefIdc = tmp;

    tmp = h264bsdGetBits(pStrmData, 5);
    pNalUnit->nalUnitType = (nalUnitType_e)tmp;

    DEBUG_PRINT(("NAL TYPE %d\n", tmp));

    /* data partitioning NAL units not supported */
    if ( (tmp == NAL_CODED_SLICE_DP_A) ||
            (tmp == NAL_CODED_SLICE_DP_B) ||
            (tmp == NAL_CODED_SLICE_DP_C) )
    {
        ERROR_PRINT(("DP slices not allowed!!!"));
        return(HANTRO_NOK);
    }

    /* nal_ref_idc shall not be zero for these nal_unit_types */
    if ( ( (tmp == NAL_SEQ_PARAM_SET) || (tmp == NAL_PIC_PARAM_SET) ||
            (tmp == NAL_CODED_SLICE_IDR) ) && (pNalUnit->nalRefIdc == 0) )
    {
        ERROR_PRINT(("nal_ref_idc shall not be zero!!!"));
        return(HANTRO_NOK);
    }
    /* nal_ref_idc shall be zero for these nal_unit_types */
    else if ( ( (tmp == NAL_SEI) || (tmp == NAL_ACCESS_UNIT_DELIMITER) ||
                (tmp == NAL_END_OF_SEQUENCE) || (tmp == NAL_END_OF_STREAM) ||
                (tmp == NAL_FILLER_DATA) ) && (pNalUnit->nalRefIdc != 0) )
    {
        ERROR_PRINT(("nal_ref_idc shall be zero!!!"));
        return(HANTRO_NOK);
    }

    if (pNalUnit->nalUnitType == NAL_PREFIX ||
            pNalUnit->nalUnitType == NAL_CODED_SLICE_EXT)
    {
        /* svc_extension_flag */
        tmp = h264bsdGetBits(pStrmData, 1);
        tmp = h264bsdGetBits(pStrmData, 1);
        pNalUnit->nonIdrFlag = tmp;
        tmp = h264bsdGetBits(pStrmData, 6);
        pNalUnit->priorityId = tmp;
        tmp = h264bsdGetBits(pStrmData, 10);
        pNalUnit->viewId = tmp;
        tmp = h264bsdGetBits(pStrmData, 3);
        pNalUnit->temporalId = tmp;
        tmp = h264bsdGetBits(pStrmData, 1);
        pNalUnit->anchorPicFlag = tmp;
        tmp = h264bsdGetBits(pStrmData, 1);
        pNalUnit->interViewFlag = tmp;
        /* reserved_one_bit */
        tmp = h264bsdGetBits(pStrmData, 1);
        if (tmp == END_OF_STREAM)
            return(HANTRO_NOK);
    }

    return(HANTRO_OK);

}