Esempio n. 1
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 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 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);

}
Esempio n. 4
0
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);

}