Exemplo n.º 1
0
u32 h264bsdDecodeSliceData(strmData_t *pStrmData, storage_t *pStorage,
    image_t *currImage, sliceHeader_t *pSliceHeader)
{

/* Variables */

    u8 mbData[384 + 15 + 32];
    u8 *data;
    u32 tmp;
    u32 skipRun;
    u32 prevSkipped;
    u32 currMbAddr;
    u32 moreMbs;
    u32 mbCount;
    i32 qpY;
    macroblockLayer_t *mbLayer;

/* Code */

    ASSERT(pStrmData);
    ASSERT(pSliceHeader);
    ASSERT(pStorage);
    ASSERT(pSliceHeader->firstMbInSlice < pStorage->picSizeInMbs);

    /* ensure 16-byte alignment */
    data = (u8*)ALIGN(mbData, 16);

    mbLayer = pStorage->mbLayer;

    currMbAddr = pSliceHeader->firstMbInSlice;
    skipRun = 0;
    prevSkipped = HANTRO_FALSE;

    /* increment slice index, will be one for decoding of the first slice of
     * the picture */
    pStorage->slice->sliceId++;

    /* lastMbAddr stores address of the macroblock that was last successfully
     * decoded, needed for error handling */
    pStorage->slice->lastMbAddr = 0;

    mbCount = 0;
    /* initial quantization parameter for the slice is obtained as the sum of
     * initial QP for the picture and sliceQpDelta for the current slice */
    qpY = (i32)pStorage->activePps->picInitQp + pSliceHeader->sliceQpDelta;
    do
    {
        /* primary picture and already decoded macroblock -> error */
        if (!pSliceHeader->redundantPicCnt && pStorage->mb[currMbAddr].decoded)
        {
            EPRINT("Primary and already decoded");
            return(HANTRO_NOK);
        }

        SetMbParams(pStorage->mb + currMbAddr, pSliceHeader,
            pStorage->slice->sliceId, pStorage->activePps->chromaQpIndexOffset);

        if (!IS_I_SLICE(pSliceHeader->sliceType))
        {
            if (!prevSkipped)
            {
                tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &skipRun);
                if (tmp != HANTRO_OK)
                    return(tmp);
                /* skip_run shall be less than or equal to number of
                 * macroblocks left */
                if (skipRun > (pStorage->picSizeInMbs - currMbAddr))
                {
                    EPRINT("skip_run");
                    return(HANTRO_NOK);
                }
                if (skipRun)
                {
                    prevSkipped = HANTRO_TRUE;
                    memset(&mbLayer->mbPred, 0, sizeof(mbPred_t));
                    /* mark current macroblock skipped */
                    mbLayer->mbType = P_Skip;
                }
            }
        }

        if (skipRun)
        {
            DEBUG(("Skipping macroblock %d\n", currMbAddr));
            skipRun--;
        }
        else
        {
            prevSkipped = HANTRO_FALSE;
            tmp = h264bsdDecodeMacroblockLayer(pStrmData, mbLayer,
                pStorage->mb + currMbAddr, pSliceHeader->sliceType,
                pSliceHeader->numRefIdxL0Active);
            if (tmp != HANTRO_OK)
            {
                EPRINT("macroblock_layer");
                return(tmp);
            }
        }

        tmp = h264bsdDecodeMacroblock(pStorage->mb + currMbAddr, mbLayer,
            currImage, pStorage->dpb, &qpY, currMbAddr,
            pStorage->activePps->constrainedIntraPredFlag, data);
        if (tmp != HANTRO_OK)
        {
            EPRINT("MACRO_BLOCK");
            return(tmp);
        }

        /* increment macroblock count only for macroblocks that were decoded
         * for the first time (redundant slices) */
        if (pStorage->mb[currMbAddr].decoded == 1)
            mbCount++;

        /* keep on processing as long as there is stream data left or
         * processing of macroblocks to be skipped based on the last skipRun is
         * not finished */
        moreMbs = (h264bsdMoreRbspData(pStrmData) || skipRun) ?
                                        HANTRO_TRUE : HANTRO_FALSE;

        /* lastMbAddr is only updated for intra slices (all macroblocks of
         * inter slices will be lost in case of an error) */
        if (IS_I_SLICE(pSliceHeader->sliceType))
            pStorage->slice->lastMbAddr = currMbAddr;

        currMbAddr = h264bsdNextMbAddress(pStorage->sliceGroupMap,
            pStorage->picSizeInMbs, currMbAddr);
        /* data left in the buffer but no more macroblocks for current slice
         * group -> error */
        if (moreMbs && !currMbAddr)
        {
            EPRINT("Next mb address");
            return(HANTRO_NOK);
        }

    } while (moreMbs);

    if ((pStorage->slice->numDecodedMbs + mbCount) > pStorage->picSizeInMbs)
    {
        EPRINT("Num decoded mbs");
        return(HANTRO_NOK);
    }

    pStorage->slice->numDecodedMbs += mbCount;

    return(HANTRO_OK);

}
Exemplo n.º 2
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));

}