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); 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 CheckAccessUnitBoundary (const PNalUnit kpCurNal, const PNalUnit kpLastNal, const PSps kpSps);
bool CheckAccessUnitBoundaryExt (PNalUnitHeaderExt pLastNalHdrExt, PNalUnitHeaderExt pCurNalHeaderExt, bool CheckAccessUnitBoundaryExt (PNalUnitHeaderExt pLastNalHdrExt, PNalUnitHeaderExt pCurNalHeaderExt,
PSliceHeader pLastSliceHeader, PSliceHeader pCurSliceHeader); PSliceHeader pLastSliceHeader, PSliceHeader pCurSliceHeader);
/*! /*!
************************************************************************************* *************************************************************************************
* \brief to parse Sequence Parameter Set (SPS) * \brief to parse Sequence Parameter Set (SPS)

View File

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

View File

@ -43,12 +43,12 @@
namespace WelsDec { namespace WelsDec {
typedef enum TagWelsErr { typedef enum TagWelsErr {
ERR_NONE = 0, ERR_NONE = 0,
ERR_INVALID_PARAMETERS = 1, ERR_INVALID_PARAMETERS = 1,
ERR_MALLOC_FAILED = 2, ERR_MALLOC_FAILED = 2,
ERR_API_FAILED = 3, ERR_API_FAILED = 3,
ERR_BOUND = 31, ERR_BOUND = 31,
} EWelsErr; } EWelsErr;
/* /*
@ -62,13 +62,13 @@ ERR_BOUND = 31,
/* ERR_LEVEL */ /* ERR_LEVEL */
//----------------------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------------------
enum { enum {
ERR_LEVEL_ACCESS_UNIT = 1, ERR_LEVEL_ACCESS_UNIT = 1,
ERR_LEVEL_NAL_UNIT_HEADER, ERR_LEVEL_NAL_UNIT_HEADER,
ERR_LEVEL_PREFIX_NAL, ERR_LEVEL_PREFIX_NAL,
ERR_LEVEL_PARAM_SETS, ERR_LEVEL_PARAM_SETS,
ERR_LEVEL_SLICE_HEADER, ERR_LEVEL_SLICE_HEADER,
ERR_LEVEL_SLICE_DATA, ERR_LEVEL_SLICE_DATA,
ERR_LEVEL_MB_DATA, ERR_LEVEL_MB_DATA,
}; };
//----------------------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------------------
@ -79,102 +79,104 @@ ERR_LEVEL_MB_DATA,
#define ERR_INFO_SYNTAX_BASE 1001 #define ERR_INFO_SYNTAX_BASE 1001
#define ERR_INFO_LOGIC_BASE 10001 #define ERR_INFO_LOGIC_BASE 10001
enum { enum {
/* Error from common system level: 1-1000 */ /* Error from common system level: 1-1000 */
ERR_INFO_OUT_OF_MEMORY = ERR_INFO_COMMON_BASE, ERR_INFO_OUT_OF_MEMORY = ERR_INFO_COMMON_BASE,
ERR_INFO_INVALID_ACCESS, ERR_INFO_INVALID_ACCESS,
ERR_INFO_INVALID_PTR, ERR_INFO_INVALID_PTR,
ERR_INFO_INVALID_PARAM, ERR_INFO_INVALID_PARAM,
ERR_INFO_FILE_NO_FOUND, ERR_INFO_FILE_NO_FOUND,
ERR_INFO_PATH_NO_FOUND, ERR_INFO_PATH_NO_FOUND,
ERR_INFO_ACCESS_DENIED, ERR_INFO_ACCESS_DENIED,
ERR_INFO_NOT_READY, ERR_INFO_NOT_READY,
ERR_INFO_WRITE_FAULT, ERR_INFO_WRITE_FAULT,
ERR_INFO_READ_FAULT, ERR_INFO_READ_FAULT,
/* Error from H.264 syntax elements parser: 1001-10000 */ ERR_INFO_READ_OVERFLOW,
ERR_INFO_NO_PREFIX_CODE = ERR_INFO_SYNTAX_BASE, // No start prefix code indication ERR_INFO_READ_LEADING_ZERO,
ERR_INFO_NO_PARAM_SETS, // No SPS and/ PPS before sequence header /* Error from H.264 syntax elements parser: 1001-10000 */
ERR_INFO_PARAM_SETS_NOT_INTEGRATED, // Parameters sets (sps/pps) are not integrated at all before to decode VCL nal ERR_INFO_NO_PREFIX_CODE = ERR_INFO_SYNTAX_BASE, // No start prefix code indication
ERR_INFO_SPS_ID_OVERFLOW, ERR_INFO_NO_PARAM_SETS, // No SPS and/ PPS before sequence header
ERR_INFO_PPS_ID_OVERFLOW, ERR_INFO_PARAM_SETS_NOT_INTEGRATED, // Parameters sets (sps/pps) are not integrated at all before to decode VCL nal
ERR_INFO_INVALID_PROFILE_IDC, ERR_INFO_SPS_ID_OVERFLOW,
ERR_INFO_UNMATCHED_LEVEL_IDC, ERR_INFO_PPS_ID_OVERFLOW,
ERR_INFO_INVALID_POC_TYPE, ERR_INFO_INVALID_PROFILE_IDC,
ERR_INFO_INVALID_MB_SIZE_INFO, ERR_INFO_UNMATCHED_LEVEL_IDC,
ERR_INFO_REF_COUNT_OVERFLOW, ERR_INFO_INVALID_POC_TYPE,
ERR_INFO_CROPPING_NO_SUPPORTED, ERR_INFO_INVALID_MB_SIZE_INFO,
ERR_INFO_INVALID_SLICEGROUP, ERR_INFO_REF_COUNT_OVERFLOW,
ERR_INFO_INVALID_SLICEGROUP_MAP_TYPE, ERR_INFO_CROPPING_NO_SUPPORTED,
ERR_INFO_INVALID_FRAME_NUM, ERR_INFO_INVALID_SLICEGROUP,
ERR_INFO_INVALID_IDR_PIC_ID, ERR_INFO_INVALID_SLICEGROUP_MAP_TYPE,
ERR_INFO_INVALID_REDUNDANT_PIC_CNT, ERR_INFO_INVALID_FRAME_NUM,
ERR_INFO_INVALID_MAX_NUM_REF_FRAMES, ERR_INFO_INVALID_IDR_PIC_ID,
ERR_INFO_INVALID_FIRST_MB_IN_SLICE, ERR_INFO_INVALID_REDUNDANT_PIC_CNT,
ERR_INFO_INVALID_NUM_REF_IDX_L0_ACTIVE_MINUS1, ERR_INFO_INVALID_MAX_NUM_REF_FRAMES,
ERR_INFO_INVALID_SLICE_ALPHA_C0_OFFSET_DIV2, ERR_INFO_INVALID_FIRST_MB_IN_SLICE,
ERR_INFO_INVALID_SLICE_BETA_OFFSET_DIV2, ERR_INFO_INVALID_NUM_REF_IDX_L0_ACTIVE_MINUS1,
ERR_INFO_FMO_INIT_FAIL, ERR_INFO_INVALID_SLICE_ALPHA_C0_OFFSET_DIV2,
ERR_INFO_SLICE_TYPE_OVERFLOW, ERR_INFO_INVALID_SLICE_BETA_OFFSET_DIV2,
ERR_INFO_INVALID_QP, ERR_INFO_FMO_INIT_FAIL,
ERR_INFO_INVALID_PIC_INIT_QS, ERR_INFO_SLICE_TYPE_OVERFLOW,
ERR_INFO_INVALID_CHROMA_QP_INDEX_OFFSET, ERR_INFO_INVALID_QP,
ERR_INFO_INVALID_PIC_INIT_QP, ERR_INFO_INVALID_PIC_INIT_QS,
ERR_INFO_INVALID_LOG2_MAX_FRAME_NUM_MINUS4, ERR_INFO_INVALID_CHROMA_QP_INDEX_OFFSET,
ERR_INFO_INVALID_LOG2_MAX_PIC_ORDER_CNT_LSB_MINUS4, ERR_INFO_INVALID_PIC_INIT_QP,
ERR_INFO_INVALID_NUM_REF_FRAME_IN_PIC_ORDER_CNT_CYCLE, ERR_INFO_INVALID_LOG2_MAX_FRAME_NUM_MINUS4,
ERR_INFO_INVALID_DBLOCKING_IDC, ERR_INFO_INVALID_LOG2_MAX_PIC_ORDER_CNT_LSB_MINUS4,
ERR_INFO_INVALID_MB_TYPE, ERR_INFO_INVALID_NUM_REF_FRAME_IN_PIC_ORDER_CNT_CYCLE,
ERR_INFO_INVALID_SUB_MB_TYPE, ERR_INFO_INVALID_DBLOCKING_IDC,
ERR_INFO_UNAVAILABLE_TOP_BLOCK_FOR_INTRA, ERR_INFO_INVALID_MB_TYPE,
ERR_INFO_UNAVAILABLE_LEFT_BLOCK_FOR_INTRA, ERR_INFO_INVALID_SUB_MB_TYPE,
ERR_INFO_INVALID_REF_INDEX, ERR_INFO_UNAVAILABLE_TOP_BLOCK_FOR_INTRA,
ERR_INFO_INVALID_CBP, ERR_INFO_UNAVAILABLE_LEFT_BLOCK_FOR_INTRA,
ERR_INFO_DQUANT_OUT_OF_RANGE, ERR_INFO_INVALID_REF_INDEX,
ERR_INFO_CAVLC_INVALID_PREFIX, ERR_INFO_INVALID_CBP,
ERR_INFO_CAVLC_INVALID_TOTAL_COEFF_OR_TRAILING_ONES, ERR_INFO_DQUANT_OUT_OF_RANGE,
ERR_INFO_CAVLC_INVALID_ZERO_LEFT, ERR_INFO_CAVLC_INVALID_PREFIX,
ERR_INFO_CAVLC_INVALID_RUN_BEFORE, ERR_INFO_CAVLC_INVALID_TOTAL_COEFF_OR_TRAILING_ONES,
ERR_INFO_MV_OUT_OF_RANGE, 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_I4x4_PRED_MODE,
ERR_INFO_INVALID_I16x16_PRED_MODE, ERR_INFO_INVALID_I16x16_PRED_MODE,
ERR_INFO_INVALID_I_CHROMA_PRED_MODE, ERR_INFO_INVALID_I_CHROMA_PRED_MODE,
ERR_INFO_UNSUPPORTED_NON_BASELINE, ERR_INFO_UNSUPPORTED_NON_BASELINE,
ERR_INFO_UNSUPPORTED_FMOTYPE, ERR_INFO_UNSUPPORTED_FMOTYPE,
ERR_INFO_UNSUPPORTED_MBAFF, ERR_INFO_UNSUPPORTED_MBAFF,
ERR_INFO_UNSUPPORTED_ILP, ERR_INFO_UNSUPPORTED_ILP,
ERR_INFO_UNSUPPORTED_CABAC_EL, ERR_INFO_UNSUPPORTED_CABAC_EL,
ERR_INFO_UNSUPPORTED_SPSI, ERR_INFO_UNSUPPORTED_SPSI,
ERR_INFO_UNSUPPORTED_MGS, ERR_INFO_UNSUPPORTED_MGS,
ERR_INFO_UNSUPPORTED_BIPRED, ERR_INFO_UNSUPPORTED_BIPRED,
ERR_INFO_UNSUPPORTED_WP, ERR_INFO_UNSUPPORTED_WP,
ERR_INFO_FRAMES_LOST, ERR_INFO_FRAMES_LOST,
ERR_INFO_DEPENDENCY_SPATIAL_LAYER_LOST, ERR_INFO_DEPENDENCY_SPATIAL_LAYER_LOST,
ERR_INFO_DEPENDENCY_QUALIT_LAYER_LOST, ERR_INFO_DEPENDENCY_QUALIT_LAYER_LOST,
ERR_INFO_REFERENCE_PIC_LOST, ERR_INFO_REFERENCE_PIC_LOST,
ERR_INFO_INVALID_REORDERING, ERR_INFO_INVALID_REORDERING,
ERR_INFO_INVALID_MARKING, ERR_INFO_INVALID_MARKING,
ERR_INFO_FMO_NOT_SUPPORTED_IN_BASE_LAYER, ERR_INFO_FMO_NOT_SUPPORTED_IN_BASE_LAYER,
ERR_INFO_INVALID_ESS, ERR_INFO_INVALID_ESS,
ERR_INFO_INVALID_SLICE_TYPE, ERR_INFO_INVALID_SLICE_TYPE,
ERR_INFO_INVALID_REF_MARKING, ERR_INFO_INVALID_REF_MARKING,
ERR_INFO_INVALID_REF_REORDERING, ERR_INFO_INVALID_REF_REORDERING,
/* Error from corresponding logic, 10001-65535 */ /* Error from corresponding logic, 10001-65535 */
ERR_INFO_NO_IDR_PIC = ERR_INFO_LOGIC_BASE, // NO IDR picture available before sequence header 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_NO_NEIGHBOUR_MBS,
ERR_INFO_EC_UNEXPECTED_MB_TYPE, ERR_INFO_EC_UNEXPECTED_MB_TYPE,
ERR_INFO_EC_NO_ENOUGH_NEIGHBOUR_MBS, ERR_INFO_EC_NO_ENOUGH_NEIGHBOUR_MBS,
//for LTR //for LTR
ERR_INFO_INVALID_MMCO_OPCODE_BASE, ERR_INFO_INVALID_MMCO_OPCODE_BASE,
ERR_INFO_INVALID_MMCO_SHORT2UNUSED, ERR_INFO_INVALID_MMCO_SHORT2UNUSED,
EER_INFO_INVALID_MMCO_LONG2UNUSED, EER_INFO_INVALID_MMCO_LONG2UNUSED,
ERR_INFO_INVALID_MMCO_SHOART2LONG, ERR_INFO_INVALID_MMCO_SHOART2LONG,
ERR_INFO_INVALID_MMCO_REF_NUM_OVERFLOW, ERR_INFO_INVALID_MMCO_REF_NUM_OVERFLOW,
ERR_INFO_INVALID_MMCO_REF_NUM_NOT_ENOUGH, ERR_INFO_INVALID_MMCO_REF_NUM_NOT_ENOUGH,
ERR_INFO_INVALID_MMCO_LONG_TERM_IDX_EXCEED_MAX, 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, bool CheckAccessUnitBoundaryExt (PNalUnitHeaderExt pLastNalHdrExt, PNalUnitHeaderExt pCurNalHeaderExt,
PSliceHeader pLastSliceHeader, PSliceHeader pCurSliceHeader) { PSliceHeader pLastSliceHeader, PSliceHeader pCurSliceHeader) {
const PSps kpSps = pCurSliceHeader->pSps; const PSps kpSps = pCurSliceHeader->pSps;
//Sub-clause 7.1.4.1.1 temporal_id //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; return iErr;
} }
void ParseRefBasePicMarking (PBitStringAux pBs, PRefBasePicMarking pRefBasePicMarking) { int32_t ParseRefBasePicMarking (PBitStringAux pBs, PRefBasePicMarking pRefBasePicMarking) {
const bool kbAdaptiveMarkingModeFlag = !!BsGetOneBit (pBs); uint32_t uiCode;
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //adaptive_ref_base_pic_marking_mode_flag
const bool kbAdaptiveMarkingModeFlag = !!uiCode;
pRefBasePicMarking->bAdaptiveRefBasePicMarkingModeFlag = kbAdaptiveMarkingModeFlag; pRefBasePicMarking->bAdaptiveRefBasePicMarkingModeFlag = kbAdaptiveMarkingModeFlag;
if (kbAdaptiveMarkingModeFlag) { if (kbAdaptiveMarkingModeFlag) {
int32_t iIdx = 0; int32_t iIdx = 0;
do { 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; pRefBasePicMarking->mmco_base[iIdx].uiMmcoType = kuiMmco;
@ -573,31 +576,39 @@ void ParseRefBasePicMarking (PBitStringAux pBs, PRefBasePicMarking pRefBasePicMa
break; break;
if (kuiMmco == MMCO_SHORT2UNUSED) { 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; pRefBasePicMarking->mmco_base[iIdx].iShortFrameNum = 0;
} else if (kuiMmco == MMCO_LONG2UNUSED) { } 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; ++ iIdx;
} while (iIdx < MAX_MMCO_COUNT); } 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; PNalUnit pCurNal = &pCtx->sPrefixNal;
uint32_t uiCode;
if (pCurNal->sNalHeaderExt.sNalUnitHeader.uiNalRefIdc != 0) { if (pCurNal->sNalHeaderExt.sNalUnitHeader.uiNalRefIdc != 0) {
PNalUnitHeaderExt head_ext = &pCurNal->sNalHeaderExt; PNalUnitHeaderExt head_ext = &pCurNal->sNalHeaderExt;
PPrefixNalUnit sPrefixNal = &pCurNal->sNalData.sPrefixNal; 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) { 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) { 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 #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) { int32_t DecodeSpsSvcExt (PWelsDecoderContext pCtx, PSubsetSps pSpsExt, PBitStringAux pBs) {
PSpsSvcExt pExt = NULL; PSpsSvcExt pExt = NULL;
uint8_t uiChromaArrayType = 1; uint8_t uiChromaArrayType = 1;
uint32_t uiCode;
int32_t iCode;
pExt = &pSpsExt->sSpsSvcExt; pExt = &pSpsExt->sSpsSvcExt;
pExt->bInterLayerDeblockingFilterCtrlPresentFlag = !!BsGetOneBit (pBs); WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //inter_layer_deblocking_filter_control_present_flag
pExt->uiExtendedSpatialScalability = BsGetBits (pBs, 2); pExt->bInterLayerDeblockingFilterCtrlPresentFlag = !!uiCode;
WELS_READ_VERIFY (BsGetBits (pBs, 2, &uiCode)); //extended_spatial_scalability_idc
pExt->uiExtendedSpatialScalability = uiCode;
if (pExt->uiExtendedSpatialScalability > 2) { if (pExt->uiExtendedSpatialScalability > 2) {
WelsLog (pCtx, WELS_LOG_WARNING, "DecodeSpsSvcExt():extended_spatial_scalability (%d) != 0, ESS not supported!\n", WelsLog (pCtx, WELS_LOG_WARNING, "DecodeSpsSvcExt():extended_spatial_scalability (%d) != 0, ESS not supported!\n",
pExt->uiExtendedSpatialScalability); pExt->uiExtendedSpatialScalability);
@ -631,8 +646,10 @@ int32_t DecodeSpsSvcExt (PWelsDecoderContext pCtx, PSubsetSps pSpsExt, PBitStrin
pExt->uiChromaPhaseYPlus1 = 1; pExt->uiChromaPhaseYPlus1 = 1;
uiChromaArrayType = pSpsExt->sSps.uiChromaArrayType; uiChromaArrayType = pSpsExt->sSps.uiChromaArrayType;
pExt->uiChromaPhaseXPlus1Flag = BsGetOneBit (pBs); WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //chroma_phase_x_plus1_flag
pExt->uiChromaPhaseYPlus1 = BsGetBits (pBs, 2); pExt->uiChromaPhaseXPlus1Flag = uiCode;
WELS_READ_VERIFY (BsGetBits (pBs, 2, &uiCode)); //chroma_phase_y_plus1
pExt->uiChromaPhaseYPlus1 = uiCode;
pExt->uiSeqRefLayerChromaPhaseXPlus1Flag = pExt->uiChromaPhaseXPlus1Flag; pExt->uiSeqRefLayerChromaPhaseXPlus1Flag = pExt->uiChromaPhaseXPlus1Flag;
pExt->uiSeqRefLayerChromaPhaseYPlus1 = pExt->uiChromaPhaseYPlus1; pExt->uiSeqRefLayerChromaPhaseYPlus1 = pExt->uiChromaPhaseYPlus1;
@ -640,28 +657,38 @@ int32_t DecodeSpsSvcExt (PWelsDecoderContext pCtx, PSubsetSps pSpsExt, PBitStrin
if (pExt->uiExtendedSpatialScalability == 1) { if (pExt->uiExtendedSpatialScalability == 1) {
SPosOffset* const kpPos = &pExt->sSeqScaledRefLayer; SPosOffset* const kpPos = &pExt->sSeqScaledRefLayer;
pExt->uiSeqRefLayerChromaPhaseXPlus1Flag = BsGetOneBit (pBs); WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //seq_ref_layer_chroma_phase_x_plus1_flag
pExt->uiSeqRefLayerChromaPhaseYPlus1 = BsGetBits (pBs, 2); 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, 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"); 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, 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"); 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, 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"); 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, 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"); 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; pExt->bAdaptiveTCoeffLevelPredFlag = false;
if (pExt->bSeqTCoeffLevelPredFlag) if (pExt->bSeqTCoeffLevelPredFlag) {
pExt->bAdaptiveTCoeffLevelPredFlag = !!BsGetOneBit (pBs); WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //adaptive_tcoeff_level_prediction_flag
pExt->bSliceHeaderRestrictionFlag = !!BsGetOneBit (pBs); 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 */ {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) { switch (iLevelIdx) {
case 10: case 10:
return &g_kSLevelLimits[0]; return &g_kSLevelLimits[0];
@ -765,7 +792,8 @@ int32_t ParseSps (PWelsDecoderContext pCtx, PBitStringAux pBsAux, int32_t* pPicW
ProfileIdc uiProfileIdc; ProfileIdc uiProfileIdc;
uint8_t uiLevelIdc; uint8_t uiLevelIdc;
int32_t iSpsId; int32_t iSpsId;
uint32_t uiTmp; uint32_t uiCode;
int32_t iCode;
bool bConstraintSetFlags[6] = { false }; bool bConstraintSetFlags[6] = { false };
const bool kbUseSubsetFlag = IS_SUBSET_SPS_NAL (pNalHead->eNalUnitType); 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 #endif //MOSAIC_AVOID_BASED_ON_SPS_PPS_ID
} }
uiProfileIdc = BsGetBits (pBs, 8); WELS_READ_VERIFY (BsGetBits (pBs, 8, &uiCode)); //profile_idc
bConstraintSetFlags[0] = !!BsGetOneBit (pBs); // constraint_set0_flag uiProfileIdc = uiCode;
bConstraintSetFlags[1] = !!BsGetOneBit (pBs); // constraint_set1_flag WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //constraint_set0_flag
bConstraintSetFlags[2] = !!BsGetOneBit (pBs); // constraint_set2_flag bConstraintSetFlags[0] = !!uiCode;
bConstraintSetFlags[3] = !!BsGetOneBit (pBs); // constraint_set3_flag WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //constraint_set1_flag
bConstraintSetFlags[4] = !!BsGetOneBit (pBs); // constraint_set4_flag bConstraintSetFlags[1] = !!uiCode;
bConstraintSetFlags[5] = !!BsGetOneBit (pBs); // constraint_set5_flag WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //constraint_set2_flag
BsGetBits (pBs, 2); // reserved_zero_2bits, equal to 0 bConstraintSetFlags[2] = !!uiCode;
uiLevelIdc = BsGetBits (pBs, 8); // level_idc WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //constraint_set3_flag
iSpsId = BsGetUe (pBs); // seq_parameter_set_id 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 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"); WelsLog (pCtx, WELS_LOG_WARNING, " iSpsId is out of range! \n");
return GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_SPS_ID_OVERFLOW); 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_HIGH422 == uiProfileIdc || PRO_HIGH444 == uiProfileIdc ||
PRO_CAVLC444 == uiProfileIdc || 44 == 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) { if (pSps->uiChromaFormatIdc != 1) {
WelsLog (pCtx, WELS_LOG_WARNING, "ParseSps(): chroma_format_idc (%d) = 1 supported.\n", pSps->uiChromaFormatIdc); 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); return GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_UNSUPPORTED_NON_BASELINE);
} }
pSps->uiChromaArrayType = pSps->uiChromaFormatIdc; 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) { if (pSps->uiBitDepthLuma != 8) {
WelsLog (pCtx, WELS_LOG_WARNING, "ParseSps(): bit_depth_luma (%d) Only 8 bit supported.\n", pSps->uiBitDepthLuma); 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); 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) { if (pSps->uiBitDepthChroma != 8) {
WelsLog (pCtx, WELS_LOG_WARNING, "ParseSps(): bit_depth_chroma (%d). Only 8 bit supported.\n", pSps->uiBitDepthChroma); 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); return GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_UNSUPPORTED_NON_BASELINE);
} }
pSps->bQpPrimeYZeroTransfBypassFlag = !!BsGetOneBit (pBs); WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //qpprime_y_zero_transform_bypass_flag
pSps->bSeqScalingMatrixPresentFlag = !!BsGetOneBit (pBs); 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 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", 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); return GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_UNSUPPORTED_NON_BASELINE);
} }
} }
uiTmp = BsGetUe (pBs); WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //log2_max_frame_num_minus4
WELS_CHECK_SE_UPPER_ERROR (uiTmp, SPS_LOG2_MAX_FRAME_NUM_MINUS4_MAX, "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)); 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->uiLog2MaxFrameNum = LOG2_MAX_FRAME_NUM_OFFSET + uiCode;
pSps->uiPocType = BsGetUe (pBs); // pic_order_cnt_type WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //pic_order_cnt_type
pSps->uiPocType = uiCode;
if (0 == pSps->uiPocType) { 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) // 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)); 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) { } else if (1 == pSps->uiPocType) {
int32_t i; int32_t i;
pSps->bDeltaPicOrderAlwaysZeroFlag = !!BsGetOneBit (pBs); // bDeltaPicOrderAlwaysZeroFlag WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //delta_pic_order_always_zero_flag
pSps->iOffsetForNonRefPic = BsGetSe (pBs); // iOffsetForNonRefPic pSps->bDeltaPicOrderAlwaysZeroFlag = !!uiCode;
pSps->iOffsetForTopToBottomField = BsGetSe (pBs); // iOffsetForTopToBottomField WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //offset_for_non_ref_pic
uiTmp = BsGetUe (pBs); pSps->iOffsetForNonRefPic = iCode;
WELS_CHECK_SE_UPPER_ERROR (uiTmp, SPS_NUM_REF_FRAMES_IN_PIC_ORDER_CNT_CYCLE_MAX, 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, "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)); ERR_INFO_INVALID_NUM_REF_FRAME_IN_PIC_ORDER_CNT_CYCLE));
pSps->iNumRefFramesInPocCycle = uiTmp; // num_ref_frames_in_pic_order_cnt_cycle pSps->iNumRefFramesInPocCycle = uiCode;
for (i = 0; i < pSps->iNumRefFramesInPocCycle; i++) for (i = 0; i < pSps->iNumRefFramesInPocCycle; i++) {
pSps->iOffsetForRefFrame[ i ] = BsGetSe (pBs); // iOffsetForRefFrame[ i ] WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //offset_for_ref_frame[ i ]
pSps->iOffsetForRefFrame[ i ] = iCode;
}
} }
if (pSps->uiPocType > 2) { if (pSps->uiPocType > 2) {
WelsLog (pCtx, WELS_LOG_WARNING, " illegal pic_order_cnt_type: %d ! \n", pSps->uiPocType); 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); return GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_INVALID_POC_TYPE);
} }
pSps->iNumRefFrames = BsGetUe (pBs); // max_num_ref_frames WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //max_num_ref_frames
pSps->bGapsInFrameNumValueAllowedFlag = !!BsGetOneBit (pBs); // bGapsInFrameNumValueAllowedFlag pSps->iNumRefFrames = uiCode;
uiTmp = BsGetUe (pBs); // pic_width_in_mbs_minus1 WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //gaps_in_frame_num_value_allowed_flag
if (uiTmp == 0xffffffff) { 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"); 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); 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)) { 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"); WelsLog (pCtx, WELS_LOG_WARNING, " the pic_width_in_mbs exceeds the level limits!\n");
} }
uiTmp = BsGetUe (pBs); // pic_height_in_map_units_minus1 WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //pic_height_in_map_units_minus1
if (uiTmp == 0xffffffff) { if (uiCode == 0xffffffff) {
WelsLog (pCtx, WELS_LOG_ERROR, " pic_height_in_mbs read error!\n"); 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); 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)) { 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"); 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) { if ((uint32_t)pSps->iNumRefFrames > uiMaxDpbFrames) {
WelsLog (pCtx, WELS_LOG_WARNING, " max_num_ref_frames exceeds level limits!\n"); 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) { if (!pSps->bFrameMbsOnlyFlag) {
WelsLog (pCtx, WELS_LOG_WARNING, "ParseSps(): frame_mbs_only_flag (%d) not supported.\n", 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); return GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_UNSUPPORTED_MBAFF);
} }
pSps->bDirect8x8InferenceFlag = !!BsGetOneBit (pBs); // direct_8x8_inference_flag WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //direct_8x8_inference_flag
pSps->bFrameCroppingFlag = !!BsGetOneBit (pBs); // frame_cropping_flag pSps->bDirect8x8InferenceFlag = !!uiCode;
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //frame_cropping_flag
pSps->bFrameCroppingFlag = !!uiCode;
if (pSps->bFrameCroppingFlag) { if (pSps->bFrameCroppingFlag) {
pSps->sFrameCrop.iLeftOffset = BsGetUe (pBs); // frame_crop_left_offset WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //frame_crop_left_offset
pSps->sFrameCrop.iRightOffset = BsGetUe (pBs); // frame_crop_right_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)) { 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"); 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 WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //frame_crop_top_offset
pSps->sFrameCrop.iBottomOffset = BsGetUe (pBs); // frame_crop_bottom_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)) { 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"); 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.iTopOffset = 0; // frame_crop_top_offset
pSps->sFrameCrop.iBottomOffset = 0; // frame_crop_bottom_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 // Check if SPS SVC extension applicated
if (kbUseSubsetFlag && (PRO_SCALABLE_BASELINE == uiProfileIdc || PRO_SCALABLE_HIGH == uiProfileIdc)) { 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; return -1;
} }
pSubsetSps->bSvcVuiParamPresentFlag = !!BsGetOneBit (pBs); WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //svc_vui_parameters_present_flag
pSubsetSps->bSvcVuiParamPresentFlag = !!uiCode;
if (pSubsetSps->bSvcVuiParamPresentFlag) { if (pSubsetSps->bSvcVuiParamPresentFlag) {
} }
} }
@ -1005,8 +1064,11 @@ int32_t ParsePps (PWelsDecoderContext pCtx, PPps pPpsList, PBitStringAux pBsAux)
PPps pPps = NULL; PPps pPps = NULL;
uint32_t uiPpsId = 0; uint32_t uiPpsId = 0;
uint32_t iTmp; 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) { if (uiPpsId >= MAX_PPS_COUNT) {
return ERR_INFO_PPS_ID_OVERFLOW; return ERR_INFO_PPS_ID_OVERFLOW;
} }
@ -1019,23 +1081,28 @@ int32_t ParsePps (PWelsDecoderContext pCtx, PPps pPpsList, PBitStringAux pBsAux)
pPps->iPpsId = uiPpsId; 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) { if (pPps->iSpsId >= MAX_SPS_COUNT) {
return ERR_INFO_SPS_ID_OVERFLOW; return ERR_INFO_SPS_ID_OVERFLOW;
} }
pPps->bEntropyCodingModeFlag = !!BsGetOneBit (pBsAux); WELS_READ_VERIFY (BsGetOneBit (pBsAux, &uiCode)); //entropy_coding_mode_flag
pPps->bPicOrderPresentFlag = !!BsGetOneBit (pBsAux); 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) { if (pPps->uiNumSliceGroups > MAX_SLICEGROUP_IDS) {
return ERR_INFO_INVALID_SLICEGROUP; return ERR_INFO_INVALID_SLICEGROUP;
} }
if (pPps->uiNumSliceGroups > 1) { 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) { if (pPps->uiSliceGroupMapType > 1) {
WelsLog (pCtx, WELS_LOG_WARNING, "ParsePps(): slice_group_map_type (%d): support only 0,1.\n", WelsLog (pCtx, WELS_LOG_WARNING, "ParsePps(): slice_group_map_type (%d): support only 0,1.\n",
pPps->uiSliceGroupMapType); pPps->uiSliceGroupMapType);
@ -1045,7 +1112,8 @@ int32_t ParsePps (PWelsDecoderContext pCtx, PPps pPpsList, PBitStringAux pBsAux)
switch (pPps->uiSliceGroupMapType) { switch (pPps->uiSliceGroupMapType) {
case 0: case 0:
for (iTmp = 0; iTmp < pPps->uiNumSliceGroups; iTmp++) { 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; break;
default: 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); WELS_READ_VERIFY (BsGetUe (pBsAux, &uiCode)); //num_ref_idx_l0_default_active_minus1
pPps->uiNumRefIdxL1Active = NUM_REF_IDX_L1_DEFAULT_ACTIVE_OFFSET + BsGetUe (pBsAux); 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 || if (pPps->uiNumRefIdxL0Active > MAX_REF_PIC_COUNT ||
pPps->uiNumRefIdxL1Active > MAX_REF_PIC_COUNT) { pPps->uiNumRefIdxL1Active > MAX_REF_PIC_COUNT) {
return ERR_INFO_REF_COUNT_OVERFLOW; return ERR_INFO_REF_COUNT_OVERFLOW;
} }
pPps->bWeightedPredFlag = !!BsGetOneBit (pBsAux); WELS_READ_VERIFY (BsGetOneBit (pBsAux, &uiCode)); //weighted_pred_flag
pPps->uiWeightedBipredIdc = BsGetBits (pBsAux, 2); pPps->bWeightedPredFlag = !!uiCode;
WELS_READ_VERIFY (BsGetBits (pBsAux, 2, &uiCode)); //weighted_bipred_idc
pPps->uiWeightedBipredIdc = uiCode;
if (pPps->bWeightedPredFlag || pPps->uiWeightedBipredIdc != 0) { if (pPps->bWeightedPredFlag || pPps->uiWeightedBipredIdc != 0) {
WelsLog (pCtx, WELS_LOG_WARNING, "ParsePps(): weighted_pred_flag (%d) weighted_bipred_idc (%d) neither supported.\n", WelsLog (pCtx, WELS_LOG_WARNING, "ParsePps(): weighted_pred_flag (%d) weighted_bipred_idc (%d) neither supported.\n",
pPps->bWeightedPredFlag, pPps->uiWeightedBipredIdc); pPps->bWeightedPredFlag, pPps->uiWeightedBipredIdc);
return GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_UNSUPPORTED_WP); 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", 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)); 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", 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)); 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, 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)); "chroma_qp_index_offset", GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_INVALID_CHROMA_QP_INDEX_OFFSET));
pPps->bDeblockingFilterControlPresentFlag = !!BsGetOneBit (pBsAux); WELS_READ_VERIFY (BsGetOneBit (pBsAux, &uiCode)); //deblocking_filter_control_present_flag
pPps->bConstainedIntraPredFlag = !!BsGetOneBit (pBsAux); pPps->bDeblockingFilterControlPresentFlag = !!uiCode;
pPps->bRedundantPicCntPresentFlag = !!BsGetOneBit (pBsAux); 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 #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, 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 i;
int32_t iOffsetDst = 0, iOffsetSrc = 0; int32_t iOffsetDst = 0, iOffsetSrc = 0;
for (i = 0; i < iHeight; i++) { for (i = 0; i < iHeight; i++) {
@ -491,13 +491,16 @@ int32_t WelsActualDecodeMbCavlcISlice (PWelsDecoderContext pCtx) {
int32_t iMbXy = pCurLayer->iMbXyIndex; int32_t iMbXy = pCurLayer->iMbXyIndex;
int32_t iNMbMode, i; int32_t iNMbMode, i;
uint32_t uiMbType = 0, uiCbp = 0, uiCbpL = 0, uiCbpC = 0; 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); ENFORCE_STACK_ALIGN_1D (uint8_t, pNonZeroCount, 48, 16);
pCurLayer->pInterPredictionDoneFlag[iMbXy] = 0; pCurLayer->pInterPredictionDoneFlag[iMbXy] = 0;
pCurLayer->pResidualPredFlag[iMbXy] = pSlice->sSliceHeaderExt.bDefaultResidualPredFlag; pCurLayer->pResidualPredFlag[iMbXy] = pSlice->sSliceHeaderExt.bDefaultResidualPredFlag;
uiMbType = BsGetUe (pBs); WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //mb_type
uiMbType = uiCode;
if (uiMbType > 25) { if (uiMbType > 25) {
return ERR_INFO_INVALID_MB_TYPE; return ERR_INFO_INVALID_MB_TYPE;
} }
@ -561,7 +564,8 @@ int32_t WelsActualDecodeMbCavlcISlice (PWelsDecoderContext pCtx) {
} }
//uiCbp //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 //G.9.1 Alternative parsing process for coded pBlock pattern
if (uiCbp > 47) if (uiCbp > 47)
return ERR_INFO_INVALID_CBP; return ERR_INFO_INVALID_CBP;
@ -603,7 +607,8 @@ int32_t WelsActualDecodeMbCavlcISlice (PWelsDecoderContext pCtx) {
if (pCurLayer->pCbp[iMbXy] || MB_TYPE_INTRA16x16 == pCurLayer->pMbType[iMbXy]) { if (pCurLayer->pCbp[iMbXy] || MB_TYPE_INTRA16x16 == pCurLayer->pMbType[iMbXy]) {
int32_t iQpDelta, iId8x8, iId4x4; 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 if (iQpDelta > 25 || iQpDelta < -26) { //out of iQpDelta range
return ERR_INFO_INVALID_QP; return ERR_INFO_INVALID_QP;
@ -732,9 +737,11 @@ int32_t WelsDecodeMbCavlcISlice (PWelsDecoderContext pCtx, PNalUnit pNalCur) {
PSliceHeaderExt pSliceHeaderExt = &pCurLayer->sLayerInfo.sSliceInLayer.sSliceHeaderExt; PSliceHeaderExt pSliceHeaderExt = &pCurLayer->sLayerInfo.sSliceInLayer.sSliceHeaderExt;
int32_t iBaseModeFlag; int32_t iBaseModeFlag;
int32_t iRet = 0; //should have the return value to indicate decoding error or not, It's NECESSARY--2010.4.15 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) { if (pSliceHeaderExt->bAdaptiveBaseModeFlag == 1) {
iBaseModeFlag = BsGetOneBit (pBs); WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //base_mode_flag
iBaseModeFlag = uiCode;
} else { } else {
iBaseModeFlag = pSliceHeaderExt->bDefaultBaseModeFlag; iBaseModeFlag = pSliceHeaderExt->bDefaultBaseModeFlag;
} }
@ -769,11 +776,14 @@ int32_t WelsActualDecodeMbCavlcPSlice (PWelsDecoderContext pCtx) {
int32_t iNMbMode, i; int32_t iNMbMode, i;
uint32_t uiMbType = 0, uiCbp = 0, uiCbpL = 0, uiCbpC = 0; 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); ENFORCE_STACK_ALIGN_1D (uint8_t, pNonZeroCount, 48, 16);
pCurLayer->pInterPredictionDoneFlag[iMbXy] = 0;//2009.10.23 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 if (uiMbType < 5) { //inter MB type
int16_t iMotionVector[LIST_A][30][MV_A]; int16_t iMotionVector[LIST_A][30][MV_A];
@ -785,7 +795,8 @@ int32_t WelsActualDecodeMbCavlcPSlice (PWelsDecoderContext pCtx) {
} }
if (pSlice->sSliceHeaderExt.bAdaptiveResidualPredFlag == 1) { if (pSlice->sSliceHeaderExt.bAdaptiveResidualPredFlag == 1) {
pCurLayer->pResidualPredFlag[iMbXy] = BsGetOneBit (pBs); WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //residual_prediction_flag
pCurLayer->pResidualPredFlag[iMbXy] = uiCode;
} else { } else {
pCurLayer->pResidualPredFlag[iMbXy] = pSlice->sSliceHeaderExt.bDefaultResidualPredFlag; pCurLayer->pResidualPredFlag[iMbXy] = pSlice->sSliceHeaderExt.bDefaultResidualPredFlag;
} }
@ -882,7 +893,8 @@ int32_t WelsActualDecodeMbCavlcPSlice (PWelsDecoderContext pCtx) {
} }
if (MB_TYPE_INTRA16x16 != pCurLayer->pMbType[iMbXy]) { if (MB_TYPE_INTRA16x16 != pCurLayer->pMbType[iMbXy]) {
uiCbp = BsGetUe (pBs); WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //coded_block_pattern
uiCbp = uiCode;
{ {
if (uiCbp > 47) if (uiCbp > 47)
return ERR_INFO_INVALID_CBP; return ERR_INFO_INVALID_CBP;
@ -918,7 +930,8 @@ int32_t WelsActualDecodeMbCavlcPSlice (PWelsDecoderContext pCtx) {
if (pCurLayer->pCbp[iMbXy] || MB_TYPE_INTRA16x16 == pCurLayer->pMbType[iMbXy]) { if (pCurLayer->pCbp[iMbXy] || MB_TYPE_INTRA16x16 == pCurLayer->pMbType[iMbXy]) {
int32_t iQpDelta, iId8x8, iId4x4; 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 if (iQpDelta > 25 || iQpDelta < -26) { //out of iQpDelta range
return ERR_INFO_INVALID_QP; return ERR_INFO_INVALID_QP;
@ -1048,9 +1061,11 @@ int32_t WelsDecodeMbCavlcPSlice (PWelsDecoderContext pCtx, PNalUnit pNalCur) {
int32_t iMbXy = pCurLayer->iMbXyIndex; int32_t iMbXy = pCurLayer->iMbXyIndex;
int32_t iBaseModeFlag, i; 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 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) { if (-1 == pSlice->iMbSkipRun) {
pSlice->iMbSkipRun = BsGetUe (pBs); WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //mb_skip_run
pSlice->iMbSkipRun = uiCode;
if (-1 == pSlice->iMbSkipRun) { if (-1 == pSlice->iMbSkipRun) {
return -1; return -1;
} }
@ -1094,7 +1109,8 @@ int32_t WelsDecodeMbCavlcPSlice (PWelsDecoderContext pCtx, PNalUnit pNalCur) {
} }
if (pSlice->sSliceHeaderExt.bAdaptiveBaseModeFlag == 1) { if (pSlice->sSliceHeaderExt.bAdaptiveBaseModeFlag == 1) {
iBaseModeFlag = BsGetOneBit (pBs); WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //base_mode_flag
iBaseModeFlag = uiCode;
} else { } else {
iBaseModeFlag = pSlice->sSliceHeaderExt.bDefaultBaseModeFlag; iBaseModeFlag = pSlice->sSliceHeaderExt.bDefaultBaseModeFlag;
} }

View File

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

View File

@ -477,7 +477,8 @@ void BsStartCavlc (PBitStringAux pBs) {
} }
void BsEndCavlc (PBitStringAux pBs) { void BsEndCavlc (PBitStringAux pBs) {
pBs->pCurBuf = pBs->pStartBuf + (pBs->iIndex >> 3); 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->uiCurBits = uiCache32Bit << (pBs->iIndex & 0x07);
pBs->pCurBuf += 4; pBs->pCurBuf += 4;
pBs->iLeftBits = -16 + (pBs->iIndex & 0x07); 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); uint8_t bChroma = (bChromaDc || CHROMA_AC == iResidualProperty);
SReadBitsCache sReadBitsCache; 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.uiCache32Bit = uiCache32Bit << (iCurIdx & 0x07);
sReadBitsCache.uiRemainBits = 32 - (iCurIdx & 0x07); sReadBitsCache.uiRemainBits = 32 - (iCurIdx & 0x07);
sReadBitsCache.pBuf = pBuf; sReadBitsCache.pBuf = pBuf;
@ -782,7 +783,7 @@ int32_t ParseIntra4x4ModeConstrain0 (PNeighAvail pNeighAvail, int8_t* pIntraPred
int32_t iFinalMode, i; int32_t iFinalMode, i;
uint8_t uiNeighAvail = 0; uint8_t uiNeighAvail = 0;
uint32_t uiTmp; uint32_t uiCode;
if (pNeighAvail->iLeftAvail) { //left if (pNeighAvail->iLeftAvail) { //left
iSampleAvail[ 6] = iSampleAvail[ 6] =
iSampleAvail[12] = iSampleAvail[12] =
@ -805,14 +806,16 @@ int32_t ParseIntra4x4ModeConstrain0 (PNeighAvail pNeighAvail, int8_t* pIntraPred
uiNeighAvail = (iSampleAvail[6] << 2) | (iSampleAvail[0] << 1) | (iSampleAvail[1]); uiNeighAvail = (iSampleAvail[6] << 2) | (iSampleAvail[0] << 1) | (iSampleAvail[1]);
for (i = 0; i < 16; i++) { 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); const int32_t kiPredMode = PredIntra4x4Mode (pIntraPredMode, i);
int8_t iBestMode; int8_t iBestMode;
if (kiPrevIntra4x4PredMode) { if (kiPrevIntra4x4PredMode) {
iBestMode = kiPredMode; iBestMode = kiPredMode;
} else { //kPrevIntra4x4PredMode == 0 } 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) { if (kiRemIntra4x4PredMode < kiPredMode) {
iBestMode = kiRemIntra4x4PredMode; iBestMode = kiRemIntra4x4PredMode;
} else { } else {
@ -835,11 +838,11 @@ int32_t ParseIntra4x4ModeConstrain0 (PNeighAvail pNeighAvail, int8_t* pIntraPred
pCurDqLayer->pIntraPredMode[iMbXy][4] = pIntraPredMode[4 + 8 * 1]; pCurDqLayer->pIntraPredMode[iMbXy][4] = pIntraPredMode[4 + 8 * 1];
pCurDqLayer->pIntraPredMode[iMbXy][5] = pIntraPredMode[4 + 8 * 2]; pCurDqLayer->pIntraPredMode[iMbXy][5] = pIntraPredMode[4 + 8 * 2];
pCurDqLayer->pIntraPredMode[iMbXy][6] = pIntraPredMode[4 + 8 * 3]; pCurDqLayer->pIntraPredMode[iMbXy][6] = pIntraPredMode[4 + 8 * 3];
uiTmp = BsGetUe (pBs); WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //intra_chroma_pred_mode
if (uiTmp > MAX_PRED_MODE_ID_CHROMA) { if (uiCode > MAX_PRED_MODE_ID_CHROMA) {
return ERR_INFO_INVALID_I_CHROMA_PRED_MODE; return ERR_INFO_INVALID_I_CHROMA_PRED_MODE;
} }
pCurDqLayer->pChromaPredMode[iMbXy] = uiTmp; pCurDqLayer->pChromaPredMode[iMbXy] = uiCode;
if (CheckIntraChromaPredMode (uiNeighAvail, &pCurDqLayer->pChromaPredMode[iMbXy])) { if (CheckIntraChromaPredMode (uiNeighAvail, &pCurDqLayer->pChromaPredMode[iMbXy])) {
return ERR_INFO_INVALID_I_CHROMA_PRED_MODE; return ERR_INFO_INVALID_I_CHROMA_PRED_MODE;
} }
@ -854,7 +857,7 @@ int32_t ParseIntra4x4ModeConstrain1 (PNeighAvail pNeighAvail, int8_t* pIntraPred
int32_t iFinalMode, i; int32_t iFinalMode, i;
uint8_t uiNeighAvail = 0; uint8_t uiNeighAvail = 0;
uint32_t uiTmp; uint32_t uiCode;
if (pNeighAvail->iLeftAvail && IS_INTRA (pNeighAvail->iLeftType)) { //left if (pNeighAvail->iLeftAvail && IS_INTRA (pNeighAvail->iLeftType)) { //left
iSampleAvail[ 6] = iSampleAvail[ 6] =
iSampleAvail[12] = iSampleAvail[12] =
@ -877,14 +880,16 @@ int32_t ParseIntra4x4ModeConstrain1 (PNeighAvail pNeighAvail, int8_t* pIntraPred
uiNeighAvail = (iSampleAvail[6] << 2) | (iSampleAvail[0] << 1) | (iSampleAvail[1]); uiNeighAvail = (iSampleAvail[6] << 2) | (iSampleAvail[0] << 1) | (iSampleAvail[1]);
for (i = 0; i < 16; i++) { 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); const int32_t kiPredMode = PredIntra4x4Mode (pIntraPredMode, i);
int8_t iBestMode; int8_t iBestMode;
if (kiPrevIntra4x4PredMode) { if (kiPrevIntra4x4PredMode) {
iBestMode = kiPredMode; iBestMode = kiPredMode;
} else { //kPrevIntra4x4PredMode == 0 } 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) { if (kiRemIntra4x4PredMode < kiPredMode) {
iBestMode = kiRemIntra4x4PredMode; iBestMode = kiRemIntra4x4PredMode;
} else { } else {
@ -907,11 +912,11 @@ int32_t ParseIntra4x4ModeConstrain1 (PNeighAvail pNeighAvail, int8_t* pIntraPred
pCurDqLayer->pIntraPredMode[iMbXy][4] = pIntraPredMode[4 + 8 * 1]; pCurDqLayer->pIntraPredMode[iMbXy][4] = pIntraPredMode[4 + 8 * 1];
pCurDqLayer->pIntraPredMode[iMbXy][5] = pIntraPredMode[4 + 8 * 2]; pCurDqLayer->pIntraPredMode[iMbXy][5] = pIntraPredMode[4 + 8 * 2];
pCurDqLayer->pIntraPredMode[iMbXy][6] = pIntraPredMode[4 + 8 * 3]; pCurDqLayer->pIntraPredMode[iMbXy][6] = pIntraPredMode[4 + 8 * 3];
uiTmp = BsGetUe (pBs); WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //intra_chroma_pred_mode
if (uiTmp > MAX_PRED_MODE_ID_CHROMA) { if (uiCode > MAX_PRED_MODE_ID_CHROMA) {
return ERR_INFO_INVALID_I_CHROMA_PRED_MODE; return ERR_INFO_INVALID_I_CHROMA_PRED_MODE;
} }
pCurDqLayer->pChromaPredMode[iMbXy] = uiTmp; pCurDqLayer->pChromaPredMode[iMbXy] = uiCode;
if (CheckIntraChromaPredMode (uiNeighAvail, &pCurDqLayer->pChromaPredMode[iMbXy])) { if (CheckIntraChromaPredMode (uiNeighAvail, &pCurDqLayer->pChromaPredMode[iMbXy])) {
return ERR_INFO_INVALID_I_CHROMA_PRED_MODE; 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 ParseIntra16x16ModeConstrain0 (PNeighAvail pNeighAvail, PBitStringAux pBs, PDqLayer pCurDqLayer) {
int32_t iMbXy = pCurDqLayer->iMbXyIndex; 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) 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) { if (pNeighAvail->iLeftAvail) {
uiNeighAvail = (1 << 2); uiNeighAvail = (1 << 2);
} }
@ -937,11 +942,11 @@ int32_t ParseIntra16x16ModeConstrain0 (PNeighAvail pNeighAvail, PBitStringAux pB
&pCurDqLayer->pIntraPredMode[iMbXy][7])) { //invalid iPredMode, must stop decoding &pCurDqLayer->pIntraPredMode[iMbXy][7])) { //invalid iPredMode, must stop decoding
return ERR_INFO_INVALID_I16x16_PRED_MODE; return ERR_INFO_INVALID_I16x16_PRED_MODE;
} }
uiTmp = BsGetUe (pBs); WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //intra_chroma_pred_mode
if (uiTmp > MAX_PRED_MODE_ID_CHROMA) { if (uiCode > MAX_PRED_MODE_ID_CHROMA) {
return ERR_INFO_INVALID_I_CHROMA_PRED_MODE; return ERR_INFO_INVALID_I_CHROMA_PRED_MODE;
} }
pCurDqLayer->pChromaPredMode[iMbXy] = uiTmp; pCurDqLayer->pChromaPredMode[iMbXy] = uiCode;
if (CheckIntraChromaPredMode (uiNeighAvail, &pCurDqLayer->pChromaPredMode[iMbXy])) { if (CheckIntraChromaPredMode (uiNeighAvail, &pCurDqLayer->pChromaPredMode[iMbXy])) {
return ERR_INFO_INVALID_I_CHROMA_PRED_MODE; 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 ParseIntra16x16ModeConstrain1 (PNeighAvail pNeighAvail, PBitStringAux pBs, PDqLayer pCurDqLayer) {
int32_t iMbXy = pCurDqLayer->iMbXyIndex; 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) 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)) { if (pNeighAvail->iLeftAvail && IS_INTRA (pNeighAvail->iLeftType)) {
uiNeighAvail = (1 << 2); uiNeighAvail = (1 << 2);
} }
@ -968,11 +973,11 @@ int32_t ParseIntra16x16ModeConstrain1 (PNeighAvail pNeighAvail, PBitStringAux pB
&pCurDqLayer->pIntraPredMode[iMbXy][7])) { //invalid iPredMode, must stop decoding &pCurDqLayer->pIntraPredMode[iMbXy][7])) { //invalid iPredMode, must stop decoding
return ERR_INFO_INVALID_I16x16_PRED_MODE; return ERR_INFO_INVALID_I16x16_PRED_MODE;
} }
uiTmp = BsGetUe (pBs); WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //intra_chroma_pred_mode
if (uiTmp > MAX_PRED_MODE_ID_CHROMA) { if (uiCode > MAX_PRED_MODE_ID_CHROMA) {
return ERR_INFO_INVALID_I_CHROMA_PRED_MODE; return ERR_INFO_INVALID_I_CHROMA_PRED_MODE;
} }
pCurDqLayer->pChromaPredMode[iMbXy] = uiTmp; pCurDqLayer->pChromaPredMode[iMbXy] = uiCode;
if (CheckIntraChromaPredMode (uiNeighAvail, &pCurDqLayer->pChromaPredMode[iMbXy])) { if (CheckIntraChromaPredMode (uiNeighAvail, &pCurDqLayer->pChromaPredMode[iMbXy])) {
return ERR_INFO_INVALID_I_CHROMA_PRED_MODE; 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 iMbXy = pCurDqLayer->iMbXyIndex;
int32_t iMotionPredFlag[4]; int32_t iMotionPredFlag[4];
int16_t iMv[2] = {0}; int16_t iMv[2] = {0};
uint32_t uiCode;
int32_t iCode;
int16_t iMinVmv = pSliceHeader->pSps->pSLevelLimits->iMinVmv; int16_t iMinVmv = pSliceHeader->pSps->pSLevelLimits->iMinVmv;
int16_t iMaxVmv = pSliceHeader->pSps->pSLevelLimits->iMaxVmv; int16_t iMaxVmv = pSliceHeader->pSps->pSLevelLimits->iMaxVmv;
iMotionPredFlag[0] = iMotionPredFlag[1] = iMotionPredFlag[2] = iMotionPredFlag[3] = 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: { case MB_TYPE_16x16: {
int32_t iRefIdx = 0; int32_t iRefIdx = 0;
if (pSlice->sSliceHeaderExt.bAdaptiveMotionPredFlag) { 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) { 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 // 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. // 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 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); PredMv (iMvArray, iRefIdxArray, 0, 4, iRefIdx, iMv);
iMv[0] += BsGetSe (pBs); WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //mvd_l0[ mbPartIdx ][ 0 ][ compIdx ]
iMv[1] += BsGetSe (pBs); 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"); WELS_CHECK_SE_BOTH_WARNING (iMv[1], iMinVmv, iMaxVmv, "vertical mv");
UpdateP16x16MotionInfo (pCurDqLayer, iRefIdx, iMv); UpdateP16x16MotionInfo (pCurDqLayer, iRefIdx, iMv);
} }
@ -1029,7 +1040,8 @@ int32_t ParseInterInfo (PWelsDecoderContext pCtx, int16_t iMvArray[LIST_A][30][M
int32_t iRefIdx[2]; int32_t iRefIdx[2];
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
if (pSlice->sSliceHeaderExt.bAdaptiveMotionPredFlag) { 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"); WelsLog (pCtx, WELS_LOG_WARNING, "inter parse: iMotionPredFlag = 1 not supported. \n");
return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_UNSUPPORTED_ILP); 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 if ((iRefIdx[i] < 0) || (iRefIdx[i] >= iRefCount[0]) || (ppRefPic[iRefIdx[i]] == NULL)) { //error ref_idx
return ERR_INFO_INVALID_REF_INDEX; 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++) { for (i = 0; i < 2; i++) {
PredInter16x8Mv (iMvArray, iRefIdxArray, i << 3, iRefIdx[i], iMv); PredInter16x8Mv (iMvArray, iRefIdxArray, i << 3, iRefIdx[i], iMv);
iMv[0] += BsGetSe (pBs); WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //mvd_l0[ mbPartIdx ][ 0 ][ compIdx ]
iMv[1] += BsGetSe (pBs); 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"); WELS_CHECK_SE_BOTH_WARNING (iMv[1], iMinVmv, iMaxVmv, "vertical mv");
UpdateP16x8MotionInfo (pCurDqLayer, iMvArray, iRefIdxArray, i << 3, iRefIdx[i], iMv); 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]; int32_t iRefIdx[2];
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
if (pSlice->sSliceHeaderExt.bAdaptiveMotionPredFlag) { 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++) { for (i = 0; i < 2; i++) {
if (iMotionPredFlag[i] == 0) { 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 if ((iRefIdx[i] < 0) || (iRefIdx[i] >= iRefCount[0]) || (ppRefPic[iRefIdx[i]] == NULL)) { //error ref_idx
return ERR_INFO_INVALID_REF_INDEX; 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++) { for (i = 0; i < 2; i++) {
PredInter8x16Mv (iMvArray, iRefIdxArray, i << 2, iRefIdx[i], iMv); PredInter8x16Mv (iMvArray, iRefIdxArray, i << 2, iRefIdx[i], iMv);
iMv[0] += BsGetSe (pBs); WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //mvd_l0[ mbPartIdx ][ 0 ][ compIdx ]
iMv[1] += BsGetSe (pBs); 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"); WELS_CHECK_SE_BOTH_WARNING (iMv[1], iMinVmv, iMaxVmv, "vertical mv");
UpdateP8x16MotionInfo (pCurDqLayer, iMvArray, iRefIdxArray, i << 2, iRefIdx[i], iMv); 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 //uiSubMbType, partition
for (i = 0; i < 4; i++) { 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 if (uiSubMbType >= 4) { //invalid uiSubMbType
return ERR_INFO_INVALID_SUB_MB_TYPE; 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) { if (pSlice->sSliceHeaderExt.bAdaptiveMotionPredFlag) {
for (i = 0; i < 4; i++) { 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]; uint8_t uiScan4Idx = g_kuiScan4[iIndex8];
if (iMotionPredFlag[i] == 0) { 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 if ((iRefIdx[i] < 0) || (iRefIdx[i] >= iRefCount[0]) || (ppRefPic[iRefIdx[i]] == NULL)) { //error ref_idx
return ERR_INFO_INVALID_REF_INDEX; 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]; uiCacheIdx = g_kuiCache30ScanIdx[iPartIdx];
PredMv (iMvArray, iRefIdxArray, iPartIdx, iBlockWidth, iRefIdx[i], iMv); PredMv (iMvArray, iRefIdxArray, iPartIdx, iBlockWidth, iRefIdx[i], iMv);
iMv[0] += BsGetSe (pBs); WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //mvd_l0[ mbPartIdx ][ subMbPartIdx ][ compIdx ]
iMv[1] += BsGetSe (pBs); 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"); WELS_CHECK_SE_BOTH_WARNING (iMv[1], iMinVmv, iMaxVmv, "vertical mv");
if (SUB_MB_TYPE_8x8 == uiSubMbType) { if (SUB_MB_TYPE_8x8 == uiSubMbType) {
ST32 (pCurDqLayer->pMv[0][iMbXy][uiScan4Idx], LD32 (iMv)); ST32 (pCurDqLayer->pMv[0][iMbXy][uiScan4Idx], LD32 (iMv));