Merge pull request #2371 from GregoryJWolfe/master

Added support for "video signal type present" information.
This commit is contained in:
HaiboZhu 2016-02-25 10:49:34 +08:00
commit 027f027c25
6 changed files with 244 additions and 2 deletions

View File

@ -1,4 +1,4 @@
# Contributors to the OpenH264 project
# Contributors to the OpenH264 project
Patrick Ai
Sijia Chen
@ -35,6 +35,7 @@ James Wang
Juanny Wang
Zhiliang Wang
Hervé Willems
Gregory J Wolfe
Katherine Wu
Guang Xu
Jeffery Xu

View File

@ -343,6 +343,77 @@ typedef struct {
unsigned int uiSliceSizeConstraint; ///< now only used when uiSliceMode=4
} 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
*/
@ -357,6 +428,18 @@ typedef struct {
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;
/**

View File

@ -190,6 +190,16 @@ typedef struct TagWelsSvcCodingParam: SEncParamExt {
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
}
}
@ -408,6 +418,15 @@ typedef struct TagWelsSvcCodingParam: SEncParamExt {
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;
++ pSpatialLayer;

View File

@ -79,6 +79,19 @@ bool bVuiParamPresentFlag;
// 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;

View File

@ -202,7 +202,27 @@ int32_t WelsWriteVUI (SWelsSPS* pSps, SBitStringAux* pBitStringAux) {
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 @@ int32_t WelsInitSps (SWelsSPS* pSps, SSpatialLayerConfig* pLayerParam, SSpatialL
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;
}

View File

@ -120,4 +120,100 @@ TEST_F (ParameterSetStrategyTest, FindExistingSps) {
(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
}