github.com/bluenviron/mediacommon@v1.9.3/pkg/codecs/h265/sps_test.go (about)

     1  package h265
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/stretchr/testify/require"
     7  )
     8  
     9  func TestSPSUnmarshal(t *testing.T) {
    10  	for _, ca := range []struct {
    11  		name   string
    12  		byts   []byte
    13  		sps    SPS
    14  		width  int
    15  		height int
    16  		fps    float64
    17  	}{
    18  		{
    19  			"1920x1080",
    20  			[]byte{
    21  				0x42, 0x01, 0x01, 0x01, 0x60, 0x00, 0x00, 0x03,
    22  				0x00, 0x90, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03,
    23  				0x00, 0x78, 0xa0, 0x03, 0xc0, 0x80, 0x10, 0xe5,
    24  				0x96, 0x66, 0x69, 0x24, 0xca, 0xe0, 0x10, 0x00,
    25  				0x00, 0x03, 0x00, 0x10, 0x00, 0x00, 0x03, 0x01,
    26  				0xe0, 0x80,
    27  			},
    28  			SPS{
    29  				TemporalIDNestingFlag: true,
    30  				ProfileTierLevel: SPS_ProfileTierLevel{
    31  					GeneralProfileIdc: 1,
    32  					GeneralProfileCompatibilityFlag: [32]bool{
    33  						false, true, true, false, false, false, false, false,
    34  						false, false, false, false, false, false, false, false,
    35  						false, false, false, false, false, false, false, false,
    36  						false, false, false, false, false, false, false, false,
    37  					},
    38  					GeneralProgressiveSourceFlag:   true,
    39  					GeneralFrameOnlyConstraintFlag: true,
    40  					GeneralLevelIdc:                120,
    41  				},
    42  				ChromaFormatIdc:                      1,
    43  				PicWidthInLumaSamples:                1920,
    44  				PicHeightInLumaSamples:               1080,
    45  				Log2MaxPicOrderCntLsbMinus4:          4,
    46  				SubLayerOrderingInfoPresentFlag:      true,
    47  				MaxDecPicBufferingMinus1:             []uint32{5},
    48  				MaxNumReorderPics:                    []uint32{2},
    49  				MaxLatencyIncreasePlus1:              []uint32{5},
    50  				Log2DiffMaxMinLumaCodingBlockSize:    3,
    51  				Log2DiffMaxMinLumaTransformBlockSize: 3,
    52  				SampleAdaptiveOffsetEnabledFlag:      true,
    53  				TemporalMvpEnabledFlag:               true,
    54  				StrongIntraSmoothingEnabledFlag:      true,
    55  				VUI: &SPS_VUI{
    56  					TimingInfo: &SPS_TimingInfo{
    57  						NumUnitsInTick: 1,
    58  						TimeScale:      30,
    59  					},
    60  				},
    61  			},
    62  			1920,
    63  			1080,
    64  			30,
    65  		},
    66  		{
    67  			"1920x800",
    68  			[]byte{
    69  				0x42, 0x01, 0x01, 0x01, 0x60, 0x00, 0x00, 0x03,
    70  				0x00, 0x90, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03,
    71  				0x00, 0x78, 0xa0, 0x03, 0xc0, 0x80, 0x32, 0x16,
    72  				0x59, 0x59, 0xa4, 0x93, 0x2b, 0xc0, 0x5a, 0x80,
    73  				0x80, 0x80, 0x82, 0x00, 0x00, 0x07, 0xd2, 0x00,
    74  				0x00, 0xbb, 0x80, 0x10,
    75  			},
    76  			SPS{
    77  				TemporalIDNestingFlag: true,
    78  				ProfileTierLevel: SPS_ProfileTierLevel{
    79  					GeneralProfileIdc: 1,
    80  					GeneralProfileCompatibilityFlag: [32]bool{
    81  						false, true, true, false, false, false, false, false,
    82  						false, false, false, false, false, false, false, false,
    83  						false, false, false, false, false, false, false, false,
    84  						false, false, false, false, false, false, false, false,
    85  					},
    86  					GeneralProgressiveSourceFlag:   true,
    87  					GeneralFrameOnlyConstraintFlag: true,
    88  					GeneralLevelIdc:                120,
    89  				},
    90  				ChromaFormatIdc:                      1,
    91  				PicWidthInLumaSamples:                1920,
    92  				PicHeightInLumaSamples:               800,
    93  				Log2MaxPicOrderCntLsbMinus4:          4,
    94  				SubLayerOrderingInfoPresentFlag:      true,
    95  				MaxDecPicBufferingMinus1:             []uint32{4},
    96  				MaxNumReorderPics:                    []uint32{2},
    97  				MaxLatencyIncreasePlus1:              []uint32{5},
    98  				Log2DiffMaxMinLumaCodingBlockSize:    3,
    99  				Log2DiffMaxMinLumaTransformBlockSize: 3,
   100  				SampleAdaptiveOffsetEnabledFlag:      true,
   101  				TemporalMvpEnabledFlag:               true,
   102  				StrongIntraSmoothingEnabledFlag:      true,
   103  				VUI: &SPS_VUI{
   104  					AspectRatioInfoPresentFlag:   true,
   105  					AspectRatioIdc:               1,
   106  					VideoSignalTypePresentFlag:   true,
   107  					VideoFormat:                  5,
   108  					ColourDescriptionPresentFlag: true,
   109  					ColourPrimaries:              1,
   110  					TransferCharacteristics:      1,
   111  					MatrixCoefficients:           1,
   112  					TimingInfo: &SPS_TimingInfo{
   113  						NumUnitsInTick: 1001,
   114  						TimeScale:      24000,
   115  					},
   116  				},
   117  			},
   118  			1920,
   119  			800,
   120  			23.976023976023978,
   121  		},
   122  		{
   123  			"1280x720",
   124  			[]byte{
   125  				0x42, 0x01, 0x01, 0x04, 0x08, 0x00, 0x00, 0x03,
   126  				0x00, 0x98, 0x08, 0x00, 0x00, 0x03, 0x00, 0x00,
   127  				0x5d, 0x90, 0x00, 0x50, 0x10, 0x05, 0xa2, 0x29,
   128  				0x4b, 0x74, 0x94, 0x98, 0x5f, 0xfe, 0x00, 0x02,
   129  				0x00, 0x02, 0xd4, 0x04, 0x04, 0x04, 0x10, 0x00,
   130  				0x00, 0x03, 0x00, 0x10, 0x00, 0x00, 0x03, 0x01,
   131  				0xe0, 0x80,
   132  			},
   133  			SPS{
   134  				TemporalIDNestingFlag: true,
   135  				ProfileTierLevel: SPS_ProfileTierLevel{
   136  					GeneralProfileIdc: 4,
   137  					GeneralProfileCompatibilityFlag: [32]bool{
   138  						false, false, false, false, true, false, false, false,
   139  						false, false, false, false, false, false, false, false,
   140  						false, false, false, false, false, false, false, false,
   141  						false, false, false, false, false, false, false, false,
   142  					},
   143  					GeneralProgressiveSourceFlag:      true,
   144  					GeneralFrameOnlyConstraintFlag:    true,
   145  					GeneralMax12bitConstraintFlag:     true,
   146  					GeneralLowerBitRateConstraintFlag: true,
   147  					GeneralLevelIdc:                   93,
   148  				},
   149  				ChromaFormatIdc:                      3,
   150  				PicWidthInLumaSamples:                1280,
   151  				PicHeightInLumaSamples:               720,
   152  				BitDepthLumaMinus8:                   4,
   153  				BitDepthChromaMinus8:                 4,
   154  				Log2MaxPicOrderCntLsbMinus4:          4,
   155  				SubLayerOrderingInfoPresentFlag:      true,
   156  				MaxDecPicBufferingMinus1:             []uint32{2},
   157  				MaxNumReorderPics:                    []uint32{0},
   158  				MaxLatencyIncreasePlus1:              []uint32{1},
   159  				Log2MinLumaCodingBlockSizeMinus3:     1,
   160  				Log2DiffMaxMinLumaCodingBlockSize:    1,
   161  				Log2DiffMaxMinLumaTransformBlockSize: 3,
   162  				TemporalMvpEnabledFlag:               true,
   163  				StrongIntraSmoothingEnabledFlag:      true,
   164  				VUI: &SPS_VUI{
   165  					AspectRatioInfoPresentFlag:   true,
   166  					AspectRatioIdc:               255,
   167  					SarWidth:                     1,
   168  					SarHeight:                    1,
   169  					VideoSignalTypePresentFlag:   true,
   170  					VideoFormat:                  5,
   171  					ColourDescriptionPresentFlag: true,
   172  					ColourPrimaries:              1,
   173  					TransferCharacteristics:      1,
   174  					MatrixCoefficients:           1,
   175  					TimingInfo: &SPS_TimingInfo{
   176  						NumUnitsInTick: 1,
   177  						TimeScale:      30,
   178  					},
   179  				},
   180  			},
   181  			1280,
   182  			720,
   183  			30,
   184  		},
   185  		{
   186  			"10 bit",
   187  			[]byte{
   188  				0x42, 0x01, 0x01, 0x22, 0x20, 0x00, 0x00, 0x03,
   189  				0x00, 0x90, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03,
   190  				0x00, 0x78, 0xa0, 0x03, 0xc0, 0x80, 0x10, 0xe4,
   191  				0xd9, 0x66, 0x66, 0x92, 0x4c, 0xaf, 0x01, 0x01,
   192  				0x00, 0x00, 0x03, 0x00, 0x64, 0x00, 0x00, 0x0b,
   193  				0xb5, 0x08,
   194  			},
   195  			SPS{
   196  				TemporalIDNestingFlag: true,
   197  				ProfileTierLevel: SPS_ProfileTierLevel{
   198  					GeneralTierFlag:   1,
   199  					GeneralProfileIdc: 2,
   200  					GeneralProfileCompatibilityFlag: [32]bool{
   201  						false, false, true, false, false, false, false, false,
   202  						false, false, false, false, false, false, false, false,
   203  						false, false, false, false, false, false, false, false,
   204  						false, false, false, false, false, false, false, false,
   205  					},
   206  					GeneralProgressiveSourceFlag:   true,
   207  					GeneralFrameOnlyConstraintFlag: true,
   208  					GeneralLevelIdc:                120,
   209  				},
   210  				ChromaFormatIdc:                      1,
   211  				PicWidthInLumaSamples:                1920,
   212  				PicHeightInLumaSamples:               1080,
   213  				BitDepthLumaMinus8:                   2,
   214  				BitDepthChromaMinus8:                 2,
   215  				Log2MaxPicOrderCntLsbMinus4:          4,
   216  				SubLayerOrderingInfoPresentFlag:      true,
   217  				MaxDecPicBufferingMinus1:             []uint32{5},
   218  				MaxNumReorderPics:                    []uint32{2},
   219  				MaxLatencyIncreasePlus1:              []uint32{5},
   220  				Log2DiffMaxMinLumaCodingBlockSize:    3,
   221  				Log2DiffMaxMinLumaTransformBlockSize: 3,
   222  				SampleAdaptiveOffsetEnabledFlag:      true,
   223  				TemporalMvpEnabledFlag:               true,
   224  				StrongIntraSmoothingEnabledFlag:      true,
   225  				VUI: &SPS_VUI{
   226  					AspectRatioInfoPresentFlag: true,
   227  					AspectRatioIdc:             1,
   228  					TimingInfo: &SPS_TimingInfo{
   229  						NumUnitsInTick: 100,
   230  						TimeScale:      2997,
   231  					},
   232  				},
   233  			},
   234  			1920,
   235  			1080,
   236  			29.97,
   237  		},
   238  		{
   239  			"nvenc",
   240  			[]byte{
   241  				0x42, 0x01, 0x01, 0x01, 0x40, 0x00, 0x00, 0x03,
   242  				0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00,
   243  				0x03, 0x00, 0x7b, 0xa0, 0x03, 0xc0, 0x80, 0x11,
   244  				0x07, 0xcb, 0x96, 0xb4, 0xa4, 0x25, 0x92, 0xe3,
   245  				0x01, 0x6a, 0x02, 0x02, 0x02, 0x08, 0x00, 0x00,
   246  				0x03, 0x00, 0x08, 0x00, 0x00, 0x03, 0x01, 0xe3,
   247  				0x00, 0x2e, 0xf2, 0x88, 0x00, 0x07, 0x27, 0x0c,
   248  				0x00, 0x00, 0x98, 0x96, 0x82,
   249  			},
   250  			SPS{
   251  				TemporalIDNestingFlag: true,
   252  				ProfileTierLevel: SPS_ProfileTierLevel{
   253  					GeneralProfileIdc: 1,
   254  					GeneralProfileCompatibilityFlag: [32]bool{
   255  						false, true, false, false, false, false, false, false,
   256  						false, false, false, false, false, false, false, false,
   257  						false, false, false, false, false, false, false, false,
   258  						false, false, false, false, false, false, false, false,
   259  					},
   260  					GeneralLevelIdc: 123,
   261  				},
   262  				ChromaFormatIdc:        1,
   263  				PicWidthInLumaSamples:  1920,
   264  				PicHeightInLumaSamples: 1088,
   265  				ConformanceWindow: &SPS_ConformanceWindow{
   266  					BottomOffset: 4,
   267  				},
   268  				Log2MaxPicOrderCntLsbMinus4:          4,
   269  				SubLayerOrderingInfoPresentFlag:      true,
   270  				MaxDecPicBufferingMinus1:             []uint32{1},
   271  				MaxNumReorderPics:                    []uint32{0},
   272  				MaxLatencyIncreasePlus1:              []uint32{0},
   273  				Log2MinLumaCodingBlockSizeMinus3:     1,
   274  				Log2DiffMaxMinLumaCodingBlockSize:    1,
   275  				Log2DiffMaxMinLumaTransformBlockSize: 3,
   276  				MaxTransformHierarchyDepthInter:      3,
   277  				AmpEnabledFlag:                       true,
   278  				SampleAdaptiveOffsetEnabledFlag:      true,
   279  				ShortTermRefPicSets: []*SPS_ShortTermRefPicSet{{
   280  					NumNegativePics:     1,
   281  					DeltaPocS0Minus1:    []uint32{0},
   282  					UsedByCurrPicS0Flag: []bool{true},
   283  				}},
   284  				VUI: &SPS_VUI{
   285  					AspectRatioInfoPresentFlag:   true,
   286  					AspectRatioIdc:               1,
   287  					VideoSignalTypePresentFlag:   true,
   288  					VideoFormat:                  5,
   289  					ColourDescriptionPresentFlag: true,
   290  					ColourPrimaries:              1,
   291  					TransferCharacteristics:      1,
   292  					MatrixCoefficients:           1,
   293  					TimingInfo: &SPS_TimingInfo{
   294  						NumUnitsInTick: 1,
   295  						TimeScale:      60,
   296  					},
   297  				},
   298  			},
   299  			1920,
   300  			1080,
   301  			60,
   302  		},
   303  		{
   304  			"avigilon",
   305  			[]byte{
   306  				0x42, 0x01, 0x01, 0x01, 0x60, 0x00, 0x00, 0x03,
   307  				0x00, 0x80, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03,
   308  				0x00, 0x96, 0xa0, 0x01, 0x80, 0x20, 0x06, 0xc1,
   309  				0xfe, 0x36, 0xbb, 0xb5, 0x37, 0x77, 0x25, 0xd6,
   310  				0x02, 0xdc, 0x04, 0x04, 0x04, 0x10, 0x00, 0x00,
   311  				0x3e, 0x80, 0x00, 0x04, 0x26, 0x87, 0x21, 0xde,
   312  				0xe5, 0x10, 0x01, 0x6e, 0x20, 0x00, 0x66, 0xff,
   313  				0x00, 0x0b, 0x71, 0x00, 0x03, 0x37, 0xf8, 0x80,
   314  			},
   315  			SPS{
   316  				TemporalIDNestingFlag: true,
   317  				ProfileTierLevel: SPS_ProfileTierLevel{
   318  					GeneralProfileIdc: 1,
   319  					GeneralProfileCompatibilityFlag: [32]bool{
   320  						false, true, true, false, false, false, false, false,
   321  						false, false, false, false, false, false, false, false,
   322  						false, false, false, false, false, false, false, false,
   323  						false, false, false, false, false, false, false, false,
   324  					},
   325  					GeneralProgressiveSourceFlag: true,
   326  					GeneralLevelIdc:              150,
   327  				},
   328  				ChromaFormatIdc:                      1,
   329  				PicWidthInLumaSamples:                3072,
   330  				PicHeightInLumaSamples:               1728,
   331  				ConformanceWindow:                    &SPS_ConformanceWindow{},
   332  				Log2MaxPicOrderCntLsbMinus4:          12,
   333  				SubLayerOrderingInfoPresentFlag:      true,
   334  				MaxDecPicBufferingMinus1:             []uint32{1},
   335  				MaxNumReorderPics:                    []uint32{0},
   336  				MaxLatencyIncreasePlus1:              []uint32{0},
   337  				Log2DiffMaxMinLumaCodingBlockSize:    2,
   338  				SampleAdaptiveOffsetEnabledFlag:      true,
   339  				PcmEnabledFlag:                       true,
   340  				PcmSampleBitDepthLumaMinus1:          7,
   341  				PcmSampleBitDepthChromaMinus1:        7,
   342  				Log2DiffMaxMinLumaTransformBlockSize: 2,
   343  				MaxTransformHierarchyDepthInter:      1,
   344  				Log2MinPcmLumaCodingBlockSizeMinus3:  2,
   345  				ShortTermRefPicSets: []*SPS_ShortTermRefPicSet{
   346  					{
   347  						NumNegativePics:     1,
   348  						DeltaPocS0Minus1:    []uint32{0},
   349  						UsedByCurrPicS0Flag: []bool{true},
   350  					},
   351  				},
   352  				TemporalMvpEnabledFlag: true,
   353  				VUI: &SPS_VUI{
   354  					AspectRatioInfoPresentFlag:   true,
   355  					AspectRatioIdc:               1,
   356  					VideoSignalTypePresentFlag:   true,
   357  					VideoFormat:                  5,
   358  					VideoFullRangeFlag:           true,
   359  					ColourDescriptionPresentFlag: true,
   360  					ColourPrimaries:              1,
   361  					TransferCharacteristics:      1,
   362  					MatrixCoefficients:           1,
   363  					TimingInfo: &SPS_TimingInfo{
   364  						NumUnitsInTick: 1000,
   365  						TimeScale:      17000,
   366  					},
   367  				},
   368  			},
   369  			3072,
   370  			1728,
   371  			17,
   372  		},
   373  		{
   374  			"long_term_ref_pics_present_flag",
   375  			[]byte{
   376  				0x42, 0x01, 0x01, 0x01, 0x60, 0x00, 0x00, 0x03,
   377  				0x00, 0xb0, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03,
   378  				0x00, 0x5d, 0xa0, 0x02, 0x80, 0x80, 0x2d, 0x16,
   379  				0x36, 0xb9, 0x24, 0xcb, 0xf0, 0x08, 0x00, 0x00,
   380  				0x03, 0x00, 0x08, 0x00, 0x00, 0x03, 0x01, 0x95,
   381  				0x08,
   382  			},
   383  			SPS{
   384  				TemporalIDNestingFlag: true,
   385  				ProfileTierLevel: SPS_ProfileTierLevel{
   386  					GeneralProfileIdc: 1,
   387  					GeneralProfileCompatibilityFlag: [32]bool{
   388  						false, true, true, false, false, false, false, false,
   389  						false, false, false, false, false, false, false, false,
   390  						false, false, false, false, false, false, false, false,
   391  						false, false, false, false, false, false, false, false,
   392  					},
   393  					GeneralProgressiveSourceFlag:   true,
   394  					GeneralNonPackedConstraintFlag: true,
   395  					GeneralFrameOnlyConstraintFlag: true,
   396  					GeneralLevelIdc:                93,
   397  				},
   398  				ChromaFormatIdc:                      1,
   399  				PicWidthInLumaSamples:                1280,
   400  				PicHeightInLumaSamples:               720,
   401  				Log2MaxPicOrderCntLsbMinus4:          12,
   402  				SubLayerOrderingInfoPresentFlag:      true,
   403  				MaxDecPicBufferingMinus1:             []uint32{1},
   404  				MaxNumReorderPics:                    []uint32{0},
   405  				MaxLatencyIncreasePlus1:              []uint32{0},
   406  				Log2DiffMaxMinLumaCodingBlockSize:    3,
   407  				Log2DiffMaxMinLumaTransformBlockSize: 3,
   408  				SampleAdaptiveOffsetEnabledFlag:      true,
   409  				LongTermRefPicsPresentFlag:           true,
   410  				TemporalMvpEnabledFlag:               true,
   411  				StrongIntraSmoothingEnabledFlag:      true,
   412  				VUI: &SPS_VUI{
   413  					TimingInfo: &SPS_TimingInfo{
   414  						NumUnitsInTick:              1,
   415  						TimeScale:                   50,
   416  						POCProportionalToTimingFlag: true,
   417  						NumTicksPOCDiffOneMinus1:    1,
   418  					},
   419  				},
   420  			},
   421  			1280,
   422  			720,
   423  			50,
   424  		},
   425  	} {
   426  		t.Run(ca.name, func(t *testing.T) {
   427  			var sps SPS
   428  			err := sps.Unmarshal(ca.byts)
   429  			require.NoError(t, err)
   430  			require.Equal(t, ca.sps, sps)
   431  			require.Equal(t, ca.width, sps.Width())
   432  			require.Equal(t, ca.height, sps.Height())
   433  			require.Equal(t, ca.fps, sps.FPS())
   434  		})
   435  	}
   436  }
   437  
   438  func FuzzSPSUnmarshal(f *testing.F) {
   439  	f.Fuzz(func(_ *testing.T, b []byte) {
   440  		var sps SPS
   441  		sps.Unmarshal(b) //nolint:errcheck
   442  	})
   443  }