Files
MAX_CARLINK_A270S/MXC_A27-PCB4.5-270S/lib/hx170dec/src/h264hwd_decoder.c
2025-01-21 16:49:37 +08:00

1150 lines
36 KiB
C
Raw Blame History

/*------------------------------------------------------------------------------
-- --
-- This software is confidential and proprietary and may be used --
-- only as expressly authorized by a licensing agreement from --
-- --
-- Hantro Products Oy. --
-- --
-- (C) COPYRIGHT 2006 HANTRO PRODUCTS OY --
-- ALL RIGHTS RESERVED --
-- --
-- The entire notice above must be reproduced --
-- on all copies and should not be removed. --
-- --
--------------------------------------------------------------------------------
--
-- Abstract : Top level control of the decoder
--
--------------------------------------------------------------------------------
--
-- Version control information, please leave untouched.
--
-- $RCSfile: h264hwd_decoder.c,v $
-- $Date: 2009/11/26 13:32:15 $
-- $Revision: 1.23 $
--
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
1. Include headers
------------------------------------------------------------------------------*/
#include "h264hwd_container.h"
#include "h264hwd_decoder.h"
#include "h264hwd_nal_unit.h"
#include "h264hwd_byte_stream.h"
#include "h264hwd_seq_param_set.h"
#include "h264hwd_pic_param_set.h"
#include "h264hwd_slice_header.h"
#include "h264hwd_slice_data.h"
#include "h264hwd_neighbour.h"
#include "h264hwd_util.h"
#include "h264hwd_dpb.h"
#include "h264hwd_conceal.h"
/*------------------------------------------------------------------------------
2. External compiler flags
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
3. Module defines
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
4. Local function prototypes
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
Function name: h264bsdInit
Functional description:
Initialize the decoder.
Inputs:
noOutputReordering flag to indicate the decoder that it does not
have to perform reordering of display images.
Outputs:
pStorage pointer to initialized storage structure
Returns:
none
------------------------------------------------------------------------------*/
void h264bsdInit(storage_t * pStorage, u32 noOutputReordering,
u32 useSmoothingBuffer)
{
/* Variables */
/* Code */
ASSERT(pStorage);
h264bsdInitStorage(pStorage);
pStorage->noReordering = noOutputReordering;
pStorage->useSmoothing = useSmoothingBuffer;
}
/*------------------------------------------------------------------------------
Function: h264bsdDecodeVlc
Functional description:
Decode a NAL unit until a slice header. This function calls other modules to perform
tasks like
* extract and decode NAL unit from the byte stream
* decode parameter sets
* decode slice header and slice data
* conceal errors in the picture
* perform deblocking filtering
This function contains top level control logic of the decoder.
Inputs:
pStorage pointer to storage data structure
byteStrm pointer to stream buffer given by application
len length of the buffer in bytes
picId identifier for a picture, assigned by the
application
Outputs:
readBytes number of bytes read from the stream is stored
here
Returns:
H264BSD_RDY decoding finished, nothing special
H264BSD_PIC_RDY decoding of a picture finished
H264BSD_HDRS_RDY param sets activated, information like
picture dimensions etc can be read
H264BSD_ERROR error in decoding
H264BSD_PARAM_SET_ERROR serius error in decoding, failed to
activate param sets
------------------------------------------------------------------------------*/
u32 h264bsdDecode(decContainer_t * pDecCont, const u8 * byteStrm, u32 len,
u32 picId, u32 * readBytes)
{
/* Variables */
u32 tmp, ppsId, spsId;
u32 accessUnitBoundaryFlag = HANTRO_FALSE;
u32 picReady = HANTRO_FALSE;
storage_t *pStorage;
nalUnit_t nalUnit;
seqParamSet_t seqParamSet;
picParamSet_t picParamSet;
strmData_t strm;
u32 ret;
DEBUG_PRINT(("h264bsdDecode\n"));
/* Code */
ASSERT(pDecCont);
ASSERT(byteStrm);
ASSERT(len);
ASSERT(readBytes);
pStorage = &pDecCont->storage;
ASSERT(pStorage);
DEBUG_PRINT(("Valid slice in access unit %d\n",
pStorage->validSliceInAccessUnit));
if(pDecCont->rlcMode)
{
pStorage->strm[0].removeEmul3Byte = 1;
strm.removeEmul3Byte = 1;
}
else
{
pStorage->strm[0].removeEmul3Byte = 0;
strm.removeEmul3Byte = 0;
}
/* if previous buffer was not finished and same pointer given -> skip NAL
* unit extraction */
if(pStorage->prevBufNotFinished && byteStrm == pStorage->prevBufPointer)
{
strm = pStorage->strm[0];
strm.pStrmCurrPos = strm.pStrmBuffStart;
strm.strmBuffReadBits = strm.bitPosInWord = 0;
*readBytes = pStorage->prevBytesConsumed;
}
else
{
tmp =
h264bsdExtractNalUnit(byteStrm, len, &strm, readBytes,
pDecCont->rlcMode);
if(tmp != HANTRO_OK)
{
ERROR_PRINT("BYTE_STREAM");
return (H264BSD_ERROR);
}
/* store stream */
pStorage->strm[0] = strm;
pStorage->prevBytesConsumed = *readBytes;
pStorage->prevBufPointer = byteStrm;
}
pStorage->prevBufNotFinished = HANTRO_FALSE;
tmp = h264bsdDecodeNalUnit(&strm, &nalUnit);
if(tmp != HANTRO_OK)
{
ret = H264BSD_ERROR;
goto NEXT_NAL;
}
/* Discard unspecified, reserved, SPS extension and auxiliary picture slices */
if(nalUnit.nalUnitType == 0 || nalUnit.nalUnitType >= 13)
{
DEBUG_PRINT(("DISCARDED NAL (UNSPECIFIED, REGISTERED, SPS ext or AUX slice)\n"));
ret = H264BSD_RDY;
goto NEXT_NAL;
}
if(!pStorage->checkedAub)
{
tmp = h264bsdCheckAccessUnitBoundary(&strm,
&nalUnit,
pStorage, &accessUnitBoundaryFlag);
if(tmp != HANTRO_OK)
{
ERROR_PRINT("ACCESS UNIT BOUNDARY CHECK");
if(tmp == PARAM_SET_ERROR)
ret = (H264BSD_PARAM_SET_ERROR);
else
ret = (H264BSD_ERROR);
goto NEXT_NAL;
}
}
else
{
pStorage->checkedAub = 0;
}
if(accessUnitBoundaryFlag)
{
DEBUG_PRINT(("Access unit boundary, NAL TYPE %d\n",
nalUnit.nalUnitType));
/* conceal if picture started and param sets activated */
if(pStorage->picStarted && pStorage->activeSps != NULL)
{
if(pDecCont->rlcMode) /* Error conceal in RLC mode */
{
DecAsicBuffers_t *pAsicBuff = pDecCont->asicBuff;
ASSERT(pAsicBuff);
ASSERT(pAsicBuff->mbCtrl.virtualAddress);
DEBUG_PRINT(("CONCEALING..."));
if(!pStorage->validSliceInAccessUnit)
{
DEBUG_PRINT(("!validSliceunit\n"));
pStorage->currImage->data =
h264bsdAllocateDpbImage(pStorage->dpb);
h264bsdInitRefPicList(pStorage->dpb);
h264bsdConceal(pStorage, pAsicBuff, P_SLICE);
}
else
{
DEBUG_PRINT(("validSliceunit\n"));
h264bsdConceal(pStorage, pAsicBuff,
pStorage->sliceHeader->sliceType);
}
picReady = HANTRO_TRUE;
/* current NAL unit should be decoded on next activation -> set
* readBytes to 0 */
*readBytes = 0;
pStorage->prevBufNotFinished = HANTRO_TRUE;
DEBUG_PRINT(("...DONE\n"));
}
else /* VLC mode */
{
DEBUG_PRINT(("New access unit and previous not finished\n"));
DEBUG_PRINT(("PICTURE FREEZE CONCEAL...\n"));
if(!pStorage->validSliceInAccessUnit)
{
DEBUG_PRINT(("!validSliceunit\n"));
if (!pStorage->secondField)
{
pStorage->currImage->data =
h264bsdAllocateDpbImage(pStorage->dpb);
pStorage->sliceHeader->fieldPicFlag = 0;
}
h264bsdInitRefPicList(pStorage->dpb);
}
pStorage->skipRedundantSlices = HANTRO_FALSE;
/* current NAL unit should be decoded on next activation -> set
* readBytes to 0 */
*readBytes = 0;
pStorage->prevBufNotFinished = HANTRO_TRUE;
DEBUG_PRINT(("...DONE\n"));
return (H264BSD_NEW_ACCESS_UNIT);
}
}
else
{
DEBUG_PRINT(("vali slice false\n"));
pStorage->validSliceInAccessUnit = HANTRO_FALSE;
}
pStorage->skipRedundantSlices = HANTRO_FALSE;
}
if(!picReady)
{
DEBUG_PRINT(("nal unit type: %d\n", nalUnit.nalUnitType));
switch (nalUnit.nalUnitType)
{
case NAL_SEQ_PARAM_SET:
DEBUG_PRINT(("SEQ PARAM SET\n"));
tmp = h264bsdDecodeSeqParamSet(&strm, &seqParamSet);
if(tmp != HANTRO_OK)
{
ERROR_PRINT("SEQ_PARAM_SET decoding");
FREE(seqParamSet.offsetForRefFrame);
FREE(seqParamSet.vuiParameters);
ret = H264BSD_ERROR;
}
else
{
tmp = h264bsdStoreSeqParamSet(pStorage, &seqParamSet);
if(tmp != HANTRO_OK)
{
ERROR_PRINT("SEQ_PARAM_SET allocation");
ret = H264BSD_ERROR;
}
}
ret = H264BSD_RDY;
goto NEXT_NAL;
case NAL_PIC_PARAM_SET:
DEBUG_PRINT(("PIC PARAM SET\n"));
tmp = h264bsdDecodePicParamSet(&strm, &picParamSet);
if(tmp != HANTRO_OK)
{
ERROR_PRINT("PIC_PARAM_SET decoding");
FREE(picParamSet.runLength);
FREE(picParamSet.topLeft);
FREE(picParamSet.bottomRight);
FREE(picParamSet.sliceGroupId);
ret = H264BSD_ERROR;
}
else
{
tmp = h264bsdStorePicParamSet(pStorage, &picParamSet);
if(tmp != HANTRO_OK)
{
ERROR_PRINT("PIC_PARAM_SET allocation");
ret = H264BSD_ERROR;
}
}
ret = H264BSD_RDY;
goto NEXT_NAL;
case NAL_CODED_SLICE_IDR:
DEBUG_PRINT(("IDR "));
/* fall through */
case NAL_CODED_SLICE:
DEBUG_PRINT(("decode slice header\n"));
/* picture successfully finished and still decoding same old
* access unit -> no need to decode redundant slices */
if(pStorage->skipRedundantSlices)
{
DEBUG_PRINT(("skipping redundant slice\n"));
ret = H264BSD_RDY;
goto NEXT_NAL;
}
pStorage->picStarted = HANTRO_TRUE;
if(h264bsdIsStartOfPicture(pStorage))
{
pStorage->numConcealedMbs = 0;
pStorage->currentPicId = picId;
tmp = h264bsdCheckPpsId(&strm, &ppsId);
ASSERT(tmp == HANTRO_OK);
/* store old activeSpsId and return headers ready
* indication if activeSps changes */
spsId = pStorage->activeSpsId;
tmp = h264bsdActivateParamSets(pStorage, ppsId,
IS_IDR_NAL_UNIT(&nalUnit) ?
HANTRO_TRUE : HANTRO_FALSE);
if(tmp != HANTRO_OK)
{
ERROR_PRINT("Param set activation");
ret = H264BSD_PARAM_SET_ERROR;
goto NEXT_NAL;
}
if(spsId != pStorage->activeSpsId)
{
seqParamSet_t *oldSPS = NULL;
seqParamSet_t *newSPS = pStorage->activeSps;
u32 noOutputOfPriorPicsFlag = 1;
if(pStorage->oldSpsId < MAX_NUM_SEQ_PARAM_SETS)
{
oldSPS = pStorage->sps[pStorage->oldSpsId];
}
*readBytes = 0;
pStorage->prevBufNotFinished = HANTRO_TRUE;
if(nalUnit.nalUnitType == NAL_CODED_SLICE_IDR)
{
tmp =
h264bsdCheckPriorPicsFlag(&noOutputOfPriorPicsFlag,
&strm, newSPS,
pStorage->activePps,
nalUnit.nalUnitType);
}
else
{
tmp = HANTRO_NOK;
}
if((tmp != HANTRO_OK) ||
(noOutputOfPriorPicsFlag != 0) ||
(pStorage->dpb->noReordering) ||
(oldSPS == NULL) ||
(oldSPS->picWidthInMbs != newSPS->picWidthInMbs) ||
(oldSPS->picHeightInMbs != newSPS->picHeightInMbs) ||
(oldSPS->maxDpbSize != newSPS->maxDpbSize))
{
pStorage->dpb->flushed = 0;
}
else
{
h264bsdFlushDpb(pStorage->dpb);
}
pStorage->oldSpsId = pStorage->activeSpsId;
pStorage->picStarted = HANTRO_FALSE;
return (H264BSD_HDRS_RDY);
}
if(pStorage->activePps->numSliceGroups != 1 &&
!pDecCont->rlcMode)
{
pDecCont->reallocate = 1;
pDecCont->tryVlc = 0;
pStorage->picStarted = HANTRO_FALSE;
*readBytes = 0;
return (H264BSD_FMO);
}
if(pStorage->activePps->numSliceGroups == 1 &&
pDecCont->rlcMode && !pStorage->asoDetected)
{
if(pDecCont->forceRlcMode)
pDecCont->tryVlc = 0;
else
{
DEBUG_PRINT(("h264bsdDecode: no FMO/ASO detected, switch to VLC\n"));
pDecCont->tryVlc = 1;
/* we have removed emulation prevevention 3B from stream,
* cannot go to VLC for this frame; but try the
* next one */
/* pDecCont->rlcMode = 0; */
}
}
}
tmp = h264bsdDecodeSliceHeader(&strm, pStorage->sliceHeader + 1,
pStorage->activeSps,
pStorage->activePps, &nalUnit);
if(tmp != HANTRO_OK)
{
ERROR_PRINT("SLICE_HEADER");
ret = H264BSD_ERROR;
goto NEXT_NAL;
}
if(h264bsdIsStartOfPicture(pStorage))
{
tmp = pStorage->secondField;
if(h264bsdIsOppositeFieldPic(pStorage->sliceHeader + 1,
pStorage->sliceHeader + 0,
&pStorage->secondField,
pStorage->dpb->prevRefFrameNum,
pStorage->aub->newPicture))
{
/* TODO: make sure that currentOut->status[field] is
* EMPTY */
if(pStorage->dpb->delayedOut != 0)
{
/* we delayed the output while waiting for second field */
pStorage->dpb->outBuf[pStorage->dpb->delayedId].fieldPicture = 0; /* mark both fields available */
DEBUG_PRINT(("Second field coming...\n"));
}
}
else
{
if(pStorage->dpb->delayedOut != 0 ||
/* missing field and PP running */
(tmp && pDecCont->pp.decPpIf.ppStatus == DECPP_PIC_NOT_FINISHED))
{
pStorage->secondField = 0;
DEBUG_PRINT(("Second field missing...Output delayed stuff\n"));
*readBytes = 0;
pStorage->prevBufNotFinished = HANTRO_TRUE;
pStorage->dpb->delayedOut = 0;
pStorage->checkedAub = 1;
return (H264BSD_UNPAIRED_FIELD);
}
if(!IS_IDR_NAL_UNIT(&nalUnit) &&
!pDecCont->modeChange && !pDecCont->gapsCheckedForThis)
{
DEBUG_PRINT(("Check gaps in frame num; mode change %d\n",
pDecCont->modeChange));
tmp = h264bsdCheckGapsInFrameNum(pStorage->dpb,
pStorage->
sliceHeader[1].
frameNum,
nalUnit.nalRefIdc !=
0 ? HANTRO_TRUE :
HANTRO_FALSE,
pStorage->activeSps->
gapsInFrameNumValueAllowedFlag);
pDecCont->gapsCheckedForThis = HANTRO_TRUE;
if(tmp != HANTRO_OK)
{
pDecCont->gapsCheckedForThis = HANTRO_FALSE;
ERROR_PRINT("Gaps in frame num");
ret = H264BSD_ERROR;
goto NEXT_NAL;
}
}
pStorage->currImage->data =
h264bsdAllocateDpbImage(pStorage->dpb);
#ifdef SET_EMPTY_PICTURE_DATA /* USE THIS ONLY FOR DEBUGGING PURPOSES */
{
i32 bgd = SET_EMPTY_PICTURE_DATA;
DWLmemset(pStorage->currImage->data->virtualAddress,
bgd, pStorage->currImage->data->size);
}
#endif
}
}
else
{
if(!pDecCont->rlcMode &&
pStorage->sliceHeader[1].redundantPicCnt != 0)
{
ret = H264BSD_RDY;
goto NEXT_NAL;
}
}
DEBUG_PRINT(("vali slice TRUE\n"));
/* store slice header to storage if successfully decoded */
pStorage->sliceHeader[0] = pStorage->sliceHeader[1];
pStorage->validSliceInAccessUnit = HANTRO_TRUE;
pStorage->prevNalUnit[0] = nalUnit;
if(IS_B_SLICE(pStorage->sliceHeader[1].sliceType))
{
if((pDecCont->h264ProfileSupport == H264_BASELINE_PROFILE) ||
(pDecCont->rlcMode != 0))
{
ERROR_PRINT("B_SLICE not allowed in baseline decoder");
ret = H264BSD_ERROR;
goto NEXT_NAL;
}
if(pDecCont->asicBuff->enableDmvAndPoc == 0)
{
DEBUG_PRINT(("B_SLICE in baseline stream!!! DMV and POC writing were not enabled!"));
DEBUG_PRINT(("B_SLICE decoding will not be accurate for a while!"));
/* enable DMV and POC writing */
pDecCont->asicBuff->enableDmvAndPoc = 1;
}
}
/* For VLC mode, end SW decode here */
if(!pDecCont->rlcMode)
{
DEBUG_PRINT(("\tVLC mode! Skip slice data decoding\n"));
if(pDecCont->is8190 == 0)
{
h264bsdInitRefPicList(pStorage->dpb);
}
SetPicNums(pStorage->dpb, pStorage->sliceHeader->frameNum);
return (H264BSD_PIC_RDY);
}
/* TODO pit<69>sk<73> siirt<72><74> pelk<6C>st<73><74>n rlc moodille, note that
* SetPicNums called only inside h264bsdReorderRefPicList() */
h264bsdInitRefPicList(pStorage->dpb);
tmp = h264bsdReorderRefPicList(pStorage->dpb,
&pStorage->sliceHeader->
refPicListReordering,
pStorage->sliceHeader->frameNum,
pStorage->sliceHeader->
numRefIdxL0Active);
if(tmp != HANTRO_OK)
{
ERROR_PRINT("h264bsdReorderRefPicList failed\n");
ret = H264BSD_ERROR;
goto NEXT_NAL;
}
h264bsdComputeSliceGroupMap(pStorage,
pStorage->sliceHeader->
sliceGroupChangeCycle);
tmp = h264bsdDecodeSliceData(pDecCont, &strm,
pStorage->sliceHeader);
if(tmp != HANTRO_OK)
{
h264bsdMarkSliceCorrupted(pStorage,
pStorage->sliceHeader->
firstMbInSlice);
return (H264BSD_ERROR);
}
if(h264bsdIsEndOfPicture(pStorage))
{
picReady = HANTRO_TRUE;
DEBUG_PRINT(("Skip redundant RLC\n"));
pStorage->skipRedundantSlices = HANTRO_TRUE;
}
break;
case NAL_SEI:
DEBUG_PRINT(("SEI MESSAGE, NOT DECODED\n"));
ret = H264BSD_RDY;
goto NEXT_NAL;
case NAL_END_OF_SEQUENCE:
DEBUG_PRINT(("END_OF_SEQUENCE, NOT DECODED\n"));
ret = H264BSD_RDY;
goto NEXT_NAL;
case NAL_END_OF_STREAM:
DEBUG_PRINT(("END_OF_STREAM, NOT DECODED\n"));
ret = H264BSD_RDY;
goto NEXT_NAL;
default:
DEBUG_PRINT(("NOT IMPLEMENTED YET %d\n", nalUnit.nalUnitType));
ret = H264BSD_RDY;
goto NEXT_NAL;
}
}
if(picReady)
{
return (H264BSD_PIC_RDY);
}
else
return (H264BSD_RDY);
NEXT_NAL:
if(!pDecCont->rlcMode)
{
const u8 *next =
h264bsdFindNextStartCode(strm.pStrmBuffStart, strm.strmBuffSize);
if(next != NULL)
{
*readBytes = (u32) (next - byteStrm);
pStorage->prevBytesConsumed = *readBytes;
}
}
return ret;
}
/*------------------------------------------------------------------------------
Function: h264bsdShutdown
Functional description:
Shutdown a decoder instance. Function frees all the memories
allocated for the decoder instance.
Inputs:
pStorage pointer to storage data structure
Returns:
none
------------------------------------------------------------------------------*/
void h264bsdShutdown(storage_t * pStorage)
{
/* Variables */
u32 i;
/* Code */
ASSERT(pStorage);
for(i = 0; i < MAX_NUM_SEQ_PARAM_SETS; i++)
{
if(pStorage->sps[i])
{
FREE(pStorage->sps[i]->offsetForRefFrame);
FREE(pStorage->sps[i]->vuiParameters);
FREE(pStorage->sps[i]);
}
}
for(i = 0; i < MAX_NUM_PIC_PARAM_SETS; i++)
{
if(pStorage->pps[i])
{
FREE(pStorage->pps[i]->runLength);
FREE(pStorage->pps[i]->topLeft);
FREE(pStorage->pps[i]->bottomRight);
FREE(pStorage->pps[i]->sliceGroupId);
FREE(pStorage->pps[i]);
}
}
FREE(pStorage->mb);
FREE(pStorage->sliceGroupMap);
}
/*------------------------------------------------------------------------------
Function: h264bsdNextOutputPicture
Functional description:
Get next output picture in display order.
Inputs:
pStorage pointer to storage data structure
Returns:
pointer to the picture data
NULL if no pictures available for display
------------------------------------------------------------------------------*/
const dpbOutPicture_t *h264bsdNextOutputPicture(storage_t * pStorage)
{
/* Variables */
const dpbOutPicture_t *pOut;
/* Code */
ASSERT(pStorage);
pOut = h264bsdDpbOutputPicture(pStorage->dpb);
/* store pointer to alternate chroma output if needed */
if (pStorage->enable2ndChroma && pOut &&
(!pStorage->activeSps || !pStorage->activeSps->monoChrome))
{
pStorage->pCh2 =
(u32*)pOut->data->virtualAddress + pStorage->dpb->ch2Offset;
pStorage->bCh2 = pOut->data->busAddress + pStorage->dpb->ch2Offset;
}
else
{
pStorage->pCh2 = NULL;
pStorage->bCh2 = 0;
}
return pOut;
}
/*------------------------------------------------------------------------------
Function: h264bsdPicWidth
Functional description:
Get width of the picture in macroblocks
Inputs:
pStorage pointer to storage data structure
Outputs:
none
Returns:
picture width
0 if parameters sets not yet activated
------------------------------------------------------------------------------*/
u32 h264bsdPicWidth(storage_t * pStorage)
{
/* Variables */
/* Code */
ASSERT(pStorage);
if(pStorage->activeSps)
return (pStorage->activeSps->picWidthInMbs);
else
return (0);
}
/*------------------------------------------------------------------------------
Function: h264bsdPicHeight
Functional description:
Get height of the picture in macroblocks
Inputs:
pStorage pointer to storage data structure
Outputs:
none
Returns:
picture width
0 if parameters sets not yet activated
------------------------------------------------------------------------------*/
u32 h264bsdPicHeight(storage_t * pStorage)
{
/* Variables */
/* Code */
ASSERT(pStorage);
if(pStorage->activeSps)
return (pStorage->activeSps->picHeightInMbs);
else
return (0);
}
/*------------------------------------------------------------------------------
Function: h264bsdIsMonoChrome
Functional description:
Inputs:
pStorage pointer to storage data structure
Outputs:
Returns:
------------------------------------------------------------------------------*/
u32 h264bsdIsMonoChrome(storage_t * pStorage)
{
/* Variables */
/* Code */
ASSERT(pStorage);
if(pStorage->activeSps)
return (pStorage->activeSps->monoChrome);
else
return (0);
}
/*------------------------------------------------------------------------------
Function: h264bsdFlushBuffer
Functional description:
Flush the decoded picture buffer, see dpb.c for details
Inputs:
pStorage pointer to storage data structure
------------------------------------------------------------------------------*/
void h264bsdFlushBuffer(storage_t * pStorage)
{
/* Variables */
/* Code */
ASSERT(pStorage);
h264bsdFlushDpb(pStorage->dpb);
}
/*------------------------------------------------------------------------------
Function: h264bsdCheckValidParamSets
Functional description:
Check if any valid parameter set combinations (SPS/PPS) exists.
Inputs:
pStorage pointer to storage structure
Returns:
1 at least one valid SPS/PPS combination found
0 no valid param set combinations found
------------------------------------------------------------------------------*/
u32 h264bsdCheckValidParamSets(storage_t * pStorage)
{
/* Variables */
/* Code */
ASSERT(pStorage);
return (h264bsdValidParamSets(pStorage) == HANTRO_OK ? 1 : 0);
}
/*------------------------------------------------------------------------------
Function: h264bsdAspectRatioIdc
Functional description:
Get value of aspect_ratio_idc received in the VUI data
Inputs:
pStorage pointer to storage structure
Outputs:
value of aspect_ratio_idc if received
0 otherwise (this is the default value)
------------------------------------------------------------------------------*/
u32 h264bsdAspectRatioIdc(const storage_t * pStorage)
{
/* Variables */
const seqParamSet_t *sps;
/* Code */
ASSERT(pStorage);
sps = pStorage->activeSps;
if(sps && sps->vuiParametersPresentFlag &&
sps->vuiParameters->aspectRatioPresentFlag)
return (sps->vuiParameters->aspectRatioIdc);
else /* default unspecified */
return (0);
}
/*------------------------------------------------------------------------------
Function: h264bsdSarSize
Functional description:
Get value of sample_aspect_ratio size received in the VUI data
Inputs:
pStorage pointer to storage structure
Outputs:
values of sample_aspect_ratio size if received
0 otherwise (this is the default value)
------------------------------------------------------------------------------*/
void h264bsdSarSize(const storage_t * pStorage, u32 * sar_width,
u32 * sar_height)
{
/* Variables */
const seqParamSet_t *sps;
/* Code */
ASSERT(pStorage);
sps = pStorage->activeSps;
if(sps && pStorage->activeSps->vuiParametersPresentFlag &&
sps->vuiParameters->aspectRatioPresentFlag &&
sps->vuiParameters->aspectRatioIdc == 255)
{
*sar_width = sps->vuiParameters->sarWidth;
*sar_height = sps->vuiParameters->sarHeight;
}
else
{
*sar_width = 0;
*sar_height = 0;
}
}
/*------------------------------------------------------------------------------
Function: h264bsdVideoRange
Functional description:
Get value of video_full_range_flag received in the VUI data.
Inputs:
pStorage pointer to storage structure
Returns:
1 video_full_range_flag received and value is 1
0 otherwise
------------------------------------------------------------------------------*/
u32 h264bsdVideoRange(storage_t * pStorage)
{
/* Variables */
const seqParamSet_t *sps;
/* Code */
ASSERT(pStorage);
sps = pStorage->activeSps;
if(sps && sps->vuiParametersPresentFlag &&
sps->vuiParameters->videoSignalTypePresentFlag &&
sps->vuiParameters->videoFullRangeFlag)
return (1);
else /* default value of video_full_range_flag is 0 */
return (0);
}
/*------------------------------------------------------------------------------
Function: h264bsdMatrixCoefficients
Functional description:
Get value of matrix_coefficients received in the VUI data
Inputs:
pStorage pointer to storage structure
Outputs:
value of matrix_coefficients if received
2 otherwise (this is the default value)
------------------------------------------------------------------------------*/
u32 h264bsdMatrixCoefficients(storage_t * pStorage)
{
/* Variables */
const seqParamSet_t *sps;
/* Code */
ASSERT(pStorage);
sps = pStorage->activeSps;
if(sps && sps->vuiParametersPresentFlag &&
sps->vuiParameters->videoSignalTypePresentFlag &&
sps->vuiParameters->colourDescriptionPresentFlag)
return (sps->vuiParameters->matrixCoefficients);
else /* default unspecified */
return (2);
}
/*------------------------------------------------------------------------------
Function: hh264bsdCroppingParams
Functional description:
Get cropping parameters of the active SPS
Inputs:
pStorage pointer to storage structure
Outputs:
croppingFlag flag indicating if cropping params present is
stored here
leftOffset cropping left offset in pixels is stored here
width width of the image after cropping is stored here
topOffset cropping top offset in pixels is stored here
height height of the image after cropping is stored here
Returns:
none
------------------------------------------------------------------------------*/
void h264bsdCroppingParams(storage_t * pStorage, u32 * croppingFlag,
u32 * leftOffset, u32 * width, u32 * topOffset,
u32 * height)
{
/* Variables */
const seqParamSet_t *sps;
u32 tmp1, tmp2;
/* Code */
ASSERT(pStorage);
sps = pStorage->activeSps;
if(sps && sps->frameCroppingFlag)
{
tmp1 = sps->monoChrome ? 1 : 2;
tmp2 = sps->frameMbsOnlyFlag ? 1 : 2;
*croppingFlag = 1;
*leftOffset = tmp1 * sps->frameCropLeftOffset;
*width = 16 * sps->picWidthInMbs -
tmp1 * (sps->frameCropLeftOffset + sps->frameCropRightOffset);
*topOffset = tmp1 * tmp2 * sps->frameCropTopOffset;
*height = 16 * sps->picHeightInMbs -
tmp1 * tmp2 * (sps->frameCropTopOffset +
sps->frameCropBottomOffset);
}
else
{
*croppingFlag = 0;
*leftOffset = 0;
*width = 0;
*topOffset = 0;
*height = 0;
}
}