shithub: openh264

Download patch

ref: c7fcba06c7fab941384800dd094edee77fa5cfcb
parent: f35a0daccf870f0da2f3f9d338d5a3986ee5b55a
author: Gregory J. Wolfe <gregory.wolfe@kodakalaris.com>
date: Tue Feb 23 08:21:06 EST 2016

Added support for "video signal type present" information.
The "Video signal type present" information is written to the output
video file when it is created, and later is used by the decoder to
properly decode the compressed video data. The saved attributes
are:

- format type (PAL, NTSC, etc.)
- color primaries (BT709, SMPTE170M, etc.)
- transfer characteristics (BT709, SMPTE170M, etc.)
- color matrix ((BT709, SMPTE170M, etc.)

These modifications allow the client to specify these attributes
and, if specified, makes sure they are written to the output file.

--- 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
@@ -343,8 +343,6 @@
   unsigned int  uiSliceSizeConstraint; ///< now only used when uiSliceMode=4
 } SSliceArgument;
 
-// 02/18/2016, Greg Wolfe, Kodak Alaris:  Added support for "video signal type present" information.
-
 /**
 * @brief Enumerate the type of video format
 */
@@ -416,8 +414,6 @@
   CM_NUM_ENUM
 } EColorMatrix;
 
-// ... end 02/18/2016
-
 /**
 * @brief  Structure for spatial layer configuration
 */
@@ -433,8 +429,7 @@
 
   SSliceArgument sSliceArgument;
 
-  // 02/18/2016, Greg Wolfe, Kodak Alaris:  Added support for "video signal type present" information.
-  // See also parameter_sets.h.
+  // 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]
@@ -445,7 +440,6 @@
 										    //   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
-// ... end 02/18/2016
 } SSpatialLayerConfig;
 
 /**
--- a/codec/encoder/core/inc/param_svc.h
+++ b/codec/encoder/core/inc/param_svc.h
@@ -191,9 +191,8 @@
       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
 
-      // 02/18/2016, Greg Wolfe, Kodak Alaris:  Added support for "video signal type present" information.
-      // See codec_app_def.h for more info.  The default values preserve the previous behavior; i.e., no
-      // additional information will be written to the output file.
+      // 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]
@@ -201,7 +200,6 @@
       param.sSpatialLayers[iLayer].uiColorPrimaries = CP_UNDEF;				// undefined
       param.sSpatialLayers[iLayer].uiTransferCharacteristics = TRC_UNDEF;	// undefined
       param.sSpatialLayers[iLayer].uiColorMatrix = CM_UNDEF;				// undefined
-      // ... end 02/18/2016
     }
   }
 
@@ -420,8 +418,7 @@
 
       pSpatialLayer->iDLayerQp = pCodingParam.sSpatialLayers[iIdxSpatial].iDLayerQp;
 
-      // 02/18/2016, Greg Wolfe, Kodak Alaris:  Added support for "video signal type present" information.
-      // See codec_app_def.h and parameter_sets.h for more info.
+      // 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;
@@ -429,7 +426,6 @@
       pSpatialLayer->uiColorPrimaries =          pCodingParam.sSpatialLayers[iIdxSpatial].uiColorPrimaries;
       pSpatialLayer->uiTransferCharacteristics = pCodingParam.sSpatialLayers[iIdxSpatial].uiTransferCharacteristics;
       pSpatialLayer->uiColorMatrix =             pCodingParam.sSpatialLayers[iIdxSpatial].uiColorMatrix;
-      // ... end 02/18/2016
 
       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,15 +79,8 @@
 // bool            bTimingInfoPresentFlag;
 // bool            bFixedFrameRateFlag;
 
-bool            bConstraintSet0Flag;
-bool            bConstraintSet1Flag;
-bool            bConstraintSet2Flag;
-bool            bConstraintSet3Flag;
-// bool            bSeparateColorPlaneFlag;  // =false,: only used in decoder, encoder in general_***; it can be removed when removed general up_sample
-
-// 02/18/2016, Greg Wolfe, Kodak Alaris:  Added support for "video signal type present" information.
-// See also codec_app_def.h for definitions of enumerators EVideoFormatSPS, EColorPrimaries, ETransferCharacteristics,
-// and EColorMatrix.
+// 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]
@@ -98,7 +91,12 @@
                                     //   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
-// ... end 02/18/2016
+
+bool            bConstraintSet0Flag;
+bool            bConstraintSet1Flag;
+bool            bConstraintSet2Flag;
+bool            bConstraintSet3Flag;
+// bool            bSeparateColorPlaneFlag;  // =false,: only used in decoder, encoder in general_***; it can be removed when removed general up_sample
 
 } SWelsSPS, *PWelsSPS;
 
--- a/codec/encoder/core/src/au_set.cpp
+++ b/codec/encoder/core/src/au_set.cpp
@@ -203,8 +203,7 @@
   BsWriteOneBit (pLocalBitStringAux, false); //aspect_ratio_info_present_flag
   BsWriteOneBit (pLocalBitStringAux, false); //overscan_info_present_flag
 
-  // 02/18/2016, Greg Wolfe, Kodak Alaris:  Added support for "video signal type present" information.
-  // See parameter_sets.h for more info.
+  // 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
@@ -223,7 +222,6 @@
     }//write color description info to header
 
   }//write video signal type info to header
-  // ... end 02/18/2016
 
   BsWriteOneBit (pLocalBitStringAux, false); //chroma_loc_info_present_flag
   BsWriteOneBit (pLocalBitStringAux, false); //timing_info_present_flag
@@ -540,8 +538,7 @@
 
   pSps->bVuiParamPresentFlag = true;
 
-  // 02/18/2016, Greg Wolfe, Kodak Alaris:  Added support for "video signal type present" information.
-  // See codec_app_def.h and parameter_sets.h for more info.
+  // 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;
@@ -549,7 +546,6 @@
   pSps->uiColorPrimaries =          pLayerParam->uiColorPrimaries;
   pSps->uiTransferCharacteristics = pLayerParam->uiTransferCharacteristics;
   pSps->uiColorMatrix =             pLayerParam->uiColorMatrix;
-  // ... end 02/18/2016
 
   return 0;
 }
--- a/test/encoder/EncUT_ParameterSetStrategy.cpp
+++ b/test/encoder/EncUT_ParameterSetStrategy.cpp
@@ -120,4 +120,101 @@
   (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
+  bool TrueLocal = true;
+
+  // 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
+}
+