Merge pull request #323 from huili2/check_bit_read

add safety check for bit-reading for headers
This commit is contained in:
Licai Guo 2014-02-20 14:17:07 +08:00
commit 46b9d5d0da
7 changed files with 657 additions and 469 deletions

View File

@ -88,13 +88,13 @@ uint8_t* ParseNalHeader (PWelsDecoderContext pCtx, SNalUnitHeader* pNalUnitHeade
int32_t ParseNonVclNal (PWelsDecoderContext pCtx, uint8_t* pRbsp, const int32_t kiSrcLen);
void ParseRefBasePicMarking (PBitStringAux pBs, PRefBasePicMarking pRefBasePicMarking);
int32_t ParseRefBasePicMarking (PBitStringAux pBs, PRefBasePicMarking pRefBasePicMarking);
void ParsePrefixNalUnit (PWelsDecoderContext pCtx, PBitStringAux pBs);
int32_t ParsePrefixNalUnit (PWelsDecoderContext pCtx, PBitStringAux pBs);
bool CheckAccessUnitBoundary (const PNalUnit kpCurNal, const PNalUnit kpLastNal, const PSps kpSps);
bool CheckAccessUnitBoundaryExt (PNalUnitHeaderExt pLastNalHdrExt, PNalUnitHeaderExt pCurNalHeaderExt,
PSliceHeader pLastSliceHeader, PSliceHeader pCurSliceHeader);
PSliceHeader pLastSliceHeader, PSliceHeader pCurSliceHeader);
/*!
*************************************************************************************
* \brief to parse Sequence Parameter Set (SPS)

View File

@ -45,36 +45,41 @@
#include "macros.h"
//#include <assert.h>
#include "ls_defines.h"
#include "error_code.h"
namespace WelsDec {
#define GET_WORD(iCurBits, pBufPtr, iLeftBits) { \
#define WELS_READ_VERIFY(uiRet) { \
if( uiRet != ERR_NONE ) \
return uiRet; \
}
#define GET_WORD(iCurBits, pBufPtr, iLeftBits, iAllowedBytes, iReadBytes) { \
if (iReadBytes > iAllowedBytes+1) { \
return ERR_INFO_READ_OVERFLOW; \
} \
iCurBits |= ((pBufPtr[0] << 8) | pBufPtr[1]) << (iLeftBits); \
iLeftBits -= 16; \
pBufPtr +=2; \
}
#define NEED_BITS(iCurBits, pBufPtr, iLeftBits) { \
#define NEED_BITS(iCurBits, pBufPtr, iLeftBits, iAllowedBytes, iReadBytes) { \
if( iLeftBits > 0 ) { \
GET_WORD(iCurBits, pBufPtr, iLeftBits); \
GET_WORD(iCurBits, pBufPtr, iLeftBits, iAllowedBytes, iReadBytes); \
} \
}
#define UBITS(iCurBits, iNumBits) (iCurBits>>(32-(iNumBits)))
#define DUMP_BITS(iCurBits, pBufPtr, iLeftBits, iNumBits) { \
#define DUMP_BITS(iCurBits, pBufPtr, iLeftBits, iNumBits, iAllowedBytes, iReadBytes) { \
iCurBits <<= (iNumBits); \
iLeftBits += (iNumBits); \
NEED_BITS(iCurBits, pBufPtr, iLeftBits); \
NEED_BITS(iCurBits, pBufPtr, iLeftBits, iAllowedBytes, iReadBytes); \
}
static inline int32_t ShowBits (PBitStringAux pBs, int32_t iNumBits) {
return UBITS (pBs->uiCurBits, iNumBits);
}
static inline void FlushBits (PBitStringAux pBs, int32_t iNumBits) {
DUMP_BITS (pBs->uiCurBits, pBs->pCurBuf, pBs->iLeftBits, iNumBits);
}
static inline int32_t BsGetBits (PBitStringAux pBs, int32_t iNumBits) {
int32_t iRc = UBITS (pBs->uiCurBits, iNumBits);
DUMP_BITS (pBs->uiCurBits, pBs->pCurBuf, pBs->iLeftBits, iNumBits);
return iRc;
static inline int32_t BsGetBits (PBitStringAux pBs, int32_t iNumBits, uint32_t* pCode) {
int32_t iRc = UBITS (pBs->uiCurBits, iNumBits);
int32_t iAllowedBytes = pBs->pEndBuf - pBs->pStartBuf; //actual stream bytes
int32_t iReadBytes = pBs->pCurBuf - pBs->pStartBuf;
DUMP_BITS (pBs->uiCurBits, pBs->pCurBuf, pBs->iLeftBits, iNumBits, iAllowedBytes, iReadBytes);
*pCode = iRc;
return ERR_NONE;
}
/*
@ -88,110 +93,123 @@ extern const uint8_t g_kuiInterCbpTable[48];
extern const uint8_t g_kuiLeadingZeroTable[256];
static const uint32_t g_kuiPrefix8BitsTable[16] = {
0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3
0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3
};
static inline uint32_t GetPrefixBits (uint32_t uiValue) {
uint32_t iNumBit = 0;
uint32_t iNumBit = 0;
if (uiValue & 0xffff0000) {
uiValue >>= 16;
iNumBit += 16;
}
if (uiValue & 0xff00) {
uiValue >>= 8;
iNumBit += 8;
}
if (uiValue & 0xffff0000) {
uiValue >>= 16;
iNumBit += 16;
}
if (uiValue & 0xff00) {
uiValue >>= 8;
iNumBit += 8;
}
if (uiValue & 0xf0) {
uiValue >>= 4;
iNumBit += 4;
}
iNumBit += g_kuiPrefix8BitsTable[uiValue];
if (uiValue & 0xf0) {
uiValue >>= 4;
iNumBit += 4;
}
iNumBit += g_kuiPrefix8BitsTable[uiValue];
return (32 - iNumBit);
return (32 - iNumBit);
}
/*
* Read one bit from bit stream followed
*/
static inline uint32_t BsGetOneBit (PBitStringAux pBs) {
return (BsGetBits (pBs, 1));
static inline uint32_t BsGetOneBit (PBitStringAux pBs, uint32_t* pCode) {
return (BsGetBits (pBs, 1, pCode));
}
static inline int32_t GetLeadingZeroBits (uint32_t iCurBits) { //<=16 bits
int32_t iValue;
static inline int32_t GetLeadingZeroBits (uint32_t iCurBits) { //<=32 bits
uint32_t uiValue;
iValue = UBITS (iCurBits, 8); //ShowBits( bs, 8 );
if (iValue) {
return g_kuiLeadingZeroTable[iValue];
}
uiValue = UBITS (iCurBits, 8); //ShowBits( bs, 8 );
if (uiValue) {
return g_kuiLeadingZeroTable[uiValue];
}
iValue = UBITS (iCurBits, 16); //ShowBits( bs, 16 );
if (iValue) {
return (g_kuiLeadingZeroTable[iValue] + 8);
}
uiValue = UBITS (iCurBits, 16); //ShowBits( bs, 16 );
if (uiValue) {
return (g_kuiLeadingZeroTable[uiValue] + 8);
}
uiValue = UBITS (iCurBits, 24); //ShowBits( bs, 24 );
if (uiValue) {
return (g_kuiLeadingZeroTable[uiValue] + 16);
}
uiValue = iCurBits; //ShowBits( bs, 32 );
if (uiValue) {
return (g_kuiLeadingZeroTable[uiValue] + 24);
}
//ASSERT(false); // should not go here
return -1;
return -1;
}
static inline uint32_t BsGetUe (PBitStringAux pBs) {
uint32_t iValue = 0;
int32_t iLeadingZeroBits = GetLeadingZeroBits (pBs->uiCurBits);
static inline uint32_t BsGetUe (PBitStringAux pBs, uint32_t* pCode) {
uint32_t iValue = 0;
int32_t iLeadingZeroBits = GetLeadingZeroBits (pBs->uiCurBits);
int32_t iAllowedBytes, iReadBytes;
iAllowedBytes = pBs->pEndBuf - pBs->pStartBuf; //actual stream bytes
if (iLeadingZeroBits == -1) { //bistream error
return 0xffffffff;//-1
}
if (iLeadingZeroBits == -1) { //bistream error
return ERR_INFO_READ_LEADING_ZERO;//-1
} else if (iLeadingZeroBits >
16) { //rarely into this condition (even may be bitstream error), prevent from 16-bit reading overflow
//using two-step reading instead of one time reading of >16 bits.
iReadBytes = pBs->pCurBuf - pBs->pStartBuf;
DUMP_BITS (pBs->uiCurBits, pBs->pCurBuf, pBs->iLeftBits, 16, iAllowedBytes, iReadBytes);
iReadBytes = pBs->pCurBuf - pBs->pStartBuf;
DUMP_BITS (pBs->uiCurBits, pBs->pCurBuf, pBs->iLeftBits, iLeadingZeroBits + 1 - 16, iAllowedBytes, iReadBytes);
} else {
iReadBytes = pBs->pCurBuf - pBs->pStartBuf;
DUMP_BITS (pBs->uiCurBits, pBs->pCurBuf, pBs->iLeftBits, iLeadingZeroBits + 1, iAllowedBytes, iReadBytes);
}
if (iLeadingZeroBits) {
iValue = UBITS (pBs->uiCurBits, iLeadingZeroBits);
iReadBytes = pBs->pCurBuf - pBs->pStartBuf;
DUMP_BITS (pBs->uiCurBits, pBs->pCurBuf, pBs->iLeftBits, iLeadingZeroBits, iAllowedBytes, iReadBytes);
}
DUMP_BITS (pBs->uiCurBits, pBs->pCurBuf, pBs->iLeftBits, iLeadingZeroBits + 1);
if (iLeadingZeroBits) {
iValue = UBITS (pBs->uiCurBits, iLeadingZeroBits);
DUMP_BITS (pBs->uiCurBits, pBs->pCurBuf, pBs->iLeftBits, iLeadingZeroBits);
}
return ((1 << iLeadingZeroBits) - 1 + iValue);
*pCode = ((1 << iLeadingZeroBits) - 1 + iValue);
return ERR_NONE;
}
/*
* Read signed exp golomb codes
*/
static inline int32_t BsGetSe (PBitStringAux pBs) {
uint32_t uiCodeNum;
static inline int32_t BsGetSe (PBitStringAux pBs, int32_t* pCode) {
uint32_t uiCodeNum;
uiCodeNum = BsGetUe (pBs);
WELS_READ_VERIFY (BsGetUe (pBs, &uiCodeNum));
if (uiCodeNum & 0x01) {
return (int32_t) ((uiCodeNum + 1) >> 1);
} else {
return NEG_NUM ((int32_t) (uiCodeNum >> 1));
}
}
/*
* Read truncated exp golomb codes
*/
static inline uint32_t BsGetTe (PBitStringAux pBs, uint8_t uiRange) {
if (1 == uiRange) {
return BsGetOneBit (pBs) ^ 1;
} else {
return BsGetUe (pBs);
}
if (uiCodeNum & 0x01) {
*pCode = (int32_t) ((uiCodeNum + 1) >> 1);
} else {
*pCode = NEG_NUM ((int32_t) (uiCodeNum >> 1));
}
return ERR_NONE;
}
/*
* Get unsigned truncated exp golomb code.
*/
static inline int32_t BsGetTe0 (PBitStringAux pBs, int32_t iRange) {
if (iRange == 1)
return 0;
else if (iRange == 2)
return BsGetOneBit (pBs) ^ 1;
else
return BsGetUe (pBs);
static inline int32_t BsGetTe0 (PBitStringAux pBs, int32_t iRange, uint32_t* pCode) {
if (iRange == 1) {
*pCode = 0;
} else if (iRange == 2) {
WELS_READ_VERIFY (BsGetOneBit (pBs, pCode));
*pCode ^= 1;
} else {
WELS_READ_VERIFY (BsGetUe (pBs, pCode));
}
return ERR_NONE;
}
/*
@ -199,17 +217,17 @@ else
*/
static inline int32_t BsGetTrailingBits (uint8_t* pBuf) {
// TODO
uint32_t uiValue = *pBuf;
int32_t iRetNum = 1;
uint32_t uiValue = *pBuf;
int32_t iRetNum = 1;
do {
if (uiValue & 1)
return iRetNum;
uiValue >>= 1;
++ iRetNum;
} while (iRetNum < 9);
do {
if (uiValue & 1)
return iRetNum;
uiValue >>= 1;
++ iRetNum;
} while (iRetNum < 9);
return 0;
return 0;
}
//define macros to check syntax elements
#define WELS_CHECK_SE_BOTH_ERROR(val, lower_bound, upper_bound, syntax_name, ret_code) do {\

View File

@ -43,12 +43,12 @@
namespace WelsDec {
typedef enum TagWelsErr {
ERR_NONE = 0,
ERR_INVALID_PARAMETERS = 1,
ERR_MALLOC_FAILED = 2,
ERR_API_FAILED = 3,
ERR_NONE = 0,
ERR_INVALID_PARAMETERS = 1,
ERR_MALLOC_FAILED = 2,
ERR_API_FAILED = 3,
ERR_BOUND = 31,
ERR_BOUND = 31,
} EWelsErr;
/*
@ -62,13 +62,13 @@ ERR_BOUND = 31,
/* ERR_LEVEL */
//-----------------------------------------------------------------------------------------------------------
enum {
ERR_LEVEL_ACCESS_UNIT = 1,
ERR_LEVEL_NAL_UNIT_HEADER,
ERR_LEVEL_PREFIX_NAL,
ERR_LEVEL_PARAM_SETS,
ERR_LEVEL_SLICE_HEADER,
ERR_LEVEL_SLICE_DATA,
ERR_LEVEL_MB_DATA,
ERR_LEVEL_ACCESS_UNIT = 1,
ERR_LEVEL_NAL_UNIT_HEADER,
ERR_LEVEL_PREFIX_NAL,
ERR_LEVEL_PARAM_SETS,
ERR_LEVEL_SLICE_HEADER,
ERR_LEVEL_SLICE_DATA,
ERR_LEVEL_MB_DATA,
};
//-----------------------------------------------------------------------------------------------------------
@ -79,102 +79,104 @@ ERR_LEVEL_MB_DATA,
#define ERR_INFO_SYNTAX_BASE 1001
#define ERR_INFO_LOGIC_BASE 10001
enum {
/* Error from common system level: 1-1000 */
ERR_INFO_OUT_OF_MEMORY = ERR_INFO_COMMON_BASE,
ERR_INFO_INVALID_ACCESS,
ERR_INFO_INVALID_PTR,
ERR_INFO_INVALID_PARAM,
ERR_INFO_FILE_NO_FOUND,
ERR_INFO_PATH_NO_FOUND,
ERR_INFO_ACCESS_DENIED,
ERR_INFO_NOT_READY,
ERR_INFO_WRITE_FAULT,
ERR_INFO_READ_FAULT,
/* Error from H.264 syntax elements parser: 1001-10000 */
ERR_INFO_NO_PREFIX_CODE = ERR_INFO_SYNTAX_BASE, // No start prefix code indication
ERR_INFO_NO_PARAM_SETS, // No SPS and/ PPS before sequence header
ERR_INFO_PARAM_SETS_NOT_INTEGRATED, // Parameters sets (sps/pps) are not integrated at all before to decode VCL nal
ERR_INFO_SPS_ID_OVERFLOW,
ERR_INFO_PPS_ID_OVERFLOW,
ERR_INFO_INVALID_PROFILE_IDC,
ERR_INFO_UNMATCHED_LEVEL_IDC,
ERR_INFO_INVALID_POC_TYPE,
ERR_INFO_INVALID_MB_SIZE_INFO,
ERR_INFO_REF_COUNT_OVERFLOW,
ERR_INFO_CROPPING_NO_SUPPORTED,
ERR_INFO_INVALID_SLICEGROUP,
ERR_INFO_INVALID_SLICEGROUP_MAP_TYPE,
ERR_INFO_INVALID_FRAME_NUM,
ERR_INFO_INVALID_IDR_PIC_ID,
ERR_INFO_INVALID_REDUNDANT_PIC_CNT,
ERR_INFO_INVALID_MAX_NUM_REF_FRAMES,
ERR_INFO_INVALID_FIRST_MB_IN_SLICE,
ERR_INFO_INVALID_NUM_REF_IDX_L0_ACTIVE_MINUS1,
ERR_INFO_INVALID_SLICE_ALPHA_C0_OFFSET_DIV2,
ERR_INFO_INVALID_SLICE_BETA_OFFSET_DIV2,
ERR_INFO_FMO_INIT_FAIL,
ERR_INFO_SLICE_TYPE_OVERFLOW,
ERR_INFO_INVALID_QP,
ERR_INFO_INVALID_PIC_INIT_QS,
ERR_INFO_INVALID_CHROMA_QP_INDEX_OFFSET,
ERR_INFO_INVALID_PIC_INIT_QP,
ERR_INFO_INVALID_LOG2_MAX_FRAME_NUM_MINUS4,
ERR_INFO_INVALID_LOG2_MAX_PIC_ORDER_CNT_LSB_MINUS4,
ERR_INFO_INVALID_NUM_REF_FRAME_IN_PIC_ORDER_CNT_CYCLE,
ERR_INFO_INVALID_DBLOCKING_IDC,
ERR_INFO_INVALID_MB_TYPE,
ERR_INFO_INVALID_SUB_MB_TYPE,
ERR_INFO_UNAVAILABLE_TOP_BLOCK_FOR_INTRA,
ERR_INFO_UNAVAILABLE_LEFT_BLOCK_FOR_INTRA,
ERR_INFO_INVALID_REF_INDEX,
ERR_INFO_INVALID_CBP,
ERR_INFO_DQUANT_OUT_OF_RANGE,
ERR_INFO_CAVLC_INVALID_PREFIX,
ERR_INFO_CAVLC_INVALID_TOTAL_COEFF_OR_TRAILING_ONES,
ERR_INFO_CAVLC_INVALID_ZERO_LEFT,
ERR_INFO_CAVLC_INVALID_RUN_BEFORE,
ERR_INFO_MV_OUT_OF_RANGE,
/* Error from common system level: 1-1000 */
ERR_INFO_OUT_OF_MEMORY = ERR_INFO_COMMON_BASE,
ERR_INFO_INVALID_ACCESS,
ERR_INFO_INVALID_PTR,
ERR_INFO_INVALID_PARAM,
ERR_INFO_FILE_NO_FOUND,
ERR_INFO_PATH_NO_FOUND,
ERR_INFO_ACCESS_DENIED,
ERR_INFO_NOT_READY,
ERR_INFO_WRITE_FAULT,
ERR_INFO_READ_FAULT,
ERR_INFO_READ_OVERFLOW,
ERR_INFO_READ_LEADING_ZERO,
/* Error from H.264 syntax elements parser: 1001-10000 */
ERR_INFO_NO_PREFIX_CODE = ERR_INFO_SYNTAX_BASE, // No start prefix code indication
ERR_INFO_NO_PARAM_SETS, // No SPS and/ PPS before sequence header
ERR_INFO_PARAM_SETS_NOT_INTEGRATED, // Parameters sets (sps/pps) are not integrated at all before to decode VCL nal
ERR_INFO_SPS_ID_OVERFLOW,
ERR_INFO_PPS_ID_OVERFLOW,
ERR_INFO_INVALID_PROFILE_IDC,
ERR_INFO_UNMATCHED_LEVEL_IDC,
ERR_INFO_INVALID_POC_TYPE,
ERR_INFO_INVALID_MB_SIZE_INFO,
ERR_INFO_REF_COUNT_OVERFLOW,
ERR_INFO_CROPPING_NO_SUPPORTED,
ERR_INFO_INVALID_SLICEGROUP,
ERR_INFO_INVALID_SLICEGROUP_MAP_TYPE,
ERR_INFO_INVALID_FRAME_NUM,
ERR_INFO_INVALID_IDR_PIC_ID,
ERR_INFO_INVALID_REDUNDANT_PIC_CNT,
ERR_INFO_INVALID_MAX_NUM_REF_FRAMES,
ERR_INFO_INVALID_FIRST_MB_IN_SLICE,
ERR_INFO_INVALID_NUM_REF_IDX_L0_ACTIVE_MINUS1,
ERR_INFO_INVALID_SLICE_ALPHA_C0_OFFSET_DIV2,
ERR_INFO_INVALID_SLICE_BETA_OFFSET_DIV2,
ERR_INFO_FMO_INIT_FAIL,
ERR_INFO_SLICE_TYPE_OVERFLOW,
ERR_INFO_INVALID_QP,
ERR_INFO_INVALID_PIC_INIT_QS,
ERR_INFO_INVALID_CHROMA_QP_INDEX_OFFSET,
ERR_INFO_INVALID_PIC_INIT_QP,
ERR_INFO_INVALID_LOG2_MAX_FRAME_NUM_MINUS4,
ERR_INFO_INVALID_LOG2_MAX_PIC_ORDER_CNT_LSB_MINUS4,
ERR_INFO_INVALID_NUM_REF_FRAME_IN_PIC_ORDER_CNT_CYCLE,
ERR_INFO_INVALID_DBLOCKING_IDC,
ERR_INFO_INVALID_MB_TYPE,
ERR_INFO_INVALID_SUB_MB_TYPE,
ERR_INFO_UNAVAILABLE_TOP_BLOCK_FOR_INTRA,
ERR_INFO_UNAVAILABLE_LEFT_BLOCK_FOR_INTRA,
ERR_INFO_INVALID_REF_INDEX,
ERR_INFO_INVALID_CBP,
ERR_INFO_DQUANT_OUT_OF_RANGE,
ERR_INFO_CAVLC_INVALID_PREFIX,
ERR_INFO_CAVLC_INVALID_TOTAL_COEFF_OR_TRAILING_ONES,
ERR_INFO_CAVLC_INVALID_ZERO_LEFT,
ERR_INFO_CAVLC_INVALID_RUN_BEFORE,
ERR_INFO_MV_OUT_OF_RANGE,
ERR_INFO_INVALID_I4x4_PRED_MODE,
ERR_INFO_INVALID_I16x16_PRED_MODE,
ERR_INFO_INVALID_I_CHROMA_PRED_MODE,
ERR_INFO_INVALID_I4x4_PRED_MODE,
ERR_INFO_INVALID_I16x16_PRED_MODE,
ERR_INFO_INVALID_I_CHROMA_PRED_MODE,
ERR_INFO_UNSUPPORTED_NON_BASELINE,
ERR_INFO_UNSUPPORTED_FMOTYPE,
ERR_INFO_UNSUPPORTED_MBAFF,
ERR_INFO_UNSUPPORTED_ILP,
ERR_INFO_UNSUPPORTED_CABAC_EL,
ERR_INFO_UNSUPPORTED_SPSI,
ERR_INFO_UNSUPPORTED_MGS,
ERR_INFO_UNSUPPORTED_BIPRED,
ERR_INFO_UNSUPPORTED_WP,
ERR_INFO_UNSUPPORTED_NON_BASELINE,
ERR_INFO_UNSUPPORTED_FMOTYPE,
ERR_INFO_UNSUPPORTED_MBAFF,
ERR_INFO_UNSUPPORTED_ILP,
ERR_INFO_UNSUPPORTED_CABAC_EL,
ERR_INFO_UNSUPPORTED_SPSI,
ERR_INFO_UNSUPPORTED_MGS,
ERR_INFO_UNSUPPORTED_BIPRED,
ERR_INFO_UNSUPPORTED_WP,
ERR_INFO_FRAMES_LOST,
ERR_INFO_DEPENDENCY_SPATIAL_LAYER_LOST,
ERR_INFO_DEPENDENCY_QUALIT_LAYER_LOST,
ERR_INFO_REFERENCE_PIC_LOST,
ERR_INFO_INVALID_REORDERING,
ERR_INFO_INVALID_MARKING,
ERR_INFO_FRAMES_LOST,
ERR_INFO_DEPENDENCY_SPATIAL_LAYER_LOST,
ERR_INFO_DEPENDENCY_QUALIT_LAYER_LOST,
ERR_INFO_REFERENCE_PIC_LOST,
ERR_INFO_INVALID_REORDERING,
ERR_INFO_INVALID_MARKING,
ERR_INFO_FMO_NOT_SUPPORTED_IN_BASE_LAYER,
ERR_INFO_INVALID_ESS,
ERR_INFO_INVALID_SLICE_TYPE,
ERR_INFO_INVALID_REF_MARKING,
ERR_INFO_INVALID_REF_REORDERING,
ERR_INFO_FMO_NOT_SUPPORTED_IN_BASE_LAYER,
ERR_INFO_INVALID_ESS,
ERR_INFO_INVALID_SLICE_TYPE,
ERR_INFO_INVALID_REF_MARKING,
ERR_INFO_INVALID_REF_REORDERING,
/* Error from corresponding logic, 10001-65535 */
ERR_INFO_NO_IDR_PIC = ERR_INFO_LOGIC_BASE, // NO IDR picture available before sequence header
ERR_INFO_EC_NO_NEIGHBOUR_MBS,
ERR_INFO_EC_UNEXPECTED_MB_TYPE,
ERR_INFO_EC_NO_ENOUGH_NEIGHBOUR_MBS,
/* Error from corresponding logic, 10001-65535 */
ERR_INFO_NO_IDR_PIC = ERR_INFO_LOGIC_BASE, // NO IDR picture available before sequence header
ERR_INFO_EC_NO_NEIGHBOUR_MBS,
ERR_INFO_EC_UNEXPECTED_MB_TYPE,
ERR_INFO_EC_NO_ENOUGH_NEIGHBOUR_MBS,
//for LTR
ERR_INFO_INVALID_MMCO_OPCODE_BASE,
ERR_INFO_INVALID_MMCO_SHORT2UNUSED,
EER_INFO_INVALID_MMCO_LONG2UNUSED,
ERR_INFO_INVALID_MMCO_SHOART2LONG,
ERR_INFO_INVALID_MMCO_REF_NUM_OVERFLOW,
ERR_INFO_INVALID_MMCO_REF_NUM_NOT_ENOUGH,
ERR_INFO_INVALID_MMCO_LONG_TERM_IDX_EXCEED_MAX,
ERR_INFO_INVALID_MMCO_OPCODE_BASE,
ERR_INFO_INVALID_MMCO_SHORT2UNUSED,
EER_INFO_INVALID_MMCO_LONG2UNUSED,
ERR_INFO_INVALID_MMCO_SHOART2LONG,
ERR_INFO_INVALID_MMCO_REF_NUM_OVERFLOW,
ERR_INFO_INVALID_MMCO_REF_NUM_NOT_ENOUGH,
ERR_INFO_INVALID_MMCO_LONG_TERM_IDX_EXCEED_MAX,
};
//-----------------------------------------------------------------------------------------------------------

View File

@ -363,7 +363,7 @@ uint8_t* ParseNalHeader (PWelsDecoderContext pCtx, SNalUnitHeader* pNalUnitHeade
bool CheckAccessUnitBoundaryExt (PNalUnitHeaderExt pLastNalHdrExt, PNalUnitHeaderExt pCurNalHeaderExt,
PSliceHeader pLastSliceHeader, PSliceHeader pCurSliceHeader) {
PSliceHeader pLastSliceHeader, PSliceHeader pCurSliceHeader) {
const PSps kpSps = pCurSliceHeader->pSps;
//Sub-clause 7.1.4.1.1 temporal_id
@ -559,13 +559,16 @@ int32_t ParseNonVclNal (PWelsDecoderContext pCtx, uint8_t* pRbsp, const int32_t
return iErr;
}
void ParseRefBasePicMarking (PBitStringAux pBs, PRefBasePicMarking pRefBasePicMarking) {
const bool kbAdaptiveMarkingModeFlag = !!BsGetOneBit (pBs);
int32_t ParseRefBasePicMarking (PBitStringAux pBs, PRefBasePicMarking pRefBasePicMarking) {
uint32_t uiCode;
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //adaptive_ref_base_pic_marking_mode_flag
const bool kbAdaptiveMarkingModeFlag = !!uiCode;
pRefBasePicMarking->bAdaptiveRefBasePicMarkingModeFlag = kbAdaptiveMarkingModeFlag;
if (kbAdaptiveMarkingModeFlag) {
int32_t iIdx = 0;
do {
const uint32_t kuiMmco = BsGetUe (pBs);
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //MMCO_base
const uint32_t kuiMmco = uiCode;
pRefBasePicMarking->mmco_base[iIdx].uiMmcoType = kuiMmco;
@ -573,31 +576,39 @@ void ParseRefBasePicMarking (PBitStringAux pBs, PRefBasePicMarking pRefBasePicMa
break;
if (kuiMmco == MMCO_SHORT2UNUSED) {
pRefBasePicMarking->mmco_base[iIdx].uiDiffOfPicNums = 1 + BsGetUe (pBs);
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //difference_of_base_pic_nums_minus1
pRefBasePicMarking->mmco_base[iIdx].uiDiffOfPicNums = 1 + uiCode;
pRefBasePicMarking->mmco_base[iIdx].iShortFrameNum = 0;
} else if (kuiMmco == MMCO_LONG2UNUSED) {
pRefBasePicMarking->mmco_base[iIdx].uiLongTermPicNum = BsGetUe (pBs);
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //long_term_base_pic_num
pRefBasePicMarking->mmco_base[iIdx].uiLongTermPicNum = uiCode;
}
++ iIdx;
} while (iIdx < MAX_MMCO_COUNT);
}
return ERR_NONE;
}
void ParsePrefixNalUnit (PWelsDecoderContext pCtx, PBitStringAux pBs) {
int32_t ParsePrefixNalUnit (PWelsDecoderContext pCtx, PBitStringAux pBs) {
PNalUnit pCurNal = &pCtx->sPrefixNal;
uint32_t uiCode;
if (pCurNal->sNalHeaderExt.sNalUnitHeader.uiNalRefIdc != 0) {
PNalUnitHeaderExt head_ext = &pCurNal->sNalHeaderExt;
PPrefixNalUnit sPrefixNal = &pCurNal->sNalData.sPrefixNal;
sPrefixNal->bStoreRefBasePicFlag = !!BsGetOneBit (pBs);
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //store_ref_base_pic_flag
sPrefixNal->bStoreRefBasePicFlag = !!uiCode;
if ((head_ext->bUseRefBasePicFlag || sPrefixNal->bStoreRefBasePicFlag) && !head_ext->bIdrFlag) {
ParseRefBasePicMarking (pBs, &sPrefixNal->sRefPicBaseMarking);
WELS_READ_VERIFY (ParseRefBasePicMarking (pBs, &sPrefixNal->sRefPicBaseMarking));
}
sPrefixNal->bPrefixNalUnitAdditionalExtFlag = !!BsGetOneBit (pBs);
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //additional_prefix_nal_unit_extension_flag
sPrefixNal->bPrefixNalUnitAdditionalExtFlag = uiCode;
if (sPrefixNal->bPrefixNalUnitAdditionalExtFlag) {
sPrefixNal->bPrefixNalUnitExtFlag = !!BsGetOneBit (pBs);
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //additional_prefix_nal_unit_extension_data_flag
sPrefixNal->bPrefixNalUnitExtFlag = !!uiCode;
}
}
return ERR_NONE;
}
#define SUBSET_SPS_SEQ_SCALED_REF_LAYER_LEFT_OFFSET_MIN -32768
@ -615,11 +626,15 @@ void ParsePrefixNalUnit (PWelsDecoderContext pCtx, PBitStringAux pBs) {
int32_t DecodeSpsSvcExt (PWelsDecoderContext pCtx, PSubsetSps pSpsExt, PBitStringAux pBs) {
PSpsSvcExt pExt = NULL;
uint8_t uiChromaArrayType = 1;
uint32_t uiCode;
int32_t iCode;
pExt = &pSpsExt->sSpsSvcExt;
pExt->bInterLayerDeblockingFilterCtrlPresentFlag = !!BsGetOneBit (pBs);
pExt->uiExtendedSpatialScalability = BsGetBits (pBs, 2);
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //inter_layer_deblocking_filter_control_present_flag
pExt->bInterLayerDeblockingFilterCtrlPresentFlag = !!uiCode;
WELS_READ_VERIFY (BsGetBits (pBs, 2, &uiCode)); //extended_spatial_scalability_idc
pExt->uiExtendedSpatialScalability = uiCode;
if (pExt->uiExtendedSpatialScalability > 2) {
WelsLog (pCtx, WELS_LOG_WARNING, "DecodeSpsSvcExt():extended_spatial_scalability (%d) != 0, ESS not supported!\n",
pExt->uiExtendedSpatialScalability);
@ -631,8 +646,10 @@ int32_t DecodeSpsSvcExt (PWelsDecoderContext pCtx, PSubsetSps pSpsExt, PBitStrin
pExt->uiChromaPhaseYPlus1 = 1;
uiChromaArrayType = pSpsExt->sSps.uiChromaArrayType;
pExt->uiChromaPhaseXPlus1Flag = BsGetOneBit (pBs);
pExt->uiChromaPhaseYPlus1 = BsGetBits (pBs, 2);
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //chroma_phase_x_plus1_flag
pExt->uiChromaPhaseXPlus1Flag = uiCode;
WELS_READ_VERIFY (BsGetBits (pBs, 2, &uiCode)); //chroma_phase_y_plus1
pExt->uiChromaPhaseYPlus1 = uiCode;
pExt->uiSeqRefLayerChromaPhaseXPlus1Flag = pExt->uiChromaPhaseXPlus1Flag;
pExt->uiSeqRefLayerChromaPhaseYPlus1 = pExt->uiChromaPhaseYPlus1;
@ -640,28 +657,38 @@ int32_t DecodeSpsSvcExt (PWelsDecoderContext pCtx, PSubsetSps pSpsExt, PBitStrin
if (pExt->uiExtendedSpatialScalability == 1) {
SPosOffset* const kpPos = &pExt->sSeqScaledRefLayer;
pExt->uiSeqRefLayerChromaPhaseXPlus1Flag = BsGetOneBit (pBs);
pExt->uiSeqRefLayerChromaPhaseYPlus1 = BsGetBits (pBs, 2);
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //seq_ref_layer_chroma_phase_x_plus1_flag
pExt->uiSeqRefLayerChromaPhaseXPlus1Flag = uiCode;
WELS_READ_VERIFY (BsGetBits (pBs, 2, &uiCode)); //seq_ref_layer_chroma_phase_y_plus1
pExt->uiSeqRefLayerChromaPhaseYPlus1 = uiCode;
kpPos->iLeftOffset = BsGetSe (pBs);
WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //seq_scaled_ref_layer_left_offset
kpPos->iLeftOffset = iCode;
WELS_CHECK_SE_BOTH_WARNING (kpPos->iLeftOffset, SUBSET_SPS_SEQ_SCALED_REF_LAYER_LEFT_OFFSET_MIN,
SUBSET_SPS_SEQ_SCALED_REF_LAYER_LEFT_OFFSET_MAX, "seq_scaled_ref_layer_left_offset");
kpPos->iTopOffset = BsGetSe (pBs);
WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //seq_scaled_ref_layer_top_offset
kpPos->iTopOffset = iCode;
WELS_CHECK_SE_BOTH_WARNING (kpPos->iTopOffset, SUBSET_SPS_SEQ_SCALED_REF_LAYER_TOP_OFFSET_MIN,
SUBSET_SPS_SEQ_SCALED_REF_LAYER_TOP_OFFSET_MAX, "seq_scaled_ref_layer_top_offset");
kpPos->iRightOffset = BsGetSe (pBs);
WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //seq_scaled_ref_layer_right_offset
kpPos->iRightOffset = iCode;
WELS_CHECK_SE_BOTH_WARNING (kpPos->iRightOffset, SUBSET_SPS_SEQ_SCALED_REF_LAYER_RIGHT_OFFSET_MIN,
SUBSET_SPS_SEQ_SCALED_REF_LAYER_RIGHT_OFFSET_MAX, "seq_scaled_ref_layer_right_offset");
kpPos->iBottomOffset = BsGetSe (pBs);
WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //seq_scaled_ref_layer_bottom_offset
kpPos->iBottomOffset = iCode;
WELS_CHECK_SE_BOTH_WARNING (kpPos->iBottomOffset, SUBSET_SPS_SEQ_SCALED_REF_LAYER_BOTTOM_OFFSET_MIN,
SUBSET_SPS_SEQ_SCALED_REF_LAYER_BOTTOM_OFFSET_MAX, "seq_scaled_ref_layer_bottom_offset");
}
pExt->bSeqTCoeffLevelPredFlag = !!BsGetOneBit (pBs);
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //seq_tcoeff_level_prediction_flag
pExt->bSeqTCoeffLevelPredFlag = !!uiCode;
pExt->bAdaptiveTCoeffLevelPredFlag = false;
if (pExt->bSeqTCoeffLevelPredFlag)
pExt->bAdaptiveTCoeffLevelPredFlag = !!BsGetOneBit (pBs);
pExt->bSliceHeaderRestrictionFlag = !!BsGetOneBit (pBs);
if (pExt->bSeqTCoeffLevelPredFlag) {
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //adaptive_tcoeff_level_prediction_flag
pExt->bAdaptiveTCoeffLevelPredFlag = !!uiCode;
}
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //slice_header_restriction_flag
pExt->bSliceHeaderRestrictionFlag = !!uiCode;
@ -689,7 +716,7 @@ static const SLevelLimits g_kSLevelLimits[17] = {
{2073600, 36864, 184320, 240000, 240000, -2048, 2047, 2, 16} /* level 5.2 */
};
const SLevelLimits *GetLevelLimits(int32_t iLevelIdx, bool bConstraint3) {
const SLevelLimits* GetLevelLimits (int32_t iLevelIdx, bool bConstraint3) {
switch (iLevelIdx) {
case 10:
return &g_kSLevelLimits[0];
@ -765,7 +792,8 @@ int32_t ParseSps (PWelsDecoderContext pCtx, PBitStringAux pBsAux, int32_t* pPicW
ProfileIdc uiProfileIdc;
uint8_t uiLevelIdc;
int32_t iSpsId;
uint32_t uiTmp;
uint32_t uiCode;
int32_t iCode;
bool bConstraintSetFlags[6] = { false };
const bool kbUseSubsetFlag = IS_SUBSET_SPS_NAL (pNalHead->eNalUnitType);
@ -787,16 +815,25 @@ int32_t ParseSps (PWelsDecoderContext pCtx, PBitStringAux pBsAux, int32_t* pPicW
#endif //MOSAIC_AVOID_BASED_ON_SPS_PPS_ID
}
uiProfileIdc = BsGetBits (pBs, 8);
bConstraintSetFlags[0] = !!BsGetOneBit (pBs); // constraint_set0_flag
bConstraintSetFlags[1] = !!BsGetOneBit (pBs); // constraint_set1_flag
bConstraintSetFlags[2] = !!BsGetOneBit (pBs); // constraint_set2_flag
bConstraintSetFlags[3] = !!BsGetOneBit (pBs); // constraint_set3_flag
bConstraintSetFlags[4] = !!BsGetOneBit (pBs); // constraint_set4_flag
bConstraintSetFlags[5] = !!BsGetOneBit (pBs); // constraint_set5_flag
BsGetBits (pBs, 2); // reserved_zero_2bits, equal to 0
uiLevelIdc = BsGetBits (pBs, 8); // level_idc
iSpsId = BsGetUe (pBs); // seq_parameter_set_id
WELS_READ_VERIFY (BsGetBits (pBs, 8, &uiCode)); //profile_idc
uiProfileIdc = uiCode;
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //constraint_set0_flag
bConstraintSetFlags[0] = !!uiCode;
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //constraint_set1_flag
bConstraintSetFlags[1] = !!uiCode;
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //constraint_set2_flag
bConstraintSetFlags[2] = !!uiCode;
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //constraint_set3_flag
bConstraintSetFlags[3] = !!uiCode;
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //constraint_set4_flag
bConstraintSetFlags[4] = !!uiCode;
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //constraint_set5_flag
bConstraintSetFlags[5] = !!uiCode;
WELS_READ_VERIFY (BsGetBits (pBs, 2, &uiCode)); // reserved_zero_2bits, equal to 0
WELS_READ_VERIFY (BsGetBits (pBs, 8, &uiCode)); // level_idc
uiLevelIdc = uiCode;
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //seq_parameter_set_id
iSpsId = uiCode;
if (iSpsId >= MAX_SPS_COUNT || iSpsId < 0) { // Modified to check invalid negative iSpsId, 12/1/2009
WelsLog (pCtx, WELS_LOG_WARNING, " iSpsId is out of range! \n");
return GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_SPS_ID_OVERFLOW);
@ -846,25 +883,30 @@ int32_t ParseSps (PWelsDecoderContext pCtx, PBitStringAux pBsAux, int32_t* pPicW
PRO_HIGH422 == uiProfileIdc || PRO_HIGH444 == uiProfileIdc ||
PRO_CAVLC444 == uiProfileIdc || 44 == uiProfileIdc) {
pSps->uiChromaFormatIdc = BsGetUe (pBs);
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //chroma_format_idc
pSps->uiChromaFormatIdc = uiCode;
if (pSps->uiChromaFormatIdc != 1) {
WelsLog (pCtx, WELS_LOG_WARNING, "ParseSps(): chroma_format_idc (%d) = 1 supported.\n", pSps->uiChromaFormatIdc);
return GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_UNSUPPORTED_NON_BASELINE);
}
pSps->uiChromaArrayType = pSps->uiChromaFormatIdc;
pSps->uiBitDepthLuma = 8 + BsGetUe (pBs);
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //bit_depth_luma_minus8
pSps->uiBitDepthLuma = 8 + uiCode;
if (pSps->uiBitDepthLuma != 8) {
WelsLog (pCtx, WELS_LOG_WARNING, "ParseSps(): bit_depth_luma (%d) Only 8 bit supported.\n", pSps->uiBitDepthLuma);
return GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_UNSUPPORTED_NON_BASELINE);
}
pSps->uiBitDepthChroma = 8 + BsGetUe (pBs);
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //bit_depth_chroma_minus8
pSps->uiBitDepthChroma = 8 + uiCode;
if (pSps->uiBitDepthChroma != 8) {
WelsLog (pCtx, WELS_LOG_WARNING, "ParseSps(): bit_depth_chroma (%d). Only 8 bit supported.\n", pSps->uiBitDepthChroma);
return GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_UNSUPPORTED_NON_BASELINE);
}
pSps->bQpPrimeYZeroTransfBypassFlag = !!BsGetOneBit (pBs);
pSps->bSeqScalingMatrixPresentFlag = !!BsGetOneBit (pBs);
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //qpprime_y_zero_transform_bypass_flag
pSps->bQpPrimeYZeroTransfBypassFlag = !!uiCode;
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //seq_scaling_matrix_present_flag
pSps->bSeqScalingMatrixPresentFlag = !!uiCode;
if (pSps->bSeqScalingMatrixPresentFlag) { // For high profile, it is not used in current application. FIXME
WelsLog (pCtx, WELS_LOG_WARNING, "ParseSps(): seq_scaling_matrix_present_flag (%d). Feature not supported.\n",
@ -872,54 +914,62 @@ int32_t ParseSps (PWelsDecoderContext pCtx, PBitStringAux pBsAux, int32_t* pPicW
return GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_UNSUPPORTED_NON_BASELINE);
}
}
uiTmp = BsGetUe (pBs);
WELS_CHECK_SE_UPPER_ERROR (uiTmp, SPS_LOG2_MAX_FRAME_NUM_MINUS4_MAX, "log2_max_frame_num_minus4",
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //log2_max_frame_num_minus4
WELS_CHECK_SE_UPPER_ERROR (uiCode, SPS_LOG2_MAX_FRAME_NUM_MINUS4_MAX, "log2_max_frame_num_minus4",
GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_INVALID_LOG2_MAX_FRAME_NUM_MINUS4));
pSps->uiLog2MaxFrameNum = LOG2_MAX_FRAME_NUM_OFFSET + uiTmp; // log2_max_frame_num_minus4
pSps->uiPocType = BsGetUe (pBs); // pic_order_cnt_type
pSps->uiLog2MaxFrameNum = LOG2_MAX_FRAME_NUM_OFFSET + uiCode;
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //pic_order_cnt_type
pSps->uiPocType = uiCode;
if (0 == pSps->uiPocType) {
uiTmp = BsGetUe (pBs);
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //log2_max_pic_order_cnt_lsb_minus4
// log2_max_pic_order_cnt_lsb_minus4 should be in range 0 to 12, inclusive. (sec. 7.4.3)
WELS_CHECK_SE_UPPER_ERROR (uiTmp, SPS_LOG2_MAX_PIC_ORDER_CNT_LSB_MINUS4_MAX, "log2_max_pic_order_cnt_lsb_minus4",
WELS_CHECK_SE_UPPER_ERROR (uiCode, SPS_LOG2_MAX_PIC_ORDER_CNT_LSB_MINUS4_MAX, "log2_max_pic_order_cnt_lsb_minus4",
GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_INVALID_LOG2_MAX_PIC_ORDER_CNT_LSB_MINUS4));
pSps->iLog2MaxPocLsb = LOG2_MAX_PIC_ORDER_CNT_LSB_OFFSET + uiTmp; // log2_max_pic_order_cnt_lsb_minus4
pSps->iLog2MaxPocLsb = LOG2_MAX_PIC_ORDER_CNT_LSB_OFFSET + uiCode; // log2_max_pic_order_cnt_lsb_minus4
} else if (1 == pSps->uiPocType) {
int32_t i;
pSps->bDeltaPicOrderAlwaysZeroFlag = !!BsGetOneBit (pBs); // bDeltaPicOrderAlwaysZeroFlag
pSps->iOffsetForNonRefPic = BsGetSe (pBs); // iOffsetForNonRefPic
pSps->iOffsetForTopToBottomField = BsGetSe (pBs); // iOffsetForTopToBottomField
uiTmp = BsGetUe (pBs);
WELS_CHECK_SE_UPPER_ERROR (uiTmp, SPS_NUM_REF_FRAMES_IN_PIC_ORDER_CNT_CYCLE_MAX,
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //delta_pic_order_always_zero_flag
pSps->bDeltaPicOrderAlwaysZeroFlag = !!uiCode;
WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //offset_for_non_ref_pic
pSps->iOffsetForNonRefPic = iCode;
WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //offset_for_top_to_bottom_field
pSps->iOffsetForTopToBottomField = iCode;
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //num_ref_frames_in_pic_order_cnt_cycle
WELS_CHECK_SE_UPPER_ERROR (uiCode, SPS_NUM_REF_FRAMES_IN_PIC_ORDER_CNT_CYCLE_MAX,
"num_ref_frames_in_pic_order_cnt_cycle", GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS,
ERR_INFO_INVALID_NUM_REF_FRAME_IN_PIC_ORDER_CNT_CYCLE));
pSps->iNumRefFramesInPocCycle = uiTmp; // num_ref_frames_in_pic_order_cnt_cycle
for (i = 0; i < pSps->iNumRefFramesInPocCycle; i++)
pSps->iOffsetForRefFrame[ i ] = BsGetSe (pBs); // iOffsetForRefFrame[ i ]
pSps->iNumRefFramesInPocCycle = uiCode;
for (i = 0; i < pSps->iNumRefFramesInPocCycle; i++) {
WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //offset_for_ref_frame[ i ]
pSps->iOffsetForRefFrame[ i ] = iCode;
}
}
if (pSps->uiPocType > 2) {
WelsLog (pCtx, WELS_LOG_WARNING, " illegal pic_order_cnt_type: %d ! \n", pSps->uiPocType);
return GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_INVALID_POC_TYPE);
}
pSps->iNumRefFrames = BsGetUe (pBs); // max_num_ref_frames
pSps->bGapsInFrameNumValueAllowedFlag = !!BsGetOneBit (pBs); // bGapsInFrameNumValueAllowedFlag
uiTmp = BsGetUe (pBs); // pic_width_in_mbs_minus1
if (uiTmp == 0xffffffff) {
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //max_num_ref_frames
pSps->iNumRefFrames = uiCode;
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //gaps_in_frame_num_value_allowed_flag
pSps->bGapsInFrameNumValueAllowedFlag = !!uiCode;
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //pic_width_in_mbs_minus1
if (uiCode == 0xffffffff) {
WelsLog (pCtx, WELS_LOG_ERROR, " pic_width_in_mbs read error!\n");
return GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_INVALID_MB_SIZE_INFO);
}
pSps->iMbWidth = PIC_WIDTH_IN_MBS_OFFSET + uiTmp;
pSps->iMbWidth = PIC_WIDTH_IN_MBS_OFFSET + uiCode;
if ((uint64_t) (pSps->iMbWidth * pSps->iMbWidth) > (8 * pSLevelLimits->iMaxFS)) {
WelsLog (pCtx, WELS_LOG_WARNING, " the pic_width_in_mbs exceeds the level limits!\n");
}
uiTmp = BsGetUe (pBs); // pic_height_in_map_units_minus1
if (uiTmp == 0xffffffff) {
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //pic_height_in_map_units_minus1
if (uiCode == 0xffffffff) {
WelsLog (pCtx, WELS_LOG_ERROR, " pic_height_in_mbs read error!\n");
return GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_INVALID_MB_SIZE_INFO);
}
pSps->iMbHeight = PIC_HEIGHT_IN_MAP_UNITS_OFFSET + uiTmp;
pSps->iMbHeight = PIC_HEIGHT_IN_MAP_UNITS_OFFSET + uiCode;
if ((uint64_t) (pSps->iMbHeight * pSps->iMbHeight) > (8 * pSLevelLimits->iMaxFS)) {
WelsLog (pCtx, WELS_LOG_WARNING, " the pic_height_in_mbs exceeds the level limits!\n");
}
@ -937,21 +987,28 @@ int32_t ParseSps (PWelsDecoderContext pCtx, PBitStringAux pBsAux, int32_t* pPicW
if ((uint32_t)pSps->iNumRefFrames > uiMaxDpbFrames) {
WelsLog (pCtx, WELS_LOG_WARNING, " max_num_ref_frames exceeds level limits!\n");
}
pSps->bFrameMbsOnlyFlag = !!BsGetOneBit (pBs); // frame_mbs_only_flag
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //frame_mbs_only_flag
pSps->bFrameMbsOnlyFlag = !!uiCode;
if (!pSps->bFrameMbsOnlyFlag) {
WelsLog (pCtx, WELS_LOG_WARNING, "ParseSps(): frame_mbs_only_flag (%d) not supported.\n", pSps->bFrameMbsOnlyFlag);
return GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_UNSUPPORTED_MBAFF);
}
pSps->bDirect8x8InferenceFlag = !!BsGetOneBit (pBs); // direct_8x8_inference_flag
pSps->bFrameCroppingFlag = !!BsGetOneBit (pBs); // frame_cropping_flag
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //direct_8x8_inference_flag
pSps->bDirect8x8InferenceFlag = !!uiCode;
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //frame_cropping_flag
pSps->bFrameCroppingFlag = !!uiCode;
if (pSps->bFrameCroppingFlag) {
pSps->sFrameCrop.iLeftOffset = BsGetUe (pBs); // frame_crop_left_offset
pSps->sFrameCrop.iRightOffset = BsGetUe (pBs); // frame_crop_right_offset
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //frame_crop_left_offset
pSps->sFrameCrop.iLeftOffset = uiCode;
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //frame_crop_right_offset
pSps->sFrameCrop.iRightOffset = uiCode;
if ((pSps->sFrameCrop.iLeftOffset + pSps->sFrameCrop.iRightOffset) > ((int32_t)pSps->iMbWidth * 16 / 2)) {
WelsLog (pCtx, WELS_LOG_WARNING, "frame_crop_left_offset + frame_crop_right_offset exceeds limits!\n");
}
pSps->sFrameCrop.iTopOffset = BsGetUe (pBs); // frame_crop_top_offset
pSps->sFrameCrop.iBottomOffset = BsGetUe (pBs); // frame_crop_bottom_offset
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //frame_crop_top_offset
pSps->sFrameCrop.iTopOffset = uiCode;
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //frame_crop_bottom_offset
pSps->sFrameCrop.iBottomOffset = uiCode;
if ((pSps->sFrameCrop.iTopOffset + pSps->sFrameCrop.iBottomOffset) > ((int32_t)pSps->iMbHeight * 16 / 2)) {
WelsLog (pCtx, WELS_LOG_WARNING, "frame_crop_top_offset + frame_crop_right_offset exceeds limits!\n");
}
@ -961,7 +1018,8 @@ int32_t ParseSps (PWelsDecoderContext pCtx, PBitStringAux pBsAux, int32_t* pPicW
pSps->sFrameCrop.iTopOffset = 0; // frame_crop_top_offset
pSps->sFrameCrop.iBottomOffset = 0; // frame_crop_bottom_offset
}
pSps->bVuiParamPresentFlag = !!BsGetOneBit (pBs); // vui_parameters_present_flag
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //vui_parameters_present_flag
pSps->bVuiParamPresentFlag = !!uiCode;
// Check if SPS SVC extension applicated
if (kbUseSubsetFlag && (PRO_SCALABLE_BASELINE == uiProfileIdc || PRO_SCALABLE_HIGH == uiProfileIdc)) {
@ -969,7 +1027,8 @@ int32_t ParseSps (PWelsDecoderContext pCtx, PBitStringAux pBsAux, int32_t* pPicW
return -1;
}
pSubsetSps->bSvcVuiParamPresentFlag = !!BsGetOneBit (pBs);
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //svc_vui_parameters_present_flag
pSubsetSps->bSvcVuiParamPresentFlag = !!uiCode;
if (pSubsetSps->bSvcVuiParamPresentFlag) {
}
}
@ -1005,8 +1064,11 @@ int32_t ParsePps (PWelsDecoderContext pCtx, PPps pPpsList, PBitStringAux pBsAux)
PPps pPps = NULL;
uint32_t uiPpsId = 0;
uint32_t iTmp;
uint32_t uiCode;
int32_t iCode;
uiPpsId = BsGetUe (pBsAux);
WELS_READ_VERIFY (BsGetUe (pBsAux, &uiCode)); //pic_parameter_set_id
uiPpsId = uiCode;
if (uiPpsId >= MAX_PPS_COUNT) {
return ERR_INFO_PPS_ID_OVERFLOW;
}
@ -1019,23 +1081,28 @@ int32_t ParsePps (PWelsDecoderContext pCtx, PPps pPpsList, PBitStringAux pBsAux)
pPps->iPpsId = uiPpsId;
pPps->iSpsId = BsGetUe (pBsAux);
WELS_READ_VERIFY (BsGetUe (pBsAux, &uiCode)); //seq_parameter_set_id
pPps->iSpsId = uiCode;
if (pPps->iSpsId >= MAX_SPS_COUNT) {
return ERR_INFO_SPS_ID_OVERFLOW;
}
pPps->bEntropyCodingModeFlag = !!BsGetOneBit (pBsAux);
pPps->bPicOrderPresentFlag = !!BsGetOneBit (pBsAux);
WELS_READ_VERIFY (BsGetOneBit (pBsAux, &uiCode)); //entropy_coding_mode_flag
pPps->bEntropyCodingModeFlag = !!uiCode;
WELS_READ_VERIFY (BsGetOneBit (pBsAux, &uiCode)); //bottom_field_pic_order_in_frame_present_flag
pPps->bPicOrderPresentFlag = !!uiCode;
pPps->uiNumSliceGroups = NUM_SLICE_GROUPS_OFFSET + BsGetUe (pBsAux);
WELS_READ_VERIFY (BsGetUe (pBsAux, &uiCode)); //num_slice_groups_minus1
pPps->uiNumSliceGroups = NUM_SLICE_GROUPS_OFFSET + uiCode;
if (pPps->uiNumSliceGroups > MAX_SLICEGROUP_IDS) {
return ERR_INFO_INVALID_SLICEGROUP;
}
if (pPps->uiNumSliceGroups > 1) {
pPps->uiSliceGroupMapType = BsGetUe (pBsAux);
WELS_READ_VERIFY (BsGetUe (pBsAux, &uiCode)); //slice_group_map_type
pPps->uiSliceGroupMapType = uiCode;
if (pPps->uiSliceGroupMapType > 1) {
WelsLog (pCtx, WELS_LOG_WARNING, "ParsePps(): slice_group_map_type (%d): support only 0,1.\n",
pPps->uiSliceGroupMapType);
@ -1045,7 +1112,8 @@ int32_t ParsePps (PWelsDecoderContext pCtx, PPps pPpsList, PBitStringAux pBsAux)
switch (pPps->uiSliceGroupMapType) {
case 0:
for (iTmp = 0; iTmp < pPps->uiNumSliceGroups; iTmp++) {
pPps->uiRunLength[iTmp] = RUN_LENGTH_OFFSET + BsGetUe (pBsAux);
WELS_READ_VERIFY (BsGetUe (pBsAux, &uiCode)); //run_length_minus1[ iGroup ]
pPps->uiRunLength[iTmp] = RUN_LENGTH_OFFSET + uiCode;
}
break;
default:
@ -1053,34 +1121,44 @@ int32_t ParsePps (PWelsDecoderContext pCtx, PPps pPpsList, PBitStringAux pBsAux)
}
}
pPps->uiNumRefIdxL0Active = NUM_REF_IDX_L0_DEFAULT_ACTIVE_OFFSET + BsGetUe (pBsAux);
pPps->uiNumRefIdxL1Active = NUM_REF_IDX_L1_DEFAULT_ACTIVE_OFFSET + BsGetUe (pBsAux);
WELS_READ_VERIFY (BsGetUe (pBsAux, &uiCode)); //num_ref_idx_l0_default_active_minus1
pPps->uiNumRefIdxL0Active = NUM_REF_IDX_L0_DEFAULT_ACTIVE_OFFSET + uiCode;
WELS_READ_VERIFY (BsGetUe (pBsAux, &uiCode)); //num_ref_idx_l1_default_active_minus1
pPps->uiNumRefIdxL1Active = NUM_REF_IDX_L1_DEFAULT_ACTIVE_OFFSET + uiCode;
if (pPps->uiNumRefIdxL0Active > MAX_REF_PIC_COUNT ||
pPps->uiNumRefIdxL1Active > MAX_REF_PIC_COUNT) {
return ERR_INFO_REF_COUNT_OVERFLOW;
}
pPps->bWeightedPredFlag = !!BsGetOneBit (pBsAux);
pPps->uiWeightedBipredIdc = BsGetBits (pBsAux, 2);
WELS_READ_VERIFY (BsGetOneBit (pBsAux, &uiCode)); //weighted_pred_flag
pPps->bWeightedPredFlag = !!uiCode;
WELS_READ_VERIFY (BsGetBits (pBsAux, 2, &uiCode)); //weighted_bipred_idc
pPps->uiWeightedBipredIdc = uiCode;
if (pPps->bWeightedPredFlag || pPps->uiWeightedBipredIdc != 0) {
WelsLog (pCtx, WELS_LOG_WARNING, "ParsePps(): weighted_pred_flag (%d) weighted_bipred_idc (%d) neither supported.\n",
pPps->bWeightedPredFlag, pPps->uiWeightedBipredIdc);
return GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_UNSUPPORTED_WP);
}
pPps->iPicInitQp = PIC_INIT_QP_OFFSET + BsGetSe (pBsAux);
WELS_READ_VERIFY (BsGetSe (pBsAux, &iCode)); //pic_init_qp_minus26
pPps->iPicInitQp = PIC_INIT_QP_OFFSET + iCode;
WELS_CHECK_SE_BOTH_ERROR (pPps->iPicInitQp, PPS_PIC_INIT_QP_QS_MIN, PPS_PIC_INIT_QP_QS_MAX, "pic_init_qp_minus26 + 26",
GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_INVALID_PIC_INIT_QP));
pPps->iPicInitQs = PIC_INIT_QS_OFFSET + BsGetSe (pBsAux);
WELS_READ_VERIFY (BsGetSe (pBsAux, &iCode)); //pic_init_qs_minus26
pPps->iPicInitQs = PIC_INIT_QS_OFFSET + iCode;
WELS_CHECK_SE_BOTH_ERROR (pPps->iPicInitQs, PPS_PIC_INIT_QP_QS_MIN, PPS_PIC_INIT_QP_QS_MAX, "pic_init_qs_minus26 + 26",
GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_INVALID_PIC_INIT_QS));
pPps->iChromaQpIndexOffset = BsGetSe (pBsAux);
WELS_READ_VERIFY (BsGetSe (pBsAux, &iCode)); //chroma_qp_index_offset
pPps->iChromaQpIndexOffset = iCode;
WELS_CHECK_SE_BOTH_ERROR (pPps->iChromaQpIndexOffset, PPS_CHROMA_QP_INDEX_OFFSET_MIN, PPS_CHROMA_QP_INDEX_OFFSET_MAX,
"chroma_qp_index_offset", GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_INVALID_CHROMA_QP_INDEX_OFFSET));
pPps->bDeblockingFilterControlPresentFlag = !!BsGetOneBit (pBsAux);
pPps->bConstainedIntraPredFlag = !!BsGetOneBit (pBsAux);
pPps->bRedundantPicCntPresentFlag = !!BsGetOneBit (pBsAux);
WELS_READ_VERIFY (BsGetOneBit (pBsAux, &uiCode)); //deblocking_filter_control_present_flag
pPps->bDeblockingFilterControlPresentFlag = !!uiCode;
WELS_READ_VERIFY (BsGetOneBit (pBsAux, &uiCode)); //constrained_intra_pred_flag
pPps->bConstainedIntraPredFlag = !!uiCode;
WELS_READ_VERIFY (BsGetOneBit (pBsAux, &uiCode)); //redundant_pic_cnt_present_flag
pPps->bRedundantPicCntPresentFlag = !!uiCode;
#ifdef MOSAIC_AVOID_BASED_ON_SPS_PPS_ID

View File

@ -271,7 +271,7 @@ int32_t WelsMbInterPrediction (PWelsDecoderContext pCtx, PDqLayer pCurLayer) {
}
void WelsMbCopy (uint8_t* pDst, int32_t iStrideDst, uint8_t* pSrc, int32_t iStrideSrc,
int32_t iHeight, int32_t iWidth) {
int32_t iHeight, int32_t iWidth) {
int32_t i;
int32_t iOffsetDst = 0, iOffsetSrc = 0;
for (i = 0; i < iHeight; i++) {
@ -491,13 +491,16 @@ int32_t WelsActualDecodeMbCavlcISlice (PWelsDecoderContext pCtx) {
int32_t iMbXy = pCurLayer->iMbXyIndex;
int32_t iNMbMode, i;
uint32_t uiMbType = 0, uiCbp = 0, uiCbpL = 0, uiCbpC = 0;
uint32_t uiCode;
int32_t iCode;
ENFORCE_STACK_ALIGN_1D (uint8_t, pNonZeroCount, 48, 16);
pCurLayer->pInterPredictionDoneFlag[iMbXy] = 0;
pCurLayer->pResidualPredFlag[iMbXy] = pSlice->sSliceHeaderExt.bDefaultResidualPredFlag;
uiMbType = BsGetUe (pBs);
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //mb_type
uiMbType = uiCode;
if (uiMbType > 25) {
return ERR_INFO_INVALID_MB_TYPE;
}
@ -561,7 +564,8 @@ int32_t WelsActualDecodeMbCavlcISlice (PWelsDecoderContext pCtx) {
}
//uiCbp
uiCbp = BsGetUe (pBs);
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //coded_block_pattern
uiCbp = uiCode;
//G.9.1 Alternative parsing process for coded pBlock pattern
if (uiCbp > 47)
return ERR_INFO_INVALID_CBP;
@ -603,7 +607,8 @@ int32_t WelsActualDecodeMbCavlcISlice (PWelsDecoderContext pCtx) {
if (pCurLayer->pCbp[iMbXy] || MB_TYPE_INTRA16x16 == pCurLayer->pMbType[iMbXy]) {
int32_t iQpDelta, iId8x8, iId4x4;
iQpDelta = BsGetSe (pBs);
WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //mb_qp_delta
iQpDelta = iCode;
if (iQpDelta > 25 || iQpDelta < -26) { //out of iQpDelta range
return ERR_INFO_INVALID_QP;
@ -732,9 +737,11 @@ int32_t WelsDecodeMbCavlcISlice (PWelsDecoderContext pCtx, PNalUnit pNalCur) {
PSliceHeaderExt pSliceHeaderExt = &pCurLayer->sLayerInfo.sSliceInLayer.sSliceHeaderExt;
int32_t iBaseModeFlag;
int32_t iRet = 0; //should have the return value to indicate decoding error or not, It's NECESSARY--2010.4.15
uint32_t uiCode;
if (pSliceHeaderExt->bAdaptiveBaseModeFlag == 1) {
iBaseModeFlag = BsGetOneBit (pBs);
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //base_mode_flag
iBaseModeFlag = uiCode;
} else {
iBaseModeFlag = pSliceHeaderExt->bDefaultBaseModeFlag;
}
@ -769,11 +776,14 @@ int32_t WelsActualDecodeMbCavlcPSlice (PWelsDecoderContext pCtx) {
int32_t iNMbMode, i;
uint32_t uiMbType = 0, uiCbp = 0, uiCbpL = 0, uiCbpC = 0;
uint32_t uiCode;
int32_t iCode;
ENFORCE_STACK_ALIGN_1D (uint8_t, pNonZeroCount, 48, 16);
pCurLayer->pInterPredictionDoneFlag[iMbXy] = 0;//2009.10.23
uiMbType = BsGetUe (pBs);
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //mb_type
uiMbType = uiCode;
if (uiMbType < 5) { //inter MB type
int16_t iMotionVector[LIST_A][30][MV_A];
@ -785,7 +795,8 @@ int32_t WelsActualDecodeMbCavlcPSlice (PWelsDecoderContext pCtx) {
}
if (pSlice->sSliceHeaderExt.bAdaptiveResidualPredFlag == 1) {
pCurLayer->pResidualPredFlag[iMbXy] = BsGetOneBit (pBs);
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //residual_prediction_flag
pCurLayer->pResidualPredFlag[iMbXy] = uiCode;
} else {
pCurLayer->pResidualPredFlag[iMbXy] = pSlice->sSliceHeaderExt.bDefaultResidualPredFlag;
}
@ -882,7 +893,8 @@ int32_t WelsActualDecodeMbCavlcPSlice (PWelsDecoderContext pCtx) {
}
if (MB_TYPE_INTRA16x16 != pCurLayer->pMbType[iMbXy]) {
uiCbp = BsGetUe (pBs);
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //coded_block_pattern
uiCbp = uiCode;
{
if (uiCbp > 47)
return ERR_INFO_INVALID_CBP;
@ -918,7 +930,8 @@ int32_t WelsActualDecodeMbCavlcPSlice (PWelsDecoderContext pCtx) {
if (pCurLayer->pCbp[iMbXy] || MB_TYPE_INTRA16x16 == pCurLayer->pMbType[iMbXy]) {
int32_t iQpDelta, iId8x8, iId4x4;
iQpDelta = BsGetSe (pBs);
WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //mb_qp_delta
iQpDelta = iCode;
if (iQpDelta > 25 || iQpDelta < -26) { //out of iQpDelta range
return ERR_INFO_INVALID_QP;
@ -1048,9 +1061,11 @@ int32_t WelsDecodeMbCavlcPSlice (PWelsDecoderContext pCtx, PNalUnit pNalCur) {
int32_t iMbXy = pCurLayer->iMbXyIndex;
int32_t iBaseModeFlag, i;
int32_t iRet = 0; //should have the return value to indicate decoding error or not, It's NECESSARY--2010.4.15
uint32_t uiCode;
if (-1 == pSlice->iMbSkipRun) {
pSlice->iMbSkipRun = BsGetUe (pBs);
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //mb_skip_run
pSlice->iMbSkipRun = uiCode;
if (-1 == pSlice->iMbSkipRun) {
return -1;
}
@ -1094,7 +1109,8 @@ int32_t WelsDecodeMbCavlcPSlice (PWelsDecoderContext pCtx, PNalUnit pNalCur) {
}
if (pSlice->sSliceHeaderExt.bAdaptiveBaseModeFlag == 1) {
iBaseModeFlag = BsGetOneBit (pBs);
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //base_mode_flag
iBaseModeFlag = uiCode;
} else {
iBaseModeFlag = pSlice->sSliceHeaderExt.bDefaultBaseModeFlag;
}

View File

@ -156,17 +156,20 @@ int32_t ParseRefPicListReordering (PBitStringAux pBs, PSliceHeader pSh) {
const ESliceType keSt = pSh->eSliceType;
PRefPicListReorderSyn pRefPicListReordering = &pSh->pRefPicListReordering;
PSps pSps = pSh->pSps;
uint32_t uiCode;
if (keSt == I_SLICE || keSt == SI_SLICE)
return ERR_NONE;
// Common syntaxs for P or B slices: list0, list1 followed if B slices used.
do {
pRefPicListReordering->bRefPicListReorderingFlag[iList] = !!BsGetOneBit (pBs);
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //ref_pic_list_modification_flag_l0
pRefPicListReordering->bRefPicListReorderingFlag[iList] = !!uiCode;
if (pRefPicListReordering->bRefPicListReorderingFlag[iList]) {
int32_t iIdx = 0;
do {
const uint32_t kuiIdc = BsGetUe (pBs);
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //modification_of_pic_nums_idc
const uint32_t kuiIdc = uiCode;
//Fixed the referrence list reordering crash issue.(fault kIdc value > 3 case)---
if ((iIdx >= MAX_REF_PIC_COUNT) || (kuiIdc > 3)) {
@ -182,12 +185,13 @@ int32_t ParseRefPicListReordering (PBitStringAux pBs, PSliceHeader pSh) {
if (kuiIdc == 0 || kuiIdc == 1) {
// abs_diff_pic_num_minus1 should be in range 0 to MaxPicNum-1, MaxPicNum is derived as
// 2^(4+log2_max_frame_num_minus4)
uint32_t uiTmp = BsGetUe (pBs);
WELS_CHECK_SE_UPPER_ERROR_NOLOG (uiTmp, (1 << pSps->uiLog2MaxFrameNum), "abs_diff_pic_num_minus1",
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //abs_diff_pic_num_minus1
WELS_CHECK_SE_UPPER_ERROR_NOLOG (uiCode, (1 << pSps->uiLog2MaxFrameNum), "abs_diff_pic_num_minus1",
GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_REF_REORDERING));
pRefPicListReordering->sReorderingSyn[iList][iIdx].uiAbsDiffPicNumMinus1 = uiTmp; // uiAbsDiffPicNumMinus1
pRefPicListReordering->sReorderingSyn[iList][iIdx].uiAbsDiffPicNumMinus1 = uiCode; // uiAbsDiffPicNumMinus1
} else if (kuiIdc == 2) {
pRefPicListReordering->sReorderingSyn[iList][iIdx].uiLongTermPicNum = BsGetUe (pBs);
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //long_term_pic_num
pRefPicListReordering->sReorderingSyn[iList][iIdx].uiLongTermPicNum = uiCode;
}
++ iIdx;
@ -205,31 +209,41 @@ int32_t ParseDecRefPicMarking (PWelsDecoderContext pCtx, PBitStringAux pBs, PSli
const bool kbIdrFlag) {
PRefPicMarking const kpRefMarking = &pSh->sRefMarking;
PRefPic pRefPic = &pCtx->sRefPic;
uint32_t uiCode;
if (kbIdrFlag) {
kpRefMarking->bNoOutputOfPriorPicsFlag = !!BsGetOneBit (pBs);
kpRefMarking->bLongTermRefFlag = !!BsGetOneBit (pBs);
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //no_output_of_prior_pics_flag
kpRefMarking->bNoOutputOfPriorPicsFlag = !!uiCode;
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //long_term_reference_flag
kpRefMarking->bLongTermRefFlag = !!uiCode;
} else {
kpRefMarking->bAdaptiveRefPicMarkingModeFlag = !!BsGetOneBit (pBs);
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //adaptive_ref_pic_marking_mode_flag
kpRefMarking->bAdaptiveRefPicMarkingModeFlag = !!uiCode;
if (kpRefMarking->bAdaptiveRefPicMarkingModeFlag) {
int32_t iIdx = 0;
do {
const int32_t kiMmco = BsGetUe (pBs);
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //memory_management_control_operation
const int32_t kiMmco = uiCode;
kpRefMarking->sMmcoRef[iIdx].uiMmcoType = kiMmco;
if (kiMmco == MMCO_END)
break;
if (kiMmco == MMCO_SHORT2UNUSED || kiMmco == MMCO_SHORT2LONG) {
kpRefMarking->sMmcoRef[iIdx].iDiffOfPicNum = 1 + BsGetUe (pBs);
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //difference_of_pic_nums_minus1
kpRefMarking->sMmcoRef[iIdx].iDiffOfPicNum = 1 + uiCode;
kpRefMarking->sMmcoRef[iIdx].iShortFrameNum = (pSh->iFrameNum - kpRefMarking->sMmcoRef[iIdx].iDiffOfPicNum) & ((
1 << pSps->uiLog2MaxFrameNum) - 1);
} else if (kiMmco == MMCO_LONG2UNUSED)
kpRefMarking->sMmcoRef[iIdx].uiLongTermPicNum = BsGetUe (pBs);
} else if (kiMmco == MMCO_LONG2UNUSED) {
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //long_term_pic_num
kpRefMarking->sMmcoRef[iIdx].uiLongTermPicNum = uiCode;
}
if (kiMmco == MMCO_SHORT2LONG || kiMmco == MMCO_LONG) {
kpRefMarking->sMmcoRef[iIdx].iLongTermFrameIdx = BsGetUe (pBs);
} else if (kiMmco == MMCO_SET_MAX_LONG)
kpRefMarking->sMmcoRef[iIdx].iMaxLongTermFrameIdx = -1 + BsGetUe (pBs);
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //long_term_frame_idx
kpRefMarking->sMmcoRef[iIdx].iLongTermFrameIdx = uiCode;
} else if (kiMmco == MMCO_SET_MAX_LONG) {
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //max_long_term_frame_idx_plus1
kpRefMarking->sMmcoRef[iIdx].iMaxLongTermFrameIdx = -1 + uiCode;
}
++ iIdx;
} while (iIdx < MAX_MMCO_COUNT);
@ -477,9 +491,10 @@ int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, co
int32_t iRet = ERR_NONE;
uint8_t uiSliceType = 0;
uint8_t uiQualityId = BASE_QUALITY_ID;
uint32_t uiTmp;
bool bIdrFlag = false;
bool bSgChangeCycleInvolved = false; // involved slice group change cycle ?
uint32_t uiCode;
int32_t iCode;
if (kpCurNal == NULL) {
return ERR_INFO_OUT_OF_MEMORY;
@ -503,9 +518,11 @@ int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, co
kpCurNal->sNalData.sVclNal.bSliceHeaderExtFlag = kbExtensionFlag;
// first_mb_in_slice
pSliceHead->iFirstMbInSlice = BsGetUe (pBs);
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //first_mb_in_slice
pSliceHead->iFirstMbInSlice = uiCode;
uiSliceType = BsGetUe (pBs);
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //slice_type
uiSliceType = uiCode;
if (uiSliceType > 9) {
WelsLog (pCtx, WELS_LOG_WARNING, "slice type too large (%d) at first_mb(%d)\n", uiSliceType,
pSliceHead->iFirstMbInSlice);
@ -528,7 +545,8 @@ int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, co
pSliceHead->eSliceType = static_cast <ESliceType> (uiSliceType);
iPpsId = BsGetUe (pBs);
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //pic_parameter_set_id
iPpsId = uiCode;
if (iPpsId >= MAX_PPS_COUNT) {
WelsLog (pCtx, WELS_LOG_WARNING, "iPpsId out of range\n");
@ -583,7 +601,8 @@ int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, co
// check first_mb_in_slice
WELS_CHECK_SE_UPPER_ERROR ((uint32_t) (pSliceHead->iFirstMbInSlice), pSps->uiTotalMbCount, "first_mb_in_slice",
GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_FIRST_MB_IN_SLICE));
pSliceHead->iFrameNum = BsGetBits (pBs, pSps->uiLog2MaxFrameNum);
WELS_READ_VERIFY (BsGetBits (pBs, pSps->uiLog2MaxFrameNum, &uiCode)); //frame_num
pSliceHead->iFrameNum = uiCode;
pSliceHead->bFieldPicFlag = false;
pSliceHead->bBottomFiledFlag = false;
@ -601,11 +620,11 @@ int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, co
pSliceHead->iFrameNum);
return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_FRAME_NUM);
}
uiTmp = BsGetUe (pBs);
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //idr_pic_id
// standard 7.4.3 idr_pic_id should be in range 0 to 65535, inclusive.
WELS_CHECK_SE_UPPER_ERROR (uiTmp, SLICE_HEADER_IDR_PIC_ID_MAX, "idr_pic_id", GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER,
WELS_CHECK_SE_UPPER_ERROR (uiCode, SLICE_HEADER_IDR_PIC_ID_MAX, "idr_pic_id", GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER,
ERR_INFO_INVALID_IDR_PIC_ID));
pSliceHead->uiIdrPicId = uiTmp; /* uiIdrPicId */
pSliceHead->uiIdrPicId = uiCode; /* uiIdrPicId */
#ifdef LONG_TERM_REF
pCtx->uiCurIdrPicId = pSliceHead->uiIdrPicId;
#endif
@ -615,23 +634,28 @@ int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, co
pSliceHead->iDeltaPicOrderCnt[0] =
pSliceHead->iDeltaPicOrderCnt[1] = 0;
if (pSps->uiPocType == 0) {
pSliceHead->iPicOrderCntLsb = BsGetBits (pBs, pSps->iLog2MaxPocLsb);
WELS_READ_VERIFY (BsGetBits (pBs, pSps->iLog2MaxPocLsb, &uiCode)); //pic_order_cnt_lsb
pSliceHead->iPicOrderCntLsb = uiCode;
if (pPps->bPicOrderPresentFlag && !pSliceHead->bFieldPicFlag) {
pSliceHead->iDeltaPicOrderCntBottom = BsGetSe (pBs);
WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //delta_pic_order_cnt_bottom
pSliceHead->iDeltaPicOrderCntBottom = iCode;
}
} else if (pSps->uiPocType == 1 && !pSps->bDeltaPicOrderAlwaysZeroFlag) {
pSliceHead->iDeltaPicOrderCnt[0] = BsGetSe (pBs);
if (pPps->bPicOrderPresentFlag && !pSliceHead->bFieldPicFlag)
pSliceHead->iDeltaPicOrderCnt[1] = BsGetSe (pBs);
WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //delta_pic_order_cnt[ 0 ]
pSliceHead->iDeltaPicOrderCnt[0] = iCode;
if (pPps->bPicOrderPresentFlag && !pSliceHead->bFieldPicFlag) {
WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //delta_pic_order_cnt[ 1 ]
pSliceHead->iDeltaPicOrderCnt[1] = iCode;
}
}
pSliceHead->iRedundantPicCnt = 0;
if (pPps->bRedundantPicCntPresentFlag) {
uiTmp = BsGetUe (pBs);
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //redundant_pic_cnt
// standard section 7.4.3, redundant_pic_cnt should be in range 0 to 127, inclusive.
WELS_CHECK_SE_UPPER_ERROR (uiTmp, SLICE_HEADER_REDUNDANT_PIC_CNT_MAX, "redundant_pic_cnt",
WELS_CHECK_SE_UPPER_ERROR (uiCode, SLICE_HEADER_REDUNDANT_PIC_CNT_MAX, "redundant_pic_cnt",
GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_REDUNDANT_PIC_CNT));
pSliceHead->iRedundantPicCnt = uiTmp;
pSliceHead->iRedundantPicCnt = uiCode;
}
//set defaults, might be overriden a few line later
@ -645,9 +669,11 @@ int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, co
WelsLog (pCtx, WELS_LOG_WARNING, "ParseSliceHeaderSyntaxs(): kbBipredFlag = 1 not supported.\n");
return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_UNSUPPORTED_BIPRED);
}
pSliceHead->bNumRefIdxActiveOverrideFlag = !!BsGetOneBit (pBs);
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //num_ref_idx_active_override_flag
pSliceHead->bNumRefIdxActiveOverrideFlag = !!uiCode;
if (pSliceHead->bNumRefIdxActiveOverrideFlag) {
pSliceHead->uiRefCount[0] = 1 + BsGetUe (pBs);
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //num_ref_idx_l0_active_minus1
pSliceHead->uiRefCount[0] = 1 + uiCode;
}
}
@ -677,7 +703,8 @@ int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, co
}
if (kbExtensionFlag && !pSubsetSps->sSpsSvcExt.bSliceHeaderRestrictionFlag) {
pSliceHeadExt->bStoreRefBasePicFlag = !!BsGetOneBit (pBs);
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //store_ref_base_pic_flag
pSliceHeadExt->bStoreRefBasePicFlag = !!uiCode;
if ((pNalHeaderExt->bUseRefBasePicFlag || pSliceHeadExt->bStoreRefBasePicFlag) && !bIdrFlag) {
WelsLog (pCtx, WELS_LOG_WARNING,
"ParseSliceHeaderSyntaxs(): bUseRefBasePicFlag or bStoreRefBasePicFlag = 1 not supported.\n");
@ -692,7 +719,8 @@ int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, co
return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_UNSUPPORTED_CABAC_EL);
}
pSliceHead->iSliceQpDelta = BsGetSe (pBs);
WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //slice_qp_delta
pSliceHead->iSliceQpDelta = iCode;
pSliceHead->iSliceQp = pPps->iPicInitQp + pSliceHead->iSliceQpDelta;
if (pSliceHead->iSliceQp < 0 || pSliceHead->iSliceQp > 51) {
WelsLog (pCtx, WELS_LOG_WARNING, "QP %d out of range\n", pSliceHead->iSliceQp);
@ -711,7 +739,8 @@ int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, co
pSliceHead->iSliceAlphaC0Offset = 0;
pSliceHead->iSliceBetaOffset = 0;
if (pPps->bDeblockingFilterControlPresentFlag) {
pSliceHead->uiDisableDeblockingFilterIdc = BsGetUe (pBs);
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //disable_deblocking_filter_idc
pSliceHead->uiDisableDeblockingFilterIdc = uiCode;
//refer to JVT-X201wcm1.doc G.7.4.3.4--2010.4.20
if (pSliceHead->uiDisableDeblockingFilterIdc > 6) {
WelsLog (pCtx, WELS_LOG_WARNING, "disable_deblock_filter_idc (%d) out of range [0, 6]\n",
@ -719,11 +748,13 @@ int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, co
return ERR_INFO_INVALID_DBLOCKING_IDC;
}
if (pSliceHead->uiDisableDeblockingFilterIdc != 1) {
pSliceHead->iSliceAlphaC0Offset = BsGetSe (pBs) * 2; // slice_alpha_c0_offset_div2
WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //slice_alpha_c0_offset_div2
pSliceHead->iSliceAlphaC0Offset = iCode * 2;
WELS_CHECK_SE_BOTH_ERROR (pSliceHead->iSliceAlphaC0Offset, SLICE_HEADER_ALPHAC0_BETA_OFFSET_MIN,
SLICE_HEADER_ALPHAC0_BETA_OFFSET_MAX, "slice_alpha_c0_offset_div2 * 2", GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER,
ERR_INFO_INVALID_SLICE_ALPHA_C0_OFFSET_DIV2));
pSliceHead->iSliceBetaOffset = BsGetSe (pBs) * 2; // iSliceBetaOffset
WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //slice_beta_offset_div2
pSliceHead->iSliceBetaOffset = iCode * 2;
WELS_CHECK_SE_BOTH_ERROR (pSliceHead->iSliceBetaOffset, SLICE_HEADER_ALPHAC0_BETA_OFFSET_MIN,
SLICE_HEADER_ALPHAC0_BETA_OFFSET_MAX, "slice_beta_offset_div2 * 2", GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER,
ERR_INFO_INVALID_SLICE_BETA_OFFSET_DIV2));
@ -738,7 +769,8 @@ int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, co
if (pPps->uiSliceGroupChangeRate > 0) {
const int32_t kiNumBits = (int32_t)WELS_CEIL (log (static_cast<double> (1 + pPps->uiPicSizeInMapUnits /
pPps->uiSliceGroupChangeRate)));
pSliceHead->iSliceGroupChangeCycle = BsGetBits (pBs, kiNumBits); // For FMO extra types
WELS_READ_VERIFY (BsGetBits (pBs, kiNumBits, &uiCode)); //lice_group_change_cycle
pSliceHead->iSliceGroupChangeCycle = uiCode;
} else
pSliceHead->iSliceGroupChangeCycle = 0;
}
@ -751,9 +783,11 @@ int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, co
if (!pNalHeaderExt->iNoInterLayerPredFlag && BASE_QUALITY_ID == uiQualityId) {
//the following should be deleted for CODE_CLEAN
pSliceHeadExt->uiRefLayerDqId = BsGetUe (pBs);
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //ref_layer_dq_id
pSliceHeadExt->uiRefLayerDqId = uiCode;
if (pSubsetSps->sSpsSvcExt.bInterLayerDeblockingFilterCtrlPresentFlag) {
pSliceHeadExt->uiDisableInterLayerDeblockingFilterIdc = BsGetUe (pBs);
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //disable_inter_layer_deblocking_filter_idc
pSliceHeadExt->uiDisableInterLayerDeblockingFilterIdc = uiCode;
//refer to JVT-X201wcm1.doc G.7.4.3.4--2010.4.20
if (pSliceHeadExt->uiDisableInterLayerDeblockingFilterIdc > 6) {
WelsLog (pCtx, WELS_LOG_WARNING, "disable_inter_layer_deblock_filter_idc (%d) out of range [0, 6]\n",
@ -761,12 +795,14 @@ int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, co
return ERR_INFO_INVALID_DBLOCKING_IDC;
}
if (pSliceHeadExt->uiDisableInterLayerDeblockingFilterIdc != 1) {
pSliceHeadExt->iInterLayerSliceAlphaC0Offset = BsGetSe (pBs) << 1;
WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //inter_layer_slice_alpha_c0_offset_div2
pSliceHeadExt->iInterLayerSliceAlphaC0Offset = iCode * 2;
WELS_CHECK_SE_BOTH_ERROR (pSliceHeadExt->iInterLayerSliceAlphaC0Offset,
SLICE_HEADER_INTER_LAYER_ALPHAC0_BETA_OFFSET_MIN, SLICE_HEADER_INTER_LAYER_ALPHAC0_BETA_OFFSET_MAX,
"inter_layer_alpha_c0_offset_div2 * 2", GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER,
ERR_INFO_INVALID_SLICE_ALPHA_C0_OFFSET_DIV2));
pSliceHeadExt->iInterLayerSliceBetaOffset = BsGetSe (pBs) << 1;
WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //inter_layer_slice_beta_offset_div2
pSliceHeadExt->iInterLayerSliceBetaOffset = iCode * 2;
WELS_CHECK_SE_BOTH_ERROR (pSliceHeadExt->iInterLayerSliceBetaOffset, SLICE_HEADER_INTER_LAYER_ALPHAC0_BETA_OFFSET_MIN,
SLICE_HEADER_INTER_LAYER_ALPHAC0_BETA_OFFSET_MAX, "inter_layer_slice_beta_offset_div2 * 2",
GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_SLICE_BETA_OFFSET_DIV2));
@ -776,7 +812,8 @@ int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, co
pSliceHeadExt->uiRefLayerChromaPhaseXPlus1Flag = pSubsetSps->sSpsSvcExt.uiSeqRefLayerChromaPhaseXPlus1Flag;
pSliceHeadExt->uiRefLayerChromaPhaseYPlus1 = pSubsetSps->sSpsSvcExt.uiSeqRefLayerChromaPhaseYPlus1;
pSliceHeadExt->bConstrainedIntraResamplingFlag = !!BsGetOneBit (pBs);
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //constrained_intra_resampling_flag
pSliceHeadExt->bConstrainedIntraResamplingFlag = !!uiCode;
{
SPosOffset pos;
@ -809,32 +846,45 @@ int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, co
pSliceHeadExt->bTCoeffLevelPredFlag = pSubsetSps->sSpsSvcExt.bSeqTCoeffLevelPredFlag;
if (!pNalHeaderExt->iNoInterLayerPredFlag) {
pSliceHeadExt->bSliceSkipFlag = !!BsGetOneBit (pBs);
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //slice_skip_flag
pSliceHeadExt->bSliceSkipFlag = !!uiCode;
if (pSliceHeadExt->bSliceSkipFlag) {
pSliceHeadExt->uiNumMbsInSlice = 1 + BsGetUe (pBs);
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //num_mbs_in_slice_minus1
pSliceHeadExt->uiNumMbsInSlice = 1 + uiCode;
} else {
pSliceHeadExt->bAdaptiveBaseModeFlag = !!BsGetOneBit (pBs);
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //adaptive_base_mode_flag
pSliceHeadExt->bAdaptiveBaseModeFlag = !!uiCode;
if (!pSliceHeadExt->bAdaptiveBaseModeFlag) {
pSliceHeadExt->bDefaultBaseModeFlag = !!BsGetOneBit (pBs);
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //default_base_mode_flag
pSliceHeadExt->bDefaultBaseModeFlag = !!uiCode;
}
if (!pSliceHeadExt->bDefaultBaseModeFlag) {
pSliceHeadExt->bAdaptiveMotionPredFlag = !!BsGetOneBit (pBs);
if (!pSliceHeadExt->bAdaptiveMotionPredFlag)
pSliceHeadExt->bDefaultMotionPredFlag = !!BsGetOneBit (pBs);
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //adaptive_motion_prediction_flag
pSliceHeadExt->bAdaptiveMotionPredFlag = !!uiCode;
if (!pSliceHeadExt->bAdaptiveMotionPredFlag) {
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //default_motion_prediction_flag
pSliceHeadExt->bDefaultMotionPredFlag = !!uiCode;
}
}
pSliceHeadExt->bAdaptiveResidualPredFlag = !!BsGetOneBit (pBs);
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //adaptive_residual_prediction_flag
pSliceHeadExt->bAdaptiveResidualPredFlag = !!uiCode;
if (!pSliceHeadExt->bAdaptiveResidualPredFlag) {
pSliceHeadExt->bDefaultResidualPredFlag = !!BsGetOneBit (pBs);
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //default_residual_prediction_flag
pSliceHeadExt->bDefaultResidualPredFlag = !!uiCode;
}
}
if (pSubsetSps->sSpsSvcExt.bAdaptiveTCoeffLevelPredFlag)
pSliceHeadExt->bTCoeffLevelPredFlag = !!BsGetOneBit (pBs);
if (pSubsetSps->sSpsSvcExt.bAdaptiveTCoeffLevelPredFlag) {
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //tcoeff_level_prediction_flag
pSliceHeadExt->bTCoeffLevelPredFlag = !!uiCode;
}
}
if (!pSubsetSps->sSpsSvcExt.bSliceHeaderRestrictionFlag) {
pSliceHeadExt->uiScanIdxStart = BsGetBits (pBs, 4);
pSliceHeadExt->uiScanIdxEnd = BsGetBits (pBs, 4);
WELS_READ_VERIFY (BsGetBits (pBs, 4, &uiCode)); //scan_idx_start
pSliceHeadExt->uiScanIdxStart = uiCode;
WELS_READ_VERIFY (BsGetBits (pBs, 4, &uiCode)); //scan_idx_end
pSliceHeadExt->uiScanIdxEnd = uiCode;
if (pSliceHeadExt->uiScanIdxStart != 0 || pSliceHeadExt->uiScanIdxEnd != 15) {
WelsLog (pCtx, WELS_LOG_WARNING, "uiScanIdxStart (%d) != 0 and uiScanIdxEnd (%d) !=15 not supported here\n",
pSliceHeadExt->uiScanIdxStart, pSliceHeadExt->uiScanIdxEnd);
@ -970,84 +1020,84 @@ int32_t InitialDqLayersContext (PWelsDecoderContext pCtx, const int32_t kiMaxWid
memset (pDq, 0, sizeof (SDqLayer));
do {
const int32_t kiHshift = iPlaneIdx ? 1 : 0;
const int32_t kiVshift = kiHshift;
const int32_t kiStride = WELS_ALIGN ((kiPicStride >> kiHshift), (16 << (1 - kiHshift)));
const int32_t kiLine = (kiPicLines + (PADDING_LENGTH << 1)) >> kiVshift;
const int32_t kiSize = kiStride * kiLine;
do {
const int32_t kiHshift = iPlaneIdx ? 1 : 0;
const int32_t kiVshift = kiHshift;
const int32_t kiStride = WELS_ALIGN ((kiPicStride >> kiHshift), (16 << (1 - kiHshift)));
const int32_t kiLine = (kiPicLines + (PADDING_LENGTH << 1)) >> kiVshift;
const int32_t kiSize = kiStride * kiLine;
pCtx->pCsListXchg[i][iPlaneIdx] = (uint8_t*)WelsMalloc (kiSize * sizeof (uint8_t), "pCtx->pCsListXchg[][]");
pCtx->pCsListXchg[i][iPlaneIdx] = (uint8_t*)WelsMalloc (kiSize * sizeof (uint8_t), "pCtx->pCsListXchg[][]");
WELS_VERIFY_RETURN_IF (ERR_INFO_OUT_OF_MEMORY, (NULL == pCtx->pCsListXchg[i][iPlaneIdx]))
pCtx->iCsStride[iPlaneIdx] = kiStride;
WELS_VERIFY_RETURN_IF (ERR_INFO_OUT_OF_MEMORY, (NULL == pCtx->pCsListXchg[i][iPlaneIdx]))
pCtx->iCsStride[iPlaneIdx] = kiStride;
pCtx->pRsListXchg[i][iPlaneIdx] = (int16_t*)WelsMalloc (kiSize * sizeof (int16_t), "pCtx->pRsListXchg[][]");
pCtx->pRsListXchg[i][iPlaneIdx] = (int16_t*)WelsMalloc (kiSize * sizeof (int16_t), "pCtx->pRsListXchg[][]");
WELS_VERIFY_RETURN_IF (ERR_INFO_OUT_OF_MEMORY , (NULL == pCtx->pRsListXchg[i][iPlaneIdx]))
pCtx->iRsStride[iPlaneIdx] = kiStride;
WELS_VERIFY_RETURN_IF (ERR_INFO_OUT_OF_MEMORY , (NULL == pCtx->pRsListXchg[i][iPlaneIdx]))
pCtx->iRsStride[iPlaneIdx] = kiStride;
++ iPlaneIdx;
} while (iPlaneIdx < 3);
++ iPlaneIdx;
} while (iPlaneIdx < 3);
pCtx->sMb.pMbType[i] = (int8_t*)WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t),
"pCtx->sMb.pMbType[]");
pCtx->sMb.pMv[i][0] = (int16_t (*)[16][2])WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (
int16_t) * MV_A * MB_BLOCK4x4_NUM, "pCtx->sMb.pMv[][]");
pCtx->sMb.pRefIndex[i][0] = (int8_t (*)[MB_BLOCK4x4_NUM])WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (
int8_t) * MB_BLOCK4x4_NUM, "pCtx->sMb.pRefIndex[][]");
pCtx->sMb.pLumaQp[i] = (int8_t*)WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t),
"pCtx->sMb.pLumaQp[]");
pCtx->sMb.pChromaQp[i] = (int8_t*)WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t),
"pCtx->sMb.pChromaQp[]");
pCtx->sMb.pNzc[i] = (int8_t (*)[24])WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t) * 24,
"pCtx->sMb.pNzc[]");
pCtx->sMb.pNzcRs[i] = (int8_t (*)[24])WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t) * 24,
"pCtx->sMb.pNzcRs[]");
pCtx->sMb.pScaledTCoeff[i] = (int16_t (*)[MB_COEFF_LIST_SIZE])WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight *
sizeof (int16_t) * MB_COEFF_LIST_SIZE, "pCtx->sMb.pScaledTCoeff[]");
pCtx->sMb.pIntraPredMode[i] = (int8_t (*)[8])WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t) * 8,
"pCtx->sMb.pIntraPredMode[]");
pCtx->sMb.pIntra4x4FinalMode[i] = (int8_t (*)[MB_BLOCK4x4_NUM])WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight *
sizeof (int8_t) * MB_BLOCK4x4_NUM, "pCtx->sMb.pIntra4x4FinalMode[]");
pCtx->sMb.pChromaPredMode[i] = (int8_t*)WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t),
"pCtx->sMb.pChromaPredMode[]");
pCtx->sMb.pCbp[i] = (int8_t*)WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t),
"pCtx->sMb.pCbp[]");
pCtx->sMb.pSubMbType[i] = (int8_t (*)[MB_PARTITION_SIZE])WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (
int8_t) * MB_PARTITION_SIZE, "pCtx->sMb.pSubMbType[]");
pCtx->sMb.pSliceIdc[i] = (int32_t*) WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int32_t),
"pCtx->sMb.pSliceIdc[]"); // using int32_t for slice_idc, 4/21/2010
if (pCtx->sMb.pSliceIdc[i] != NULL)
memset (pCtx->sMb.pSliceIdc[i], 0xff, (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int32_t)));
pCtx->sMb.pResidualPredFlag[i] = (int8_t*) WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t),
"pCtx->sMb.pResidualPredFlag[]");
//pCtx->sMb.pMotionPredFlag[i] = (uint8_t *) WelsMalloc(pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof(uint8_t), "pCtx->sMb.pMotionPredFlag[]");
pCtx->sMb.pInterPredictionDoneFlag[i] = (int8_t*) WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (
int8_t), "pCtx->sMb.pInterPredictionDoneFlag[]");
pCtx->sMb.pMbType[i] = (int8_t*)WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t),
"pCtx->sMb.pMbType[]");
pCtx->sMb.pMv[i][0] = (int16_t (*)[16][2])WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (
int16_t) * MV_A * MB_BLOCK4x4_NUM, "pCtx->sMb.pMv[][]");
pCtx->sMb.pRefIndex[i][0] = (int8_t (*)[MB_BLOCK4x4_NUM])WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (
int8_t) * MB_BLOCK4x4_NUM, "pCtx->sMb.pRefIndex[][]");
pCtx->sMb.pLumaQp[i] = (int8_t*)WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t),
"pCtx->sMb.pLumaQp[]");
pCtx->sMb.pChromaQp[i] = (int8_t*)WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t),
"pCtx->sMb.pChromaQp[]");
pCtx->sMb.pNzc[i] = (int8_t (*)[24])WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t) * 24,
"pCtx->sMb.pNzc[]");
pCtx->sMb.pNzcRs[i] = (int8_t (*)[24])WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t) * 24,
"pCtx->sMb.pNzcRs[]");
pCtx->sMb.pScaledTCoeff[i] = (int16_t (*)[MB_COEFF_LIST_SIZE])WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight *
sizeof (int16_t) * MB_COEFF_LIST_SIZE, "pCtx->sMb.pScaledTCoeff[]");
pCtx->sMb.pIntraPredMode[i] = (int8_t (*)[8])WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t) * 8,
"pCtx->sMb.pIntraPredMode[]");
pCtx->sMb.pIntra4x4FinalMode[i] = (int8_t (*)[MB_BLOCK4x4_NUM])WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight *
sizeof (int8_t) * MB_BLOCK4x4_NUM, "pCtx->sMb.pIntra4x4FinalMode[]");
pCtx->sMb.pChromaPredMode[i] = (int8_t*)WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t),
"pCtx->sMb.pChromaPredMode[]");
pCtx->sMb.pCbp[i] = (int8_t*)WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t),
"pCtx->sMb.pCbp[]");
pCtx->sMb.pSubMbType[i] = (int8_t (*)[MB_PARTITION_SIZE])WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (
int8_t) * MB_PARTITION_SIZE, "pCtx->sMb.pSubMbType[]");
pCtx->sMb.pSliceIdc[i] = (int32_t*) WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int32_t),
"pCtx->sMb.pSliceIdc[]"); // using int32_t for slice_idc, 4/21/2010
if (pCtx->sMb.pSliceIdc[i] != NULL)
memset (pCtx->sMb.pSliceIdc[i], 0xff, (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int32_t)));
pCtx->sMb.pResidualPredFlag[i] = (int8_t*) WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t),
"pCtx->sMb.pResidualPredFlag[]");
//pCtx->sMb.pMotionPredFlag[i] = (uint8_t *) WelsMalloc(pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof(uint8_t), "pCtx->sMb.pMotionPredFlag[]");
pCtx->sMb.pInterPredictionDoneFlag[i] = (int8_t*) WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (
int8_t), "pCtx->sMb.pInterPredictionDoneFlag[]");
// check memory block valid due above allocated..
WELS_VERIFY_RETURN_IF (ERR_INFO_OUT_OF_MEMORY,
((NULL == pCtx->sMb.pMbType[i]) ||
(NULL == pCtx->sMb.pMv[i][0]) ||
(NULL == pCtx->sMb.pRefIndex[i][0]) ||
(NULL == pCtx->sMb.pLumaQp[i]) ||
(NULL == pCtx->sMb.pChromaQp[i]) ||
(NULL == pCtx->sMb.pNzc[i]) ||
(NULL == pCtx->sMb.pNzcRs[i]) ||
(NULL == pCtx->sMb.pScaledTCoeff[i]) ||
(NULL == pCtx->sMb.pIntraPredMode[i]) ||
(NULL == pCtx->sMb.pIntra4x4FinalMode[i]) ||
(NULL == pCtx->sMb.pChromaPredMode[i]) ||
(NULL == pCtx->sMb.pCbp[i]) ||
(NULL == pCtx->sMb.pSubMbType[i]) ||
(NULL == pCtx->sMb.pSliceIdc[i]) ||
(NULL == pCtx->sMb.pResidualPredFlag[i]) ||
(NULL == pCtx->sMb.pInterPredictionDoneFlag[i])
)
)
// check memory block valid due above allocated..
WELS_VERIFY_RETURN_IF (ERR_INFO_OUT_OF_MEMORY,
((NULL == pCtx->sMb.pMbType[i]) ||
(NULL == pCtx->sMb.pMv[i][0]) ||
(NULL == pCtx->sMb.pRefIndex[i][0]) ||
(NULL == pCtx->sMb.pLumaQp[i]) ||
(NULL == pCtx->sMb.pChromaQp[i]) ||
(NULL == pCtx->sMb.pNzc[i]) ||
(NULL == pCtx->sMb.pNzcRs[i]) ||
(NULL == pCtx->sMb.pScaledTCoeff[i]) ||
(NULL == pCtx->sMb.pIntraPredMode[i]) ||
(NULL == pCtx->sMb.pIntra4x4FinalMode[i]) ||
(NULL == pCtx->sMb.pChromaPredMode[i]) ||
(NULL == pCtx->sMb.pCbp[i]) ||
(NULL == pCtx->sMb.pSubMbType[i]) ||
(NULL == pCtx->sMb.pSliceIdc[i]) ||
(NULL == pCtx->sMb.pResidualPredFlag[i]) ||
(NULL == pCtx->sMb.pInterPredictionDoneFlag[i])
)
)
pCtx->pDqLayersList[i] = pDq;
++ i;
@ -1603,7 +1653,7 @@ int32_t ConstructAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferI
if (NAL_UNIT_CODED_SLICE_IDR == pCurAu->pNalUnitsList[pCurAu->uiStartPos]->sNalHeaderExt.sNalUnitHeader.eNalUnitType ||
pCurAu->pNalUnitsList[pCurAu->uiStartPos]->sNalHeaderExt.bIdrFlag) {
WelsResetRefPic (pCtx); //clear ref pPic when IDR NAL
iErr = SyncPictureResolutionExt (pCtx, pCtx->pSps->iMbWidth, pCtx->pSps->iMbHeight);
iErr = SyncPictureResolutionExt (pCtx, pCtx->pSps->iMbWidth, pCtx->pSps->iMbHeight);
if (ERR_NONE != iErr) {
WelsLog (pCtx, WELS_LOG_WARNING, "sync picture resolution ext failed, the error is %d", iErr);
@ -1854,7 +1904,7 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, int3
if (!dq_cur->sLayerInfo.pSps->bGapsInFrameNumValueAllowedFlag) {
const bool kbIdrFlag = dq_cur->sLayerInfo.sNalHeaderExt.bIdrFlag
|| (dq_cur->sLayerInfo.sNalHeaderExt.sNalUnitHeader.eNalUnitType == NAL_UNIT_CODED_SLICE_IDR);
|| (dq_cur->sLayerInfo.sNalHeaderExt.sNalUnitHeader.eNalUnitType == NAL_UNIT_CODED_SLICE_IDR);
// Subclause 8.2.5.2 Decoding process for gaps in frame_num
if (!kbIdrFlag &&
pSh->iFrameNum != pCtx->iPrevFrameNum &&

View File

@ -477,7 +477,8 @@ void BsStartCavlc (PBitStringAux pBs) {
}
void BsEndCavlc (PBitStringAux pBs) {
pBs->pCurBuf = pBs->pStartBuf + (pBs->iIndex >> 3);
uint32_t uiCache32Bit = (uint32_t)((((pBs->pCurBuf[0] << 8) | pBs->pCurBuf[1]) << 16) | (pBs->pCurBuf[2] << 8) | pBs->pCurBuf[3]);
uint32_t uiCache32Bit = (uint32_t) ((((pBs->pCurBuf[0] << 8) | pBs->pCurBuf[1]) << 16) |
(pBs->pCurBuf[2] << 8) | pBs->pCurBuf[3]);
pBs->uiCurBits = uiCache32Bit << (pBs->iIndex & 0x07);
pBs->pCurBuf += 4;
pBs->iLeftBits = -16 + (pBs->iIndex & 0x07);
@ -677,7 +678,7 @@ int32_t WelsResidualBlockCavlc (SVlcTable* pVlcTable, uint8_t* pNonZeroCountCach
uint8_t bChroma = (bChromaDc || CHROMA_AC == iResidualProperty);
SReadBitsCache sReadBitsCache;
uint32_t uiCache32Bit = (uint32_t)((((pBuf[0] << 8) | pBuf[1]) << 16) | (pBuf[2] << 8) | pBuf[3]);
uint32_t uiCache32Bit = (uint32_t) ((((pBuf[0] << 8) | pBuf[1]) << 16) | (pBuf[2] << 8) | pBuf[3]);
sReadBitsCache.uiCache32Bit = uiCache32Bit << (iCurIdx & 0x07);
sReadBitsCache.uiRemainBits = 32 - (iCurIdx & 0x07);
sReadBitsCache.pBuf = pBuf;
@ -782,7 +783,7 @@ int32_t ParseIntra4x4ModeConstrain0 (PNeighAvail pNeighAvail, int8_t* pIntraPred
int32_t iFinalMode, i;
uint8_t uiNeighAvail = 0;
uint32_t uiTmp;
uint32_t uiCode;
if (pNeighAvail->iLeftAvail) { //left
iSampleAvail[ 6] =
iSampleAvail[12] =
@ -805,14 +806,16 @@ int32_t ParseIntra4x4ModeConstrain0 (PNeighAvail pNeighAvail, int8_t* pIntraPred
uiNeighAvail = (iSampleAvail[6] << 2) | (iSampleAvail[0] << 1) | (iSampleAvail[1]);
for (i = 0; i < 16; i++) {
const int32_t kiPrevIntra4x4PredMode = BsGetOneBit (pBs); //1bit
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //prev_intra4x4_pred_mode_flag[ luma4x4BlkIdx ]
const int32_t kiPrevIntra4x4PredMode = uiCode;
const int32_t kiPredMode = PredIntra4x4Mode (pIntraPredMode, i);
int8_t iBestMode;
if (kiPrevIntra4x4PredMode) {
iBestMode = kiPredMode;
} else { //kPrevIntra4x4PredMode == 0
const int32_t kiRemIntra4x4PredMode = BsGetBits (pBs, 3); //3bits
WELS_READ_VERIFY (BsGetBits (pBs, 3, &uiCode)); //rem_intra4x4_pred_mode[ luma4x4BlkIdx ]
const int32_t kiRemIntra4x4PredMode = uiCode;
if (kiRemIntra4x4PredMode < kiPredMode) {
iBestMode = kiRemIntra4x4PredMode;
} else {
@ -835,11 +838,11 @@ int32_t ParseIntra4x4ModeConstrain0 (PNeighAvail pNeighAvail, int8_t* pIntraPred
pCurDqLayer->pIntraPredMode[iMbXy][4] = pIntraPredMode[4 + 8 * 1];
pCurDqLayer->pIntraPredMode[iMbXy][5] = pIntraPredMode[4 + 8 * 2];
pCurDqLayer->pIntraPredMode[iMbXy][6] = pIntraPredMode[4 + 8 * 3];
uiTmp = BsGetUe (pBs);
if (uiTmp > MAX_PRED_MODE_ID_CHROMA) {
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //intra_chroma_pred_mode
if (uiCode > MAX_PRED_MODE_ID_CHROMA) {
return ERR_INFO_INVALID_I_CHROMA_PRED_MODE;
}
pCurDqLayer->pChromaPredMode[iMbXy] = uiTmp;
pCurDqLayer->pChromaPredMode[iMbXy] = uiCode;
if (CheckIntraChromaPredMode (uiNeighAvail, &pCurDqLayer->pChromaPredMode[iMbXy])) {
return ERR_INFO_INVALID_I_CHROMA_PRED_MODE;
}
@ -854,7 +857,7 @@ int32_t ParseIntra4x4ModeConstrain1 (PNeighAvail pNeighAvail, int8_t* pIntraPred
int32_t iFinalMode, i;
uint8_t uiNeighAvail = 0;
uint32_t uiTmp;
uint32_t uiCode;
if (pNeighAvail->iLeftAvail && IS_INTRA (pNeighAvail->iLeftType)) { //left
iSampleAvail[ 6] =
iSampleAvail[12] =
@ -877,14 +880,16 @@ int32_t ParseIntra4x4ModeConstrain1 (PNeighAvail pNeighAvail, int8_t* pIntraPred
uiNeighAvail = (iSampleAvail[6] << 2) | (iSampleAvail[0] << 1) | (iSampleAvail[1]);
for (i = 0; i < 16; i++) {
const int32_t kiPrevIntra4x4PredMode = BsGetOneBit (pBs); //1bit
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //prev_intra4x4_pred_mode_flag[ luma4x4BlkIdx ]
const int32_t kiPrevIntra4x4PredMode = uiCode; //1bit
const int32_t kiPredMode = PredIntra4x4Mode (pIntraPredMode, i);
int8_t iBestMode;
if (kiPrevIntra4x4PredMode) {
iBestMode = kiPredMode;
} else { //kPrevIntra4x4PredMode == 0
const int32_t kiRemIntra4x4PredMode = BsGetBits (pBs, 3); //3bits
WELS_READ_VERIFY (BsGetBits (pBs, 3, &uiCode)); //rem_intra4x4_pred_mode[ luma4x4BlkIdx ]
const int32_t kiRemIntra4x4PredMode = uiCode;
if (kiRemIntra4x4PredMode < kiPredMode) {
iBestMode = kiRemIntra4x4PredMode;
} else {
@ -907,11 +912,11 @@ int32_t ParseIntra4x4ModeConstrain1 (PNeighAvail pNeighAvail, int8_t* pIntraPred
pCurDqLayer->pIntraPredMode[iMbXy][4] = pIntraPredMode[4 + 8 * 1];
pCurDqLayer->pIntraPredMode[iMbXy][5] = pIntraPredMode[4 + 8 * 2];
pCurDqLayer->pIntraPredMode[iMbXy][6] = pIntraPredMode[4 + 8 * 3];
uiTmp = BsGetUe (pBs);
if (uiTmp > MAX_PRED_MODE_ID_CHROMA) {
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //intra_chroma_pred_mode
if (uiCode > MAX_PRED_MODE_ID_CHROMA) {
return ERR_INFO_INVALID_I_CHROMA_PRED_MODE;
}
pCurDqLayer->pChromaPredMode[iMbXy] = uiTmp;
pCurDqLayer->pChromaPredMode[iMbXy] = uiCode;
if (CheckIntraChromaPredMode (uiNeighAvail, &pCurDqLayer->pChromaPredMode[iMbXy])) {
return ERR_INFO_INVALID_I_CHROMA_PRED_MODE;
}
@ -922,7 +927,7 @@ int32_t ParseIntra4x4ModeConstrain1 (PNeighAvail pNeighAvail, int8_t* pIntraPred
int32_t ParseIntra16x16ModeConstrain0 (PNeighAvail pNeighAvail, PBitStringAux pBs, PDqLayer pCurDqLayer) {
int32_t iMbXy = pCurDqLayer->iMbXyIndex;
uint8_t uiNeighAvail = 0; //0x07 = 0 1 1 1, means left, top-left, top avail or not. (1: avail, 0: unavail)
uint32_t uiTmp;
uint32_t uiCode;
if (pNeighAvail->iLeftAvail) {
uiNeighAvail = (1 << 2);
}
@ -937,11 +942,11 @@ int32_t ParseIntra16x16ModeConstrain0 (PNeighAvail pNeighAvail, PBitStringAux pB
&pCurDqLayer->pIntraPredMode[iMbXy][7])) { //invalid iPredMode, must stop decoding
return ERR_INFO_INVALID_I16x16_PRED_MODE;
}
uiTmp = BsGetUe (pBs);
if (uiTmp > MAX_PRED_MODE_ID_CHROMA) {
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //intra_chroma_pred_mode
if (uiCode > MAX_PRED_MODE_ID_CHROMA) {
return ERR_INFO_INVALID_I_CHROMA_PRED_MODE;
}
pCurDqLayer->pChromaPredMode[iMbXy] = uiTmp;
pCurDqLayer->pChromaPredMode[iMbXy] = uiCode;
if (CheckIntraChromaPredMode (uiNeighAvail, &pCurDqLayer->pChromaPredMode[iMbXy])) {
return ERR_INFO_INVALID_I_CHROMA_PRED_MODE;
@ -953,7 +958,7 @@ int32_t ParseIntra16x16ModeConstrain0 (PNeighAvail pNeighAvail, PBitStringAux pB
int32_t ParseIntra16x16ModeConstrain1 (PNeighAvail pNeighAvail, PBitStringAux pBs, PDqLayer pCurDqLayer) {
int32_t iMbXy = pCurDqLayer->iMbXyIndex;
uint8_t uiNeighAvail = 0; //0x07 = 0 1 1 1, means left, top-left, top avail or not. (1: avail, 0: unavail)
uint32_t uiTmp;
uint32_t uiCode;
if (pNeighAvail->iLeftAvail && IS_INTRA (pNeighAvail->iLeftType)) {
uiNeighAvail = (1 << 2);
}
@ -968,11 +973,11 @@ int32_t ParseIntra16x16ModeConstrain1 (PNeighAvail pNeighAvail, PBitStringAux pB
&pCurDqLayer->pIntraPredMode[iMbXy][7])) { //invalid iPredMode, must stop decoding
return ERR_INFO_INVALID_I16x16_PRED_MODE;
}
uiTmp = BsGetUe (pBs);
if (uiTmp > MAX_PRED_MODE_ID_CHROMA) {
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //intra_chroma_pred_mode
if (uiCode > MAX_PRED_MODE_ID_CHROMA) {
return ERR_INFO_INVALID_I_CHROMA_PRED_MODE;
}
pCurDqLayer->pChromaPredMode[iMbXy] = uiTmp;
pCurDqLayer->pChromaPredMode[iMbXy] = uiCode;
if (CheckIntraChromaPredMode (uiNeighAvail, &pCurDqLayer->pChromaPredMode[iMbXy])) {
return ERR_INFO_INVALID_I_CHROMA_PRED_MODE;
@ -993,6 +998,8 @@ int32_t ParseInterInfo (PWelsDecoderContext pCtx, int16_t iMvArray[LIST_A][30][M
int32_t iMbXy = pCurDqLayer->iMbXyIndex;
int32_t iMotionPredFlag[4];
int16_t iMv[2] = {0};
uint32_t uiCode;
int32_t iCode;
int16_t iMinVmv = pSliceHeader->pSps->pSLevelLimits->iMinVmv;
int16_t iMaxVmv = pSliceHeader->pSps->pSLevelLimits->iMaxVmv;
iMotionPredFlag[0] = iMotionPredFlag[1] = iMotionPredFlag[2] = iMotionPredFlag[3] =
@ -1004,10 +1011,12 @@ int32_t ParseInterInfo (PWelsDecoderContext pCtx, int16_t iMvArray[LIST_A][30][M
case MB_TYPE_16x16: {
int32_t iRefIdx = 0;
if (pSlice->sSliceHeaderExt.bAdaptiveMotionPredFlag) {
iMotionPredFlag[0] = BsGetOneBit (pBs);
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //motion_prediction_flag_l0[ mbPartIdx ]
iMotionPredFlag[0] = uiCode;
}
if (iMotionPredFlag[0] == 0) {
iRefIdx = BsGetTe0 (pBs, iRefCount[0]);
WELS_READ_VERIFY (BsGetTe0 (pBs, iRefCount[0], &uiCode)); //motion_prediction_flag_l1[ mbPartIdx ]
iRefIdx = uiCode;
// Security check: iRefIdx should be in range 0 to num_ref_idx_l0_active_minus1, includsive
// ref to standard section 7.4.5.1. iRefCount[0] is 1 + num_ref_idx_l0_active_minus1.
if ((iRefIdx < 0) || (iRefIdx >= iRefCount[0]) || (ppRefPic[iRefIdx] == NULL)) { //error ref_idx
@ -1019,8 +1028,10 @@ int32_t ParseInterInfo (PWelsDecoderContext pCtx, int16_t iMvArray[LIST_A][30][M
}
PredMv (iMvArray, iRefIdxArray, 0, 4, iRefIdx, iMv);
iMv[0] += BsGetSe (pBs);
iMv[1] += BsGetSe (pBs);
WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //mvd_l0[ mbPartIdx ][ 0 ][ compIdx ]
iMv[0] += iCode;
WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //mvd_l1[ mbPartIdx ][ 0 ][ compIdx ]
iMv[1] += iCode;
WELS_CHECK_SE_BOTH_WARNING (iMv[1], iMinVmv, iMaxVmv, "vertical mv");
UpdateP16x16MotionInfo (pCurDqLayer, iRefIdx, iMv);
}
@ -1029,7 +1040,8 @@ int32_t ParseInterInfo (PWelsDecoderContext pCtx, int16_t iMvArray[LIST_A][30][M
int32_t iRefIdx[2];
for (i = 0; i < 2; i++) {
if (pSlice->sSliceHeaderExt.bAdaptiveMotionPredFlag) {
iMotionPredFlag[i] = BsGetOneBit (pBs);
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //motion_prediction_flag_l0[ mbPartIdx ]
iMotionPredFlag[i] = uiCode;
}
}
@ -1038,7 +1050,8 @@ int32_t ParseInterInfo (PWelsDecoderContext pCtx, int16_t iMvArray[LIST_A][30][M
WelsLog (pCtx, WELS_LOG_WARNING, "inter parse: iMotionPredFlag = 1 not supported. \n");
return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_UNSUPPORTED_ILP);
}
iRefIdx[i] = BsGetTe0 (pBs, iRefCount[0]);
WELS_READ_VERIFY (BsGetTe0 (pBs, iRefCount[0], &uiCode)); //ref_idx_l0[ mbPartIdx ]
iRefIdx[i] = uiCode;
if ((iRefIdx[i] < 0) || (iRefIdx[i] >= iRefCount[0]) || (ppRefPic[iRefIdx[i]] == NULL)) { //error ref_idx
return ERR_INFO_INVALID_REF_INDEX;
}
@ -1046,8 +1059,10 @@ int32_t ParseInterInfo (PWelsDecoderContext pCtx, int16_t iMvArray[LIST_A][30][M
for (i = 0; i < 2; i++) {
PredInter16x8Mv (iMvArray, iRefIdxArray, i << 3, iRefIdx[i], iMv);
iMv[0] += BsGetSe (pBs);
iMv[1] += BsGetSe (pBs);
WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //mvd_l0[ mbPartIdx ][ 0 ][ compIdx ]
iMv[0] += iCode;
WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //mvd_l1[ mbPartIdx ][ 0 ][ compIdx ]
iMv[1] += iCode;
WELS_CHECK_SE_BOTH_WARNING (iMv[1], iMinVmv, iMaxVmv, "vertical mv");
UpdateP16x8MotionInfo (pCurDqLayer, iMvArray, iRefIdxArray, i << 3, iRefIdx[i], iMv);
}
@ -1057,13 +1072,15 @@ int32_t ParseInterInfo (PWelsDecoderContext pCtx, int16_t iMvArray[LIST_A][30][M
int32_t iRefIdx[2];
for (i = 0; i < 2; i++) {
if (pSlice->sSliceHeaderExt.bAdaptiveMotionPredFlag) {
iMotionPredFlag[i] = BsGetOneBit (pBs);
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //motion_prediction_flag_l0[ mbPartIdx ]
iMotionPredFlag[i] = uiCode;
}
}
for (i = 0; i < 2; i++) {
if (iMotionPredFlag[i] == 0) {
iRefIdx[i] = BsGetTe0 (pBs, iRefCount[0]);
WELS_READ_VERIFY (BsGetTe0 (pBs, iRefCount[0], &uiCode)); //ref_idx_l0[ mbPartIdx ]
iRefIdx[i] = uiCode;
if ((iRefIdx[i] < 0) || (iRefIdx[i] >= iRefCount[0]) || (ppRefPic[iRefIdx[i]] == NULL)) { //error ref_idx
return ERR_INFO_INVALID_REF_INDEX;
}
@ -1076,8 +1093,10 @@ int32_t ParseInterInfo (PWelsDecoderContext pCtx, int16_t iMvArray[LIST_A][30][M
for (i = 0; i < 2; i++) {
PredInter8x16Mv (iMvArray, iRefIdxArray, i << 2, iRefIdx[i], iMv);
iMv[0] += BsGetSe (pBs);
iMv[1] += BsGetSe (pBs);
WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //mvd_l0[ mbPartIdx ][ 0 ][ compIdx ]
iMv[0] += iCode;
WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //mvd_l1[ mbPartIdx ][ 0 ][ compIdx ]
iMv[1] += iCode;
WELS_CHECK_SE_BOTH_WARNING (iMv[1], iMinVmv, iMaxVmv, "vertical mv");
UpdateP8x16MotionInfo (pCurDqLayer, iMvArray, iRefIdxArray, i << 2, iRefIdx[i], iMv);
}
@ -1095,7 +1114,8 @@ int32_t ParseInterInfo (PWelsDecoderContext pCtx, int16_t iMvArray[LIST_A][30][M
//uiSubMbType, partition
for (i = 0; i < 4; i++) {
uiSubMbType = BsGetUe (pBs);
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //sub_mb_type[ mbPartIdx ]
uiSubMbType = uiCode;
if (uiSubMbType >= 4) { //invalid uiSubMbType
return ERR_INFO_INVALID_SUB_MB_TYPE;
}
@ -1106,7 +1126,8 @@ int32_t ParseInterInfo (PWelsDecoderContext pCtx, int16_t iMvArray[LIST_A][30][M
if (pSlice->sSliceHeaderExt.bAdaptiveMotionPredFlag) {
for (i = 0; i < 4; i++) {
iMotionPredFlag[i] = BsGetOneBit (pBs);
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //motion_prediction_flag_l0[ mbPartIdx ]
iMotionPredFlag[i] = uiCode;
}
}
@ -1119,7 +1140,8 @@ int32_t ParseInterInfo (PWelsDecoderContext pCtx, int16_t iMvArray[LIST_A][30][M
uint8_t uiScan4Idx = g_kuiScan4[iIndex8];
if (iMotionPredFlag[i] == 0) {
iRefIdx[i] = BsGetTe0 (pBs, iRefCount[0]);
WELS_READ_VERIFY (BsGetTe0 (pBs, iRefCount[0], &uiCode)); //ref_idx_l0[ mbPartIdx ]
iRefIdx[i] = uiCode;
if ((iRefIdx[i] < 0) || (iRefIdx[i] >= iRefCount[0]) || (ppRefPic[iRefIdx[i]] == NULL)) { //error ref_idx
return ERR_INFO_INVALID_REF_INDEX;
}
@ -1151,8 +1173,10 @@ int32_t ParseInterInfo (PWelsDecoderContext pCtx, int16_t iMvArray[LIST_A][30][M
uiCacheIdx = g_kuiCache30ScanIdx[iPartIdx];
PredMv (iMvArray, iRefIdxArray, iPartIdx, iBlockWidth, iRefIdx[i], iMv);
iMv[0] += BsGetSe (pBs);
iMv[1] += BsGetSe (pBs);
WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //mvd_l0[ mbPartIdx ][ subMbPartIdx ][ compIdx ]
iMv[0] += iCode;
WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //mvd_l1[ mbPartIdx ][ subMbPartIdx ][ compIdx ]
iMv[1] += iCode;
WELS_CHECK_SE_BOTH_WARNING (iMv[1], iMinVmv, iMaxVmv, "vertical mv");
if (SUB_MB_TYPE_8x8 == uiSubMbType) {
ST32 (pCurDqLayer->pMv[0][iMbXy][uiScan4Idx], LD32 (iMv));