ref: 027f027c25c194e790f3b0ad9914bfce8f56d492
parent: 3e538617cdead5397f61af82dbb7b6eaafdff62c
parent: 03890fe86f4841264c5b83076de10fd4dde36fc7
author: HaiboZhu <haibozhu@cisco.com>
date: Thu Feb 25 05:49:34 EST 2016
Merge pull request #2371 from GregoryJWolfe/master Added support for "video signal type present" information.
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -1,4 +1,4 @@
-# Contributors to the OpenH264 project
+# Contributors to the OpenH264 project
Patrick Ai
Sijia Chen
@@ -35,6 +35,7 @@
Juanny Wang
Zhiliang Wang
Hervé Willems
+Gregory J Wolfe
Katherine Wu
Guang Xu
Jeffery Xu
--- a/codec/api/svc/codec_app_def.h
+++ b/codec/api/svc/codec_app_def.h
@@ -344,6 +344,77 @@
} SSliceArgument;
/**
+* @brief Enumerate the type of video format
+*/
+typedef enum {
+ VF_COMPONENT,
+ VF_PAL,
+ VF_NTSC,
+ VF_SECAM,
+ VF_MAC,
+ VF_UNDEF,
+ VF_NUM_ENUM
+} EVideoFormatSPS; // EVideoFormat is already defined/used elsewhere!
+
+/**
+* @brief Enumerate the type of color primaries
+*/
+typedef enum {
+ CP_RESERVED0,
+ CP_BT709,
+ CP_UNDEF,
+ CP_RESERVED3,
+ CP_BT470M,
+ CP_BT470BG,
+ CP_SMPTE170M,
+ CP_SMPTE240M,
+ CP_FILM,
+ CP_BT2020,
+ CP_NUM_ENUM
+} EColorPrimaries;
+
+/**
+* @brief Enumerate the type of transfer characteristics
+*/
+typedef enum {
+ TRC_RESERVED0,
+ TRC_BT709,
+ TRC_UNDEF,
+ TRC_RESERVED3,
+ TRC_BT470M,
+ TRC_BT470BG,
+ TRC_SMPTE170M,
+ TRC_SMPTE240M,
+ TRC_LINEAR,
+ TRC_LOG100,
+ TRC_LOG316,
+ TRC_IEC61966_2_4,
+ TRC_BT1361E,
+ TRC_IEC61966_2_1,
+ TRC_BT2020_10,
+ TRC_BT2020_12,
+ TRC_NUM_ENUM
+} ETransferCharacteristics;
+
+/**
+* @brief Enumerate the type of color matrix
+*/
+typedef enum {
+ CM_GBR,
+ CM_BT709,
+ CM_UNDEF,
+ CM_RESERVED3,
+ CM_FCC,
+ CM_BT470BG,
+ CM_SMPTE170M,
+ CM_SMPTE240M,
+ CM_YCGCO,
+ CM_BT2020NC,
+ CM_BT2020C,
+ CM_NUM_ENUM
+} EColorMatrix;
+
+/**
* @brief Structure for spatial layer configuration
*/
typedef struct {
@@ -357,6 +428,18 @@
int iDLayerQp; ///< value of level IDC (0 for auto-detection)
SSliceArgument sSliceArgument;
+
+ // Note: members bVideoSignalTypePresent through uiColorMatrix below are also defined in SWelsSPS in parameter_sets.h.
+ bool bVideoSignalTypePresent; // false => do not write any of the following information to the header
+ unsigned char uiVideoFormat; // EVideoFormatSPS; 3 bits in header; 0-5 => component, kpal, ntsc, secam, mac, undef
+ bool bFullRange; // false => analog video data range [16, 235]; true => full data range [0,255]
+ bool bColorDescriptionPresent; // false => do not write any of the following three items to the header
+ unsigned char uiColorPrimaries; // EColorPrimaries; 8 bits in header; 0 - 9 => ???, bt709, undef, ???, bt470m, bt470bg,
+ // smpte170m, smpte240m, film, bt2020
+ unsigned char uiTransferCharacteristics; // ETransferCharacteristics; 8 bits in header; 0 - 15 => ???, bt709, undef, ???, bt470m, bt470bg, smpte170m,
+ // smpte240m, linear, log100, log316, iec61966-2-4, bt1361e, iec61966-2-1, bt2020-10, bt2020-12
+ unsigned char uiColorMatrix; // EColorMatrix; 8 bits in header (corresponds to FFmpeg "colorspace"); 0 - 10 => GBR, bt709,
+ // undef, ???, fcc, bt470bg, smpte170m, smpte240m, YCgCo, bt2020nc, bt2020c
} SSpatialLayerConfig;
/**
--- a/codec/encoder/core/inc/param_svc.h
+++ b/codec/encoder/core/inc/param_svc.h
@@ -190,6 +190,16 @@
const int32_t kiLesserSliceNum = ((MAX_SLICES_NUM < MAX_SLICES_NUM_TMP) ? MAX_SLICES_NUM : MAX_SLICES_NUM_TMP);
for (int32_t idx = 0; idx < kiLesserSliceNum; idx++)
param.sSpatialLayers[iLayer].sSliceArgument.uiSliceMbNum[idx] = 0; //default, using one row a slice if uiSliceMode is SM_RASTER_MODE
+
+ // See codec_app_def.h for more info about members bVideoSignalTypePresent through uiColorMatrix. The default values
+ // used below preserve the previous behavior; i.e., no additional information will be written to the output file.
+ param.sSpatialLayers[iLayer].bVideoSignalTypePresent = false; // do not write any of the following information to the header
+ param.sSpatialLayers[iLayer].uiVideoFormat = VF_UNDEF; // undefined
+ param.sSpatialLayers[iLayer].bFullRange = false; // analog video data range [16, 235]
+ param.sSpatialLayers[iLayer].bColorDescriptionPresent = false; // do not write any of the following three items to the header
+ param.sSpatialLayers[iLayer].uiColorPrimaries = CP_UNDEF; // undefined
+ param.sSpatialLayers[iLayer].uiTransferCharacteristics = TRC_UNDEF; // undefined
+ param.sSpatialLayers[iLayer].uiColorMatrix = CM_UNDEF; // undefined
}
}
@@ -407,6 +417,15 @@
sizeof (SSliceArgument)) ;
pSpatialLayer->iDLayerQp = pCodingParam.sSpatialLayers[iIdxSpatial].iDLayerQp;
+
+ // See codec_app_def.h and parameter_sets.h for more info about members bVideoSignalTypePresent through uiColorMatrix.
+ pSpatialLayer->bVideoSignalTypePresent = pCodingParam.sSpatialLayers[iIdxSpatial].bVideoSignalTypePresent;
+ pSpatialLayer->uiVideoFormat = pCodingParam.sSpatialLayers[iIdxSpatial].uiVideoFormat;
+ pSpatialLayer->bFullRange = pCodingParam.sSpatialLayers[iIdxSpatial].bFullRange;
+ pSpatialLayer->bColorDescriptionPresent = pCodingParam.sSpatialLayers[iIdxSpatial].bColorDescriptionPresent;
+ pSpatialLayer->uiColorPrimaries = pCodingParam.sSpatialLayers[iIdxSpatial].uiColorPrimaries;
+ pSpatialLayer->uiTransferCharacteristics = pCodingParam.sSpatialLayers[iIdxSpatial].uiTransferCharacteristics;
+ pSpatialLayer->uiColorMatrix = pCodingParam.sSpatialLayers[iIdxSpatial].uiColorMatrix;
uiProfileIdc = (!bSimulcastAVC) ? PRO_SCALABLE_BASELINE : PRO_BASELINE;
++ pDlp;
--- a/codec/encoder/core/inc/parameter_sets.h
+++ b/codec/encoder/core/inc/parameter_sets.h
@@ -79,6 +79,19 @@
// bool bTimingInfoPresentFlag;
// bool bFixedFrameRateFlag;
+// Note: members bVideoSignalTypePresent through uiColorMatrix below are also defined in SSpatialLayerConfig in codec_app_def.h,
+// along with definitions for enumerators EVideoFormatSPS, EColorPrimaries, ETransferCharacteristics, and EColorMatrix.
+bool bVideoSignalTypePresent; // false => do not write any of the following information to the header
+uint8_t uiVideoFormat; // EVideoFormatSPS; 3 bits in header; 0-5 => component, kpal, ntsc, secam, mac, undef
+bool bFullRange; // false => analog video data range [16, 235]; true => full data range [0,255]
+bool bColorDescriptionPresent; // false => do not write any of the following three items to the header
+uint8_t uiColorPrimaries; // EColorPrimaries; 8 bits in header; 0 - 9 => ???, bt709, undef, ???, bt470m, bt470bg,
+ // smpte170m, smpte240m, film, bt2020
+uint8_t uiTransferCharacteristics; // ETransferCharacteristics; 8 bits in header; 0 - 15 => ???, bt709, undef, ???, bt470m, bt470bg, smpte170m,
+ // smpte240m, linear, log100, log316, iec61966-2-4, bt1361e, iec61966-2-1, bt2020-10, bt2020-12
+uint8_t uiColorMatrix; // EColorMatrix; 8 bits in header (corresponds to FFmpeg "colorspace"); 0 - 10 => GBR, bt709,
+ // undef, ???, fcc, bt470bg, smpte170m, smpte240m, YCgCo, bt2020nc, bt2020c
+
bool bConstraintSet0Flag;
bool bConstraintSet1Flag;
bool bConstraintSet2Flag;
--- a/codec/encoder/core/src/au_set.cpp
+++ b/codec/encoder/core/src/au_set.cpp
@@ -202,7 +202,27 @@
BsWriteOneBit (pLocalBitStringAux, false); //aspect_ratio_info_present_flag
BsWriteOneBit (pLocalBitStringAux, false); //overscan_info_present_flag
- BsWriteOneBit (pLocalBitStringAux, false); //video_signal_type_present_flag
+
+ // See codec_app_def.h and parameter_sets.h for more info about members bVideoSignalTypePresent through uiColorMatrix.
+ BsWriteOneBit (pLocalBitStringAux, pSps->bVideoSignalTypePresent); //video_signal_type_present_flag
+ if ( pSps->bVideoSignalTypePresent )
+ {//write video signal type info to header
+
+ BsWriteBits (pLocalBitStringAux, 3, pSps->uiVideoFormat);
+ BsWriteOneBit (pLocalBitStringAux, pSps->bFullRange);
+ BsWriteOneBit (pLocalBitStringAux, pSps->bColorDescriptionPresent);
+
+ if ( pSps->bColorDescriptionPresent )
+ {//write color description info to header
+
+ BsWriteBits (pLocalBitStringAux, 8, pSps->uiColorPrimaries);
+ BsWriteBits (pLocalBitStringAux, 8, pSps->uiTransferCharacteristics);
+ BsWriteBits (pLocalBitStringAux, 8, pSps->uiColorMatrix);
+
+ }//write color description info to header
+
+ }//write video signal type info to header
+
BsWriteOneBit (pLocalBitStringAux, false); //chroma_loc_info_present_flag
BsWriteOneBit (pLocalBitStringAux, false); //timing_info_present_flag
BsWriteOneBit (pLocalBitStringAux, false); //nal_hrd_parameters_present_flag
@@ -517,6 +537,16 @@
pSps->bGapsInFrameNumValueAllowedFlag = true;
pSps->bVuiParamPresentFlag = true;
+
+ // See codec_app_def.h and parameter_sets.h for more info about members bVideoSignalTypePresent through uiColorMatrix.
+ pSps->bVideoSignalTypePresent = pLayerParam->bVideoSignalTypePresent;
+ pSps->uiVideoFormat = pLayerParam->uiVideoFormat;
+ pSps->bFullRange = pLayerParam->bFullRange;
+ pSps->bColorDescriptionPresent = pLayerParam->bColorDescriptionPresent;
+ pSps->uiColorPrimaries = pLayerParam->uiColorPrimaries;
+ pSps->uiTransferCharacteristics = pLayerParam->uiTransferCharacteristics;
+ pSps->uiColorMatrix = pLayerParam->uiColorMatrix;
+
return 0;
}
--- a/test/encoder/EncUT_ParameterSetStrategy.cpp
+++ b/test/encoder/EncUT_ParameterSetStrategy.cpp
@@ -120,4 +120,100 @@
(void) iRet; // Not using iRet at the moment
}
+TEST_F (ParameterSetStrategyTest, TestVSTPParameters) {
+ int32_t iRet = 0;
+ bool FalseLocal = false; // EXPECT_EQ does not like "true" or "false" as its first arg
+
+ // this test verifies that the client's "video signal type present" parameter values end up in SWelsSPS
+
+ //init client parameters
+ SEncParamExt sParamExt;
+ SWelsSvcCodingParam::FillDefault(sParamExt);
+ sParamExt.iUsageType = CAMERA_VIDEO_REAL_TIME;
+ sParamExt.iPicWidth = 1280;
+ sParamExt.iPicHeight = 720;
+ sParamExt.iTargetBitrate = 1000000;
+ sParamExt.iRCMode = RC_BITRATE_MODE;
+ sParamExt.fMaxFrameRate = 30.0f;
+
+ // VSTP parameters should be their default values (see SWelsSvcCodingParam::FillDefault())
+ for ( int i = 0; i < MAX_SPATIAL_LAYER_NUM; i++ )
+ {
+ // expected actual
+ EXPECT_EQ( FalseLocal, sParamExt.sSpatialLayers[i].bVideoSignalTypePresent);
+ EXPECT_EQ( VF_UNDEF, sParamExt.sSpatialLayers[i].uiVideoFormat);//5
+ EXPECT_EQ( FalseLocal, sParamExt.sSpatialLayers[i].bFullRange);
+ EXPECT_EQ( FalseLocal, sParamExt.sSpatialLayers[i].bColorDescriptionPresent);
+ EXPECT_EQ( CP_UNDEF, sParamExt.sSpatialLayers[i].uiColorPrimaries);//2
+ EXPECT_EQ( TRC_UNDEF, sParamExt.sSpatialLayers[i].uiTransferCharacteristics);//2
+ EXPECT_EQ( CM_UNDEF, sParamExt.sSpatialLayers[i].uiColorMatrix);//2
+ }
+
+ // set non-default VSTP values
+ sParamExt.iSpatialLayerNum = 2;
+
+ sParamExt.sSpatialLayers[0].bVideoSignalTypePresent = true;
+ sParamExt.sSpatialLayers[0].uiVideoFormat = VF_NTSC;//2
+ sParamExt.sSpatialLayers[0].bFullRange = true;
+ sParamExt.sSpatialLayers[0].bColorDescriptionPresent = true;
+ sParamExt.sSpatialLayers[0].uiColorPrimaries = CP_BT709;//1
+ sParamExt.sSpatialLayers[0].uiTransferCharacteristics = TRC_BT709;//1
+ sParamExt.sSpatialLayers[0].uiColorMatrix = CM_BT709;//1
+
+ sParamExt.sSpatialLayers[1].bVideoSignalTypePresent = true;
+ sParamExt.sSpatialLayers[1].uiVideoFormat = VF_PAL;//1
+ sParamExt.sSpatialLayers[1].bFullRange = true;
+ sParamExt.sSpatialLayers[1].bColorDescriptionPresent = true;
+ sParamExt.sSpatialLayers[1].uiColorPrimaries = CP_SMPTE170M;//6
+ sParamExt.sSpatialLayers[1].uiTransferCharacteristics = TRC_SMPTE170M;//6
+ sParamExt.sSpatialLayers[1].uiColorMatrix = CM_SMPTE170M;//6
+
+ // transcode parameters from client
+ SWelsSvcCodingParam sSvcCodingParam;
+ iRet = sSvcCodingParam.ParamTranscode(sParamExt);
+ EXPECT_EQ (iRet, 0);
+
+ // transcoded VSTP parameters should match the client values
+ for ( int i = 0; i < sParamExt.iSpatialLayerNum; i++ )
+ {
+ EXPECT_EQ( sParamExt.sSpatialLayers[i].bVideoSignalTypePresent, sSvcCodingParam.sSpatialLayers[i].bVideoSignalTypePresent);
+ EXPECT_EQ( sParamExt.sSpatialLayers[i].uiVideoFormat, sSvcCodingParam.sSpatialLayers[i].uiVideoFormat);
+ EXPECT_EQ( sParamExt.sSpatialLayers[i].bFullRange, sSvcCodingParam.sSpatialLayers[i].bFullRange);
+ EXPECT_EQ( sParamExt.sSpatialLayers[i].bColorDescriptionPresent, sSvcCodingParam.sSpatialLayers[i].bColorDescriptionPresent);
+ EXPECT_EQ( sParamExt.sSpatialLayers[i].uiColorPrimaries, sSvcCodingParam.sSpatialLayers[i].uiColorPrimaries);
+ EXPECT_EQ( sParamExt.sSpatialLayers[i].uiTransferCharacteristics, sSvcCodingParam.sSpatialLayers[i].uiTransferCharacteristics);
+ EXPECT_EQ( sParamExt.sSpatialLayers[i].uiColorMatrix, sSvcCodingParam.sSpatialLayers[i].uiColorMatrix);
+ }
+
+ // use transcoded parameters to initialize an SWelsSPS
+ m_pSpsArrayPointer = &m_pSpsArray[0];
+ SSpatialLayerConfig* pDlayerParam = &(sSvcCodingParam.sSpatialLayers[0]);
+ iRet = WelsInitSps (
+ m_pSpsArrayPointer,
+ pDlayerParam,
+ &sSvcCodingParam.sDependencyLayers[0],
+ sSvcCodingParam.uiIntraPeriod,
+ sSvcCodingParam.iMaxNumRefFrame,
+ 0, //SpsId
+ sSvcCodingParam.bEnableFrameCroppingFlag,
+ sSvcCodingParam.iRCMode != RC_OFF_MODE,
+ 0, //DlayerCount
+ false
+ );
+ EXPECT_EQ (iRet, 0);
+
+ // SPS VSTP parameters should match the transcoded values
+ EXPECT_EQ( sSvcCodingParam.sSpatialLayers[0].bVideoSignalTypePresent, m_pSpsArrayPointer->bVideoSignalTypePresent);
+ EXPECT_EQ( sSvcCodingParam.sSpatialLayers[0].uiVideoFormat, m_pSpsArrayPointer->uiVideoFormat);
+ EXPECT_EQ( sSvcCodingParam.sSpatialLayers[0].bFullRange, m_pSpsArrayPointer->bFullRange);
+ EXPECT_EQ( sSvcCodingParam.sSpatialLayers[0].bColorDescriptionPresent, m_pSpsArrayPointer->bColorDescriptionPresent);
+ EXPECT_EQ( sSvcCodingParam.sSpatialLayers[0].uiColorPrimaries, m_pSpsArrayPointer->uiColorPrimaries);
+ EXPECT_EQ( sSvcCodingParam.sSpatialLayers[0].uiTransferCharacteristics, m_pSpsArrayPointer->uiTransferCharacteristics);
+ EXPECT_EQ( sSvcCodingParam.sSpatialLayers[0].uiColorMatrix, m_pSpsArrayPointer->uiColorMatrix);
+
+ // TODO: verify that WriteVUI (au_set.cpp) writes the SPS VSTP values to the output file (verified using FFmpeg)
+
+ (void) iRet; // Not using iRet at the moment
+}
+