ref: 4ebaba864c1e8b4ef399860857dc29ca1c121a9a
parent: 5b5134eaeabb6620c68310a78cadcb7a8d473bce
author: huili2 <huili2@cisco.com>
date: Mon Nov 14 09:31:37 EST 2016
add part of VUI parse in sps, and add SAR option in GetOption()
--- a/codec/api/svc/codec_app_def.h
+++ b/codec/api/svc/codec_app_def.h
@@ -160,7 +160,8 @@
DECODER_OPTION_TRACE_CALLBACK, ///< a void (*)(void* context, int level, const char* message) function which receives log messages
DECODER_OPTION_TRACE_CALLBACK_CONTEXT,///< context info of trace callbac
- DECODER_OPTION_GET_STATISTICS
+ DECODER_OPTION_GET_STATISTICS, ///< feedback decoder statistics
+ DECODER_OPTION_GET_SAR_INFO, ///< feedback decoder Sample Aspect Ratio info in Vui
} DECODER_OPTION;
@@ -670,7 +671,7 @@
} SDecoderCapability;
/**
-* @brief to do
+* @brief Structure for parse only output
*/
typedef struct TagParserBsInfo {
int iNalNum; ///< total NAL number in current AU
@@ -737,5 +738,14 @@
int iSubSpsNoExistNalNum; ///< number of SubSps NoExist Nal
int iPpsNoExistNalNum; ///< number of Pps NoExist Nal
} SDecoderStatistics; // in building, coming soon
+
+/**
+* @brief Structure for sample aspect ratio (SAR) info in VUI
+*/
+typedef struct TagVuiSarInfo {
+ unsigned int uiSarWidth; ///< SAR width
+ unsigned int uiSarHeight; ///< SAR height
+ bool bOverscanAppropriateFlag; ///< SAR overscan flag
+} SVuiSarInfo, *PVuiSarInfo;
#endif//WELS_VIDEO_CODEC_APPLICATION_DEFINITION_H__
--- a/codec/common/inc/wels_common_defs.h
+++ b/codec/common/inc/wels_common_defs.h
@@ -214,6 +214,17 @@
MMCO_LONG = 6
};
+enum EVuiVideoFormat {
+ VUI_COMPONENT = 0,
+ VUI_PAL = 1,
+ VUI_NTSC = 2,
+ VUI_SECAM = 3,
+ VUI_MAC = 4,
+ VUI_UNSPECIFIED = 5,
+ VUI_RESERVED1 = 6,
+ VUI_RESERVED2 = 7
+};
+
/*
* Bit-stream auxiliary reading / writing
*/
--- a/codec/decoder/core/inc/au_parser.h
+++ b/codec/decoder/core/inc/au_parser.h
@@ -132,6 +132,22 @@
int32_t ParsePps (PWelsDecoderContext pCtx, PPps pPpsList, PBitStringAux pBsAux, uint8_t* pSrcNal, const int32_t kSrcNalLen);
/*!
+*************************************************************************************
+* \brief to parse Video Usability Information (VUI) parameter of the SPS
+*
+* \param pCtx Decoder context
+* \param pSps the sps which current Vui parameter belongs to
+* \param pBsAux bitstream reader auxiliary
+*
+* \return 0 - successed
+* 1 - failed
+*
+* \note Call it in case the flag "vui_parameters_present_flag" in sps is true.
+*************************************************************************************
+*/
+int32_t ParseVui(PWelsDecoderContext pCtx, PSps pSps, PBitStringAux pBsAux);
+
+/*!
*************************************************************************************
* \brief to parse scaling list message payload
*
--- a/codec/decoder/core/inc/dec_golomb.h
+++ b/codec/decoder/core/inc/dec_golomb.h
@@ -336,6 +336,10 @@
// From Level 5.2
#define MAX_MB_SIZE 36864
+// for aspect_ratio_idc
+#define EXTENDED_SAR 255
+// for chroma_sample_loc_type_top_field & chroma_sample_loc_type_bottom_field
+#define VUI_MAX_CHROMA_LOG_TYPE_TOP_BOTTOM_FIELD 5
} // namespace WelsDec
#endif//WELS_EXPONENTIAL_GOLOMB_ENTROPY_CODING_H__
--- a/codec/decoder/core/inc/parameter_sets.h
+++ b/codec/decoder/core/inc/parameter_sets.h
@@ -38,8 +38,31 @@
#include "wels_common_basis.h"
namespace WelsDec {
+ /* VUI syntax in Sequence Parameter Set, refer to E.1 in Rec */
+ typedef struct TagVui {
+ bool bAspectRatioInfoPresentFlag;
+ uint32_t uiAspectRatioIdc;
+ uint32_t uiSarWidth;
+ uint32_t uiSarHeight;
+ bool bOverscanInfoPresentFlag;
+ bool bOverscanAppropriateFlag;
+ bool bVideoSignalTypePresentFlag;
+ uint8_t uiVideoFormat;
+ bool bVideoFullRangeFlag;
+ bool bColourDescripPresentFlag;
+ uint8_t uiColourPrimaries;
+ uint8_t uiTransferCharacteristics;
+ uint8_t uiMatrixCoeffs;
+ bool bChromaLocInfoPresentFlag;
+ uint32_t uiChromaSampleLocTypeTopField;
+ uint32_t uiChromaSampleLocTypeBottomField;
+ bool bTimingInfoPresentFlag;
+ uint32_t uiNumUnitsInTick;
+ uint32_t uiTimeScale;
+ bool bFixedFrameRateFlag;
+ bool bNalHrdParamPresentFlag;
+ } SVui, *PVui;
-
/* Sequence Parameter Set, refer to Page 57 in JVT X201wcm */
typedef struct TagSps {
int32_t iSpsId;
@@ -91,7 +114,7 @@
//Add scaling list supporting
uint8_t iScalingList4x4[6][16];
uint8_t iScalingList8x8[6][64];
-
+ SVui sVui;
const SLevelLimits* pSLevelLimits;
} SSps, *PSps;
--- a/codec/decoder/core/inc/wels_common_basis.h
+++ b/codec/decoder/core/inc/wels_common_basis.h
@@ -251,6 +251,18 @@
{SUB_MB_TYPE_4x4, 4, 1},
};
+typedef struct TagSar {
+ uint32_t uiWidth;
+ uint32_t uiHeight;
+} sSar;
+static const sSar g_ksVuiSampleAspectRatio[17] = { //Table E-1
+ { 0, 0}, { 1, 1}, {12, 11}, { 10, 11}, {16,11}, //0~4
+ {40, 33}, {24, 11}, {20, 11}, { 32, 11}, {80,33}, //5~9
+ {18, 11}, {15, 11}, {64, 33}, {160, 99}, { 4, 3}, //10~14
+ { 3, 2}, { 2, 1} //15~16
+};
+
+
} // namespace WelsDec
#endif//WELS_COMMON_BASIS_H__
--- a/codec/decoder/core/src/au_parser.cpp
+++ b/codec/decoder/core/src/au_parser.cpp
@@ -1134,7 +1134,9 @@
}
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //vui_parameters_present_flag
pSps->bVuiParamPresentFlag = !!uiCode;
-
+ if (pSps->bVuiParamPresentFlag && !kbUseSubsetFlag) { //parse Part of Vui Parameters in avc sps only
+ WELS_READ_VERIFY (ParseVui (pCtx, pSps, pBsAux));
+ }
if (pCtx->pParam->bParseOnly) {
if (kSrcNalLen >= SPS_PPS_BS_SIZE - 4) { //sps bs exceeds!
pCtx->iErrorCode |= dsOutOfMemory;
@@ -1425,9 +1427,10 @@
if (memcmp (pCtx->pPps, pPps, sizeof (*pPps)) != 0) {
memcpy (&pCtx->sPpsBuffer[MAX_PPS_COUNT], pPps, sizeof (SPps));
pCtx->iOverwriteFlags |= OVERWRITE_PPS;
- pCtx->bAuReadyFlag = true;
- pCtx->pAccessUnitList->uiEndPos = (pCtx->pAccessUnitList->uiAvailUnitsNum > 0 ? (pCtx->pAccessUnitList->uiAvailUnitsNum
- - 1) : 0);
+ if (pCtx->pAccessUnitList->uiAvailUnitsNum > 0) {
+ pCtx->bAuReadyFlag = true;
+ pCtx->pAccessUnitList->uiEndPos = pCtx->pAccessUnitList->uiAvailUnitsNum - 1;
+ }
}
} else {
memcpy (&pCtx->sPpsBuffer[uiPpsId], pPps, sizeof (SPps));
@@ -1456,7 +1459,75 @@
}
return ERR_NONE;
}
+int32_t ParseVui (PWelsDecoderContext pCtx, PSps pSps, PBitStringAux pBsAux) {
+ uint32_t uiCode;
+ PVui pVui = &pSps->sVui;
+ WELS_READ_VERIFY (BsGetOneBit (pBsAux, &uiCode)); //aspect_ratio_info_present_flag
+ pVui->bAspectRatioInfoPresentFlag = !!uiCode;
+ if (pSps->sVui.bAspectRatioInfoPresentFlag) {
+ WELS_READ_VERIFY (BsGetBits (pBsAux, 8, &uiCode)); //aspect_ratio_idc
+ pVui->uiAspectRatioIdc = uiCode;
+ if (pVui->uiAspectRatioIdc < 17) {
+ pVui->uiSarWidth = g_ksVuiSampleAspectRatio[pVui->uiAspectRatioIdc].uiWidth;
+ pVui->uiSarHeight = g_ksVuiSampleAspectRatio[pVui->uiAspectRatioIdc].uiHeight;
+ } else if (pVui->uiAspectRatioIdc == EXTENDED_SAR) {
+ WELS_READ_VERIFY (BsGetBits (pBsAux, 16, &uiCode)); //sar_width
+ pVui->uiSarWidth = uiCode;
+ WELS_READ_VERIFY (BsGetBits (pBsAux, 16, &uiCode)); //sar_height
+ pVui->uiSarHeight = uiCode;
+ }
+ }
+ WELS_READ_VERIFY (BsGetOneBit (pBsAux, &uiCode)); //overscan_info_present_flag
+ pVui->bOverscanInfoPresentFlag = !!uiCode;
+ if (pVui->bOverscanInfoPresentFlag) {
+ WELS_READ_VERIFY (BsGetOneBit (pBsAux, &uiCode)); //overscan_appropriate_flag
+ pVui->bOverscanAppropriateFlag = !!uiCode;
+ }
+ WELS_READ_VERIFY (BsGetOneBit (pBsAux, &uiCode)); //video_signal_type_present_flag
+ pVui->bVideoSignalTypePresentFlag = !!uiCode;
+ if (pVui->bVideoSignalTypePresentFlag) {
+ WELS_READ_VERIFY (BsGetBits (pBsAux, 3, &uiCode)); //video_format
+ pVui->uiVideoFormat = uiCode;
+ WELS_READ_VERIFY (BsGetOneBit (pBsAux, &uiCode)); //video_full_range_flag
+ pVui->bVideoFullRangeFlag = !!uiCode;
+ WELS_READ_VERIFY (BsGetOneBit (pBsAux, &uiCode)); //colour_description_present_flag
+ pVui->bColourDescripPresentFlag = !!uiCode;
+ if (pVui->bColourDescripPresentFlag) {
+ WELS_READ_VERIFY (BsGetBits (pBsAux, 8, &uiCode)); //colour_primaries
+ pVui->uiColourPrimaries = uiCode;
+ WELS_READ_VERIFY (BsGetBits (pBsAux, 8, &uiCode)); //transfer_characteristics
+ pVui->uiTransferCharacteristics = uiCode;
+ WELS_READ_VERIFY (BsGetBits (pBsAux, 8, &uiCode)); //matrix_coefficients
+ pVui->uiMatrixCoeffs = uiCode;
+ }
+ }
+ WELS_READ_VERIFY (BsGetOneBit (pBsAux, &uiCode)); //chroma_loc_info_present_flag
+ pVui->bChromaLocInfoPresentFlag = !!uiCode;
+ if (pVui->bChromaLocInfoPresentFlag) {
+ WELS_READ_VERIFY (BsGetUe (pBsAux, &uiCode)); //chroma_sample_loc_type_top_field
+ pVui->uiChromaSampleLocTypeTopField = uiCode;
+ WELS_CHECK_SE_UPPER_WARNING (pVui->uiChromaSampleLocTypeTopField, VUI_MAX_CHROMA_LOG_TYPE_TOP_BOTTOM_FIELD,
+ "chroma_sample_loc_type_top_field");
+ WELS_READ_VERIFY (BsGetUe (pBsAux, &uiCode)); //chroma_sample_loc_type_bottom_field
+ pVui->uiChromaSampleLocTypeBottomField = uiCode;
+ WELS_CHECK_SE_UPPER_WARNING (pVui->uiChromaSampleLocTypeBottomField, VUI_MAX_CHROMA_LOG_TYPE_TOP_BOTTOM_FIELD,
+ "chroma_sample_loc_type_bottom_field");
+ }
+ WELS_READ_VERIFY (BsGetOneBit (pBsAux, &uiCode)); //timing_info_present_flag
+ pVui->bTimingInfoPresentFlag = !!uiCode;
+ if (pVui->bTimingInfoPresentFlag) {
+ WELS_READ_VERIFY (BsGetBits (pBsAux, 32, &uiCode)); //num_units_in_tick
+ pVui->uiNumUnitsInTick = uiCode;
+ WELS_CHECK_SE_LOWER_WARNING (pVui->uiNumUnitsInTick, 1, "num_units_in_tick");
+ WELS_READ_VERIFY (BsGetBits (pBsAux, 32, &uiCode)); //time_scale
+ pVui->uiTimeScale = uiCode;
+ WELS_READ_VERIFY (BsGetOneBit (pBsAux, &uiCode)); //fixed_frame_rate_flag
+ pVui->bFixedFrameRateFlag = !!uiCode;
+ }
+ //following HRD related parameters, omitted
+ return ERR_NONE;
+}
/*!
*************************************************************************************
* \brief to parse SEI message payload
--- a/codec/decoder/plus/src/welsDecoderExt.cpp
+++ b/codec/decoder/plus/src/welsDecoderExt.cpp
@@ -345,9 +345,11 @@
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_WARNING,
"CWelsDecoder::SetOption():DECODER_OPTION_GET_STATISTICS: this option is get-only!");
return cmInitParaError;
+ } else if (eOptID == DECODER_OPTION_GET_SAR_INFO) {
+ WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_WARNING,
+ "CWelsDecoder::SetOption():DECODER_OPTION_GET_SAR_INFO: this option is get-only!");
+ return cmInitParaError;
}
-
-
return cmInitParaError;
}
@@ -412,6 +414,17 @@
m_pDecContext->sDecoderStatistics.uiFreezingNonIDRNum);
}
return cmResultSuccess;
+ } else if (DECODER_OPTION_GET_SAR_INFO == eOptID) { //get decoder SAR info in VUI
+ PVuiSarInfo pVuiSarInfo = (static_cast<PVuiSarInfo> (pOption));
+ memset (pVuiSarInfo, 0, sizeof (SVuiSarInfo));
+ if (!m_pDecContext->pSps) {
+ return cmInitExpected;
+ } else {
+ pVuiSarInfo->uiSarWidth = m_pDecContext->pSps->sVui.uiSarWidth;
+ pVuiSarInfo->uiSarHeight = m_pDecContext->pSps->sVui.uiSarHeight;
+ pVuiSarInfo->bOverscanAppropriateFlag = m_pDecContext->pSps->sVui.bOverscanAppropriateFlag;
+ return cmResultSuccess;
+ }
}
return cmInitParaError;
binary files /dev/null b/res/SarVui.264 differ
--- a/test/decoder/DecUT_DecExt.cpp
+++ b/test/decoder/DecUT_DecExt.cpp
@@ -63,6 +63,8 @@
void TestTraceCallbackContext();
//DECODER_OPTION_GET_DECODER_STATICTIS
void TestGetDecStatistics();
+ //DECODER_OPTION_GET_SAR_INFO
+ void TestGetDecSarInfo();
//Do whole tests here
void DecoderInterfaceAll();
@@ -607,6 +609,33 @@
Uninit();
}
+
+//DECODER_OPTION_GET_SAR_INFO
+void DecoderInterfaceTest::TestGetDecSarInfo() {
+ CM_RETURN eRet;
+ int32_t iRet;
+ SVuiSarInfo sVuiSarInfo;
+
+ iRet = ValidInit();
+ ASSERT_EQ (iRet, ERR_NONE);
+ //GetOption before decoding
+ m_pDec->GetOption (DECODER_OPTION_GET_SAR_INFO, &sVuiSarInfo);
+ EXPECT_EQ (0u, sVuiSarInfo.uiSarWidth);
+ EXPECT_EQ (0u, sVuiSarInfo.uiSarHeight);
+ EXPECT_EQ (0u, sVuiSarInfo.bOverscanAppropriateFlag);
+ // setoption not support,
+ eRet = (CM_RETURN)m_pDec->SetOption (DECODER_OPTION_GET_SAR_INFO, NULL);
+ EXPECT_EQ (eRet, cmInitParaError);
+
+ //Decoder specific bs
+ DecoderBs ("res/SarVui.264");
+ m_pDec->GetOption (DECODER_OPTION_GET_SAR_INFO, &sVuiSarInfo);
+ EXPECT_EQ (80u, sVuiSarInfo.uiSarWidth); //DO NOT MODIFY the data value
+ EXPECT_EQ (33u, sVuiSarInfo.uiSarHeight); //DO NOT MODIFY the data value
+ EXPECT_EQ (1u, sVuiSarInfo.bOverscanAppropriateFlag); //DO NOT MODIFY the data value
+ Uninit();
+}
+
//TEST here for whole tests
TEST_F (DecoderInterfaceTest, DecoderInterfaceAll) {
@@ -636,6 +665,8 @@
TestTraceCallbackContext();
//DECODER_OPTION_GET_STATISTICS
TestGetDecStatistics();
+ //DECODER_OPTION_GET_SAR_INFO
+ TestGetDecSarInfo();
}
--- a/test/decoder/DecUT_ParseSyntax.cpp
+++ b/test/decoder/DecUT_ParseSyntax.cpp
@@ -164,7 +164,7 @@
m_sDecParam.uiTargetDqLayer = rand() % 100;
m_sDecParam.eEcActiveIdc = (ERROR_CON_IDC)7;
m_sDecParam.sVideoProperty.size = sizeof (SVideoProperty);
- m_sDecParam.sVideoProperty.eVideoBsType = (VIDEO_BITSTREAM_TYPE) (rand() % 3);
+ m_sDecParam.sVideoProperty.eVideoBsType = (VIDEO_BITSTREAM_TYPE) (rand() % 2);
m_sDecParam.bParseOnly = false;
m_pData[0] = m_pData[1] = m_pData[2] = NULL;