Ejemplo n.º 1
0
mfxStatus AVC_Spl::AddSliceNalUnit(mfxBitstream * nalUnit, AVCSlice * slice)
{
    static mfxU8 start_code_prefix[] = {0, 0, 1};

    mfxU32 sliceLength = (mfxU32)(nalUnit->DataLength + sizeof(start_code_prefix));

    if (m_frame.DataLength + sliceLength >= BUFFER_SIZE)
        return MFX_ERR_NOT_ENOUGH_BUFFER;

    MSDK_MEMCPY_BUF(m_frame.Data, m_frame.DataLength, BUFFER_SIZE, start_code_prefix, sizeof(start_code_prefix));
    MSDK_MEMCPY_BUF(m_frame.Data, m_frame.DataLength + sizeof(start_code_prefix), BUFFER_SIZE, nalUnit->Data + nalUnit->DataOffset, nalUnit->DataLength);

    if (!m_frame.SliceNum)
    {
        m_frame.TimeStamp = nalUnit->TimeStamp;
    }

    m_frame.SliceNum++;

    if (m_slices.size() <= m_frame.SliceNum)
    {
        m_slices.resize(m_frame.SliceNum + 10);
        m_frame.Slice = &m_slices[0];
    }

    SliceSplitterInfo & newSlice = m_slices[m_frame.SliceNum - 1];

    AVCHeadersBitstream * bs = slice->GetBitStream();

    newSlice.HeaderLength = (mfxU32)bs->BytesDecoded();

    // add number of 003 sequence to HeaderLength
    for(mfxU8 *ptr = nalUnit->Data + sizeof(start_code_prefix); ptr < nalUnit->Data + sizeof(start_code_prefix) + newSlice.HeaderLength; ptr++)
    {
        if (ptr[0]==0 && ptr[1]==0 && ptr[2]==3)
        {
            newSlice.HeaderLength++;
        }
    }

    newSlice.HeaderLength += sizeof(start_code_prefix) + 1;

    newSlice.DataLength = sliceLength;
    newSlice.DataOffset = m_frame.DataLength;
    if(IS_I_SLICE(slice->GetSliceHeader()->slice_type))
        newSlice.SliceType = TYPE_I;
    else if(IS_P_SLICE(slice->GetSliceHeader()->slice_type))
        newSlice.SliceType = TYPE_P;
    else if(IS_B_SLICE(slice->GetSliceHeader()->slice_type))
        newSlice.SliceType = TYPE_B;

    m_frame.DataLength += sliceLength;

    if (!m_currentInfo->m_index)
        m_frame.FirstFieldSliceNum++;

    return MFX_ERR_NONE;
}
Ejemplo n.º 2
0
u32 ConcealMb(mbStorage_t *pMb, image_t *currImage, u32 row, u32 col,
    u32 sliceType, u8 *refData)
{

/* Variables */

    u32 i, j, comp;
    u32 hor, ver;
    u32 mbNum;
    u32 width, height;
    u8 *mbPos;
    u8 data[384];
    u8 *pData;
    i32 tmp;
    i32 firstPhase[16];
    i32 *pTmp;
    /* neighbours above, below, left and right */
    i32 a[4] = { 0,0,0,0 }, b[4], l[4] = { 0,0,0,0 }, r[4];
    u32 A, B, L, R;
#ifdef H264DEC_OMXDL
    u8 fillBuff[32*21 + 15 + 32];
    u8 *pFill;
#endif
/* Code */

    ASSERT(pMb);
    ASSERT(!pMb->decoded);
    ASSERT(currImage);
    ASSERT(col < currImage->width);
    ASSERT(row < currImage->height);

#ifdef H264DEC_OMXDL
    pFill = ALIGN(fillBuff, 16);
#endif
    width = currImage->width;
    height = currImage->height;
    mbNum = row * width + col;

    h264bsdSetCurrImageMbPointers(currImage, mbNum);

    mbPos = currImage->data + row * 16 * width * 16 + col * 16;
    A = B = L = R = HANTRO_FALSE;

    /* set qpY to 40 to enable some filtering in deblocking (stetson value) */
    pMb->qpY = 40;
    pMb->disableDeblockingFilterIdc = 0;
    /* mbType set to intra to perform filtering despite the values of other
     * boundary strength determination fields */
    pMb->mbType = I_4x4;
    pMb->filterOffsetA = 0;
    pMb->filterOffsetB = 0;
    pMb->chromaQpIndexOffset = 0;

    if (IS_I_SLICE(sliceType))
        memset(data, 0, sizeof(data));
    else
    {
        mv_t mv = {0,0};
        image_t refImage;
        refImage.width = width;
        refImage.height = height;
        refImage.data = refData;
        if (refImage.data)
        {
#ifndef H264DEC_OMXDL
            h264bsdPredictSamples(data, &mv, &refImage, col*16, row*16,
                0, 0, 16, 16);
#else
            h264bsdPredictSamples(data, &mv, &refImage,
                    ((row*16) + ((col*16)<<16)),
                    0x00001010, pFill);
#endif
            h264bsdWriteMacroblock(currImage, data);

            return(HANTRO_OK);
        }
        else
            memset(data, 0, sizeof(data));
    }

    memset(firstPhase, 0, sizeof(firstPhase));

    /* counter for number of neighbours used */
    j = 0;
    hor = ver = 0;
    if (row && (pMb-width)->decoded)
    {
        A = HANTRO_TRUE;
        pData = mbPos - width*16;
        a[0] = *pData++; a[0] += *pData++; a[0] += *pData++; a[0] += *pData++;
        a[1] = *pData++; a[1] += *pData++; a[1] += *pData++; a[1] += *pData++;
        a[2] = *pData++; a[2] += *pData++; a[2] += *pData++; a[2] += *pData++;
        a[3] = *pData++; a[3] += *pData++; a[3] += *pData++; a[3] += *pData++;
        j++;
        hor++;
        firstPhase[0] += a[0] + a[1] + a[2] + a[3];
        firstPhase[1] += a[0] + a[1] - a[2] - a[3];
    }
    if ((row != height - 1) && (pMb+width)->decoded)
    {
        B = HANTRO_TRUE;
        pData = mbPos + 16*width*16;
        b[0] = *pData++; b[0] += *pData++; b[0] += *pData++; b[0] += *pData++;
        b[1] = *pData++; b[1] += *pData++; b[1] += *pData++; b[1] += *pData++;
        b[2] = *pData++; b[2] += *pData++; b[2] += *pData++; b[2] += *pData++;
        b[3] = *pData++; b[3] += *pData++; b[3] += *pData++; b[3] += *pData++;
        j++;
        hor++;
        firstPhase[0] += b[0] + b[1] + b[2] + b[3];
        firstPhase[1] += b[0] + b[1] - b[2] - b[3];
    }
    if (col && (pMb-1)->decoded)
    {
        L = HANTRO_TRUE;
        pData = mbPos - 1;
        l[0] = pData[0]; l[0] += pData[16*width];
        l[0] += pData[32*width]; l[0] += pData[48*width];
        pData += 64*width;
        l[1] = pData[0]; l[1] += pData[16*width];
        l[1] += pData[32*width]; l[1] += pData[48*width];
        pData += 64*width;
        l[2] = pData[0]; l[2] += pData[16*width];
        l[2] += pData[32*width]; l[2] += pData[48*width];
        pData += 64*width;
        l[3] = pData[0]; l[3] += pData[16*width];
        l[3] += pData[32*width]; l[3] += pData[48*width];
        j++;
        ver++;
        firstPhase[0] += l[0] + l[1] + l[2] + l[3];
        firstPhase[4] += l[0] + l[1] - l[2] - l[3];
    }
    if ((col != width - 1) && (pMb+1)->decoded)
    {
        R = HANTRO_TRUE;
        pData = mbPos + 16;
        r[0] = pData[0]; r[0] += pData[16*width];
        r[0] += pData[32*width]; r[0] += pData[48*width];
        pData += 64*width;
        r[1] = pData[0]; r[1] += pData[16*width];
        r[1] += pData[32*width]; r[1] += pData[48*width];
        pData += 64*width;
        r[2] = pData[0]; r[2] += pData[16*width];
        r[2] += pData[32*width]; r[2] += pData[48*width];
        pData += 64*width;
        r[3] = pData[0]; r[3] += pData[16*width];
        r[3] += pData[32*width]; r[3] += pData[48*width];
        j++;
        ver++;
        firstPhase[0] += r[0] + r[1] + r[2] + r[3];
        firstPhase[4] += r[0] + r[1] - r[2] - r[3];
    }

    /* at least one properly decoded neighbour available */
    ASSERT(j);

    /*lint -esym(644,l,r,a,b) variable initialized above */
    if (!hor && L && R)
        firstPhase[1] = (l[0]+l[1]+l[2]+l[3]-r[0]-r[1]-r[2]-r[3]) >> 5;
    else if (hor)
Ejemplo n.º 3
0
u32 h264bsdConceal(storage_t *pStorage, image_t *currImage, u32 sliceType)
{

/* Variables */

    u32 i, j;
    u32 row, col;
    u32 width, height;
    u8 *refData;
    mbStorage_t *mb;

/* Code */

    ASSERT(pStorage);
    ASSERT(currImage);

    DEBUG(("Concealing %s slice\n", IS_I_SLICE(sliceType) ?
            "intra" : "inter"));

    width = currImage->width;
    height = currImage->height;
    refData = NULL;
    /* use reference picture with smallest available index */
    if (IS_P_SLICE(sliceType) || (pStorage->intraConcealmentFlag != 0))
    {
        i = 0;
        do
        {
            refData = h264bsdGetRefPicData(pStorage->dpb, i);
            i++;
            if (i >= 16)
                break;
        } while (refData == NULL);
    }

    i = row = col = 0;
    /* find first properly decoded macroblock -> start point for concealment */
    while (i < pStorage->picSizeInMbs && !pStorage->mb[i].decoded)
    {
        i++;
        col++;
        if (col == width)
        {
            row++;
            col = 0;
        }
    }

    /* whole picture lost -> copy previous or set grey */
    if (i == pStorage->picSizeInMbs)
    {
        if ( (IS_I_SLICE(sliceType) && (pStorage->intraConcealmentFlag == 0)) ||
             refData == NULL)
        {
            memset(currImage->data, 128, width*height*384);
        }
        else
        {
#ifndef FLASCC
            memcpy(currImage->data, refData, width*height*384);
#else
            int ii = 0;
            int size = width*height*384;
            u8* curr_data = currImage->data;
            for (ii = 0; ii < size;ii++)
                curr_data[i] = refData[i];
#endif
        }

        pStorage->numConcealedMbs = pStorage->picSizeInMbs;

        /* no filtering if whole picture concealed */
        for (i = 0; i < pStorage->picSizeInMbs; i++)
            pStorage->mb[i].disableDeblockingFilterIdc = 1;

        return(HANTRO_OK);
    }

    /* start from the row containing the first correct macroblock, conceal the
     * row in question, all rows above that row and then continue downwards */
    mb = pStorage->mb + row * width;
    for (j = col; j--;)
    {
        ConcealMb(mb+j, currImage, row, j, sliceType, refData);
        mb[j].decoded = 1;
        pStorage->numConcealedMbs++;
    }
    for (j = col + 1; j < width; j++)
    {
        if (!mb[j].decoded)
        {
            ConcealMb(mb+j, currImage, row, j, sliceType, refData);
            mb[j].decoded = 1;
            pStorage->numConcealedMbs++;
        }
    }
    /* if previous row(s) could not be concealed -> conceal them now */
    if (row)
    {
        for (j = 0; j < width; j++)
        {
            i = row - 1;
            mb = pStorage->mb + i*width + j;
            do
            {
                ConcealMb(mb, currImage, i, j, sliceType, refData);
                mb->decoded = 1;
                pStorage->numConcealedMbs++;
                mb -= width;
            } while(i--);
        }
    }

    /* process rows below the one containing the first correct macroblock */
    for (i = row + 1; i < height; i++)
    {
        mb = pStorage->mb + i * width;

        for (j = 0; j < width; j++)
        {
            if (!mb[j].decoded)
            {
                ConcealMb(mb+j, currImage, i, j, sliceType, refData);
                mb[j].decoded = 1;
                pStorage->numConcealedMbs++;
            }
        }
    }

    return(HANTRO_OK);
}
Ejemplo n.º 4
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);

}
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 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 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);
}