github.com/bluenviron/mediacommon@v1.9.3/pkg/codecs/h264/sps_test.go (about) 1 package h264 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 "352x288", 20 []byte{ 21 0x67, 0x64, 0x00, 0x0c, 0xac, 0x3b, 0x50, 0xb0, 22 0x4b, 0x42, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00, 23 0x00, 0x03, 0x00, 0x3d, 0x08, 24 }, 25 SPS{ 26 ProfileIdc: 100, 27 LevelIdc: 12, 28 ChromaFormatIdc: 1, 29 Log2MaxFrameNumMinus4: 6, 30 PicOrderCntType: 2, 31 MaxNumRefFrames: 1, 32 GapsInFrameNumValueAllowedFlag: true, 33 PicWidthInMbsMinus1: 21, 34 PicHeightInMapUnitsMinus1: 17, 35 FrameMbsOnlyFlag: true, 36 Direct8x8InferenceFlag: true, 37 VUI: &SPS_VUI{ 38 TimingInfo: &SPS_TimingInfo{ 39 NumUnitsInTick: 1, 40 TimeScale: 30, 41 FixedFrameRateFlag: true, 42 }, 43 }, 44 }, 45 352, 46 288, 47 15, 48 }, 49 { 50 "1280x720", 51 []byte{ 52 0x67, 0x64, 0x00, 0x1f, 0xac, 0xd9, 0x40, 0x50, 53 0x05, 0xbb, 0x01, 0x6c, 0x80, 0x00, 0x00, 0x03, 54 0x00, 0x80, 0x00, 0x00, 0x1e, 0x07, 0x8c, 0x18, 55 0xcb, 56 }, 57 SPS{ 58 ProfileIdc: 100, 59 LevelIdc: 31, 60 ChromaFormatIdc: 1, 61 Log2MaxPicOrderCntLsbMinus4: 2, 62 MaxNumRefFrames: 4, 63 PicWidthInMbsMinus1: 79, 64 PicHeightInMapUnitsMinus1: 44, 65 FrameMbsOnlyFlag: true, 66 Direct8x8InferenceFlag: true, 67 VUI: &SPS_VUI{ 68 AspectRatioInfoPresentFlag: true, 69 AspectRatioIdc: 1, 70 VideoSignalTypePresentFlag: true, 71 VideoFormat: 5, 72 VideoFullRangeFlag: true, 73 TimingInfo: &SPS_TimingInfo{ 74 NumUnitsInTick: 1, 75 TimeScale: 60, 76 }, 77 BitstreamRestriction: &SPS_BitstreamRestriction{ 78 MotionVectorsOverPicBoundariesFlag: true, 79 Log2MaxMvLengthHorizontal: 11, 80 Log2MaxMvLengthVertical: 11, 81 MaxNumReorderFrames: 2, 82 MaxDecFrameBuffering: 4, 83 }, 84 }, 85 }, 86 1280, 87 720, 88 30, 89 }, 90 { 91 "1920x1080 baseline", 92 []byte{ 93 0x67, 0x42, 0xc0, 0x28, 0xd9, 0x00, 0x78, 0x02, 94 0x27, 0xe5, 0x84, 0x00, 0x00, 0x03, 0x00, 0x04, 95 0x00, 0x00, 0x03, 0x00, 0xf0, 0x3c, 0x60, 0xc9, 0x20, 96 }, 97 SPS{ 98 ProfileIdc: 66, 99 ChromaFormatIdc: 1, 100 ConstraintSet0Flag: true, 101 ConstraintSet1Flag: true, 102 LevelIdc: 40, 103 PicOrderCntType: 2, 104 MaxNumRefFrames: 3, 105 PicWidthInMbsMinus1: 119, 106 PicHeightInMapUnitsMinus1: 67, 107 FrameMbsOnlyFlag: true, 108 Direct8x8InferenceFlag: true, 109 FrameCropping: &SPS_FrameCropping{ 110 BottomOffset: 4, 111 }, 112 VUI: &SPS_VUI{ 113 TimingInfo: &SPS_TimingInfo{ 114 NumUnitsInTick: 1, 115 TimeScale: 60, 116 }, 117 BitstreamRestriction: &SPS_BitstreamRestriction{ 118 MotionVectorsOverPicBoundariesFlag: true, 119 Log2MaxMvLengthHorizontal: 11, 120 Log2MaxMvLengthVertical: 11, 121 MaxDecFrameBuffering: 3, 122 }, 123 }, 124 }, 125 1920, 126 1080, 127 30, 128 }, 129 { 130 "1920x1080 nvidia", 131 []byte{ 132 0x67, 0x64, 0x00, 0x28, 0xac, 0xd9, 0x40, 0x78, 133 0x02, 0x27, 0xe5, 0x84, 0x00, 0x00, 0x03, 0x00, 134 0x04, 0x00, 0x00, 0x03, 0x00, 0xf0, 0x3c, 0x60, 135 0xc6, 0x58, 136 }, 137 SPS{ 138 ProfileIdc: 100, 139 LevelIdc: 40, 140 ChromaFormatIdc: 1, 141 Log2MaxPicOrderCntLsbMinus4: 2, 142 MaxNumRefFrames: 4, 143 PicWidthInMbsMinus1: 119, 144 PicHeightInMapUnitsMinus1: 67, 145 FrameMbsOnlyFlag: true, 146 Direct8x8InferenceFlag: true, 147 FrameCropping: &SPS_FrameCropping{ 148 BottomOffset: 4, 149 }, 150 VUI: &SPS_VUI{ 151 TimingInfo: &SPS_TimingInfo{ 152 NumUnitsInTick: 1, 153 TimeScale: 60, 154 }, 155 BitstreamRestriction: &SPS_BitstreamRestriction{ 156 MotionVectorsOverPicBoundariesFlag: true, 157 Log2MaxMvLengthHorizontal: 11, 158 Log2MaxMvLengthVertical: 11, 159 MaxNumReorderFrames: 2, 160 MaxDecFrameBuffering: 4, 161 }, 162 }, 163 }, 164 1920, 165 1080, 166 30, 167 }, 168 { 169 "1920x1080", 170 []byte{ 171 0x67, 0x64, 0x00, 0x29, 0xac, 0x13, 0x31, 0x40, 172 0x78, 0x04, 0x47, 0xde, 0x03, 0xea, 0x02, 0x02, 173 0x03, 0xe0, 0x00, 0x00, 0x03, 0x00, 0x20, 0x00, 174 0x00, 0x06, 0x52, // 0x80, 175 }, 176 SPS{ 177 ProfileIdc: 100, 178 LevelIdc: 41, 179 ChromaFormatIdc: 1, 180 Log2MaxFrameNumMinus4: 8, 181 Log2MaxPicOrderCntLsbMinus4: 5, 182 MaxNumRefFrames: 4, 183 PicWidthInMbsMinus1: 119, 184 PicHeightInMapUnitsMinus1: 33, 185 Direct8x8InferenceFlag: true, 186 FrameCropping: &SPS_FrameCropping{ 187 BottomOffset: 2, 188 }, 189 VUI: &SPS_VUI{ 190 AspectRatioInfoPresentFlag: true, 191 AspectRatioIdc: 1, 192 OverscanInfoPresentFlag: true, 193 OverscanAppropriateFlag: true, 194 VideoSignalTypePresentFlag: true, 195 VideoFormat: 5, 196 ColourDescriptionPresentFlag: true, 197 ColourPrimaries: 1, 198 TransferCharacteristics: 1, 199 MatrixCoefficients: 1, 200 ChromaLocInfoPresentFlag: true, 201 TimingInfo: &SPS_TimingInfo{ 202 NumUnitsInTick: 1, 203 TimeScale: 50, 204 FixedFrameRateFlag: true, 205 }, 206 PicStructPresentFlag: true, 207 }, 208 }, 209 1920, 210 1080, 211 25, 212 }, 213 { 214 "hikvision", 215 []byte{103, 100, 0, 32, 172, 23, 42, 1, 64, 30, 104, 64, 0, 1, 194, 0, 0, 87, 228, 33}, 216 SPS{ 217 ProfileIdc: 100, 218 LevelIdc: 32, 219 ChromaFormatIdc: 1, 220 Log2MaxPicOrderCntLsbMinus4: 4, 221 MaxNumRefFrames: 1, 222 PicWidthInMbsMinus1: 79, 223 PicHeightInMapUnitsMinus1: 59, 224 FrameMbsOnlyFlag: true, 225 Direct8x8InferenceFlag: true, 226 Log2MaxFrameNumMinus4: 10, 227 VUI: &SPS_VUI{ 228 TimingInfo: &SPS_TimingInfo{ 229 NumUnitsInTick: 1800, 230 TimeScale: 90000, 231 FixedFrameRateFlag: true, 232 }, 233 }, 234 }, 235 1280, 236 960, 237 25, 238 }, 239 { 240 "scaling matrix", 241 []byte{ 242 103, 100, 0, 50, 173, 132, 1, 12, 32, 8, 97, 0, 67, 8, 2, 243 24, 64, 16, 194, 0, 132, 59, 80, 20, 0, 90, 211, 244 112, 16, 16, 20, 0, 0, 3, 0, 4, 0, 0, 3, 0, 162, 16, 245 }, 246 SPS{ 247 ProfileIdc: 100, 248 LevelIdc: 50, 249 ChromaFormatIdc: 1, 250 ScalingList4x4: [][]int32{ 251 { 252 16, 16, 16, 16, 16, 16, 16, 16, 253 16, 16, 16, 16, 16, 16, 16, 16, 254 }, 255 { 256 16, 16, 16, 16, 16, 16, 16, 16, 257 16, 16, 16, 16, 16, 16, 16, 16, 258 }, 259 { 260 16, 16, 16, 16, 16, 16, 16, 16, 261 16, 16, 16, 16, 16, 16, 16, 16, 262 }, 263 { 264 16, 16, 16, 16, 16, 16, 16, 16, 265 16, 16, 16, 16, 16, 16, 16, 16, 266 }, 267 { 268 16, 16, 16, 16, 16, 16, 16, 16, 269 16, 16, 16, 16, 16, 16, 16, 16, 270 }, 271 { 272 16, 16, 16, 16, 16, 16, 16, 16, 273 16, 16, 16, 16, 16, 16, 16, 16, 274 }, 275 }, 276 UseDefaultScalingMatrix4x4Flag: []bool{ 277 false, false, false, false, false, false, 278 }, 279 Log2MaxFrameNumMinus4: 6, 280 PicOrderCntType: 2, 281 MaxNumRefFrames: 1, 282 GapsInFrameNumValueAllowedFlag: true, 283 PicWidthInMbsMinus1: 159, 284 PicHeightInMapUnitsMinus1: 89, 285 FrameMbsOnlyFlag: true, 286 Direct8x8InferenceFlag: true, 287 VUI: &SPS_VUI{ 288 VideoSignalTypePresentFlag: true, 289 VideoFormat: 5, 290 VideoFullRangeFlag: true, 291 ColourDescriptionPresentFlag: true, 292 ColourPrimaries: 1, 293 TransferCharacteristics: 1, 294 MatrixCoefficients: 1, 295 TimingInfo: &SPS_TimingInfo{ 296 NumUnitsInTick: 1, 297 TimeScale: 40, 298 FixedFrameRateFlag: true, 299 }, 300 }, 301 }, 302 2560, 303 1440, 304 20, 305 }, 306 { 307 "1920x1080 nvenc hrd", 308 []byte{ 309 103, 100, 0, 42, 172, 44, 172, 7, 310 128, 34, 126, 92, 5, 168, 8, 8, 311 10, 0, 0, 7, 208, 0, 3, 169, 312 129, 192, 0, 0, 76, 75, 0, 0, 313 38, 37, 173, 222, 92, 20, 314 }, 315 SPS{ 316 ProfileIdc: 100, 317 LevelIdc: 42, 318 ChromaFormatIdc: 1, 319 Log2MaxFrameNumMinus4: 4, 320 Log2MaxPicOrderCntLsbMinus4: 4, 321 MaxNumRefFrames: 2, 322 PicWidthInMbsMinus1: 119, 323 PicHeightInMapUnitsMinus1: 67, 324 FrameMbsOnlyFlag: true, 325 Direct8x8InferenceFlag: true, 326 FrameCropping: &SPS_FrameCropping{ 327 BottomOffset: 4, 328 }, 329 VUI: &SPS_VUI{ 330 AspectRatioInfoPresentFlag: true, 331 AspectRatioIdc: 1, 332 VideoSignalTypePresentFlag: true, 333 VideoFormat: 5, 334 ColourDescriptionPresentFlag: true, 335 ColourPrimaries: 1, 336 TransferCharacteristics: 1, 337 MatrixCoefficients: 1, 338 TimingInfo: &SPS_TimingInfo{ 339 NumUnitsInTick: 1000, 340 TimeScale: 120000, 341 FixedFrameRateFlag: true, 342 }, 343 NalHRD: &SPS_HRD{ 344 BitRateValueMinus1: []uint32{39061}, 345 CpbSizeValueMinus1: []uint32{156249}, 346 CbrFlag: []bool{true}, 347 InitialCpbRemovalDelayLengthMinus1: 23, 348 CpbRemovalDelayLengthMinus1: 15, 349 DpbOutputDelayLengthMinus1: 5, 350 TimeOffsetLength: 24, 351 }, 352 PicStructPresentFlag: true, 353 }, 354 }, 355 1920, 356 1080, 357 60, 358 }, 359 { 360 "1920x1080 hikvision nal hrd + vcl hrd", 361 []byte{ 362 103, 77, 0, 41, 154, 100, 3, 192, 363 17, 63, 46, 2, 220, 4, 4, 5, 364 0, 0, 3, 3, 232, 0, 0, 195, 365 80, 232, 96, 0, 186, 180, 0, 2, 366 234, 196, 187, 203, 141, 12, 0, 23, 367 86, 128, 0, 93, 88, 151, 121, 112, 368 160, 369 }, 370 SPS{ 371 ProfileIdc: 77, 372 ChromaFormatIdc: 1, 373 LevelIdc: 41, 374 Log2MaxFrameNumMinus4: 5, 375 Log2MaxPicOrderCntLsbMinus4: 5, 376 MaxNumRefFrames: 1, 377 PicWidthInMbsMinus1: 119, 378 PicHeightInMapUnitsMinus1: 67, 379 FrameMbsOnlyFlag: true, 380 Direct8x8InferenceFlag: true, 381 FrameCropping: &SPS_FrameCropping{ 382 BottomOffset: 4, 383 }, 384 VUI: &SPS_VUI{ 385 AspectRatioInfoPresentFlag: true, 386 AspectRatioIdc: 1, 387 VideoSignalTypePresentFlag: true, 388 VideoFormat: 5, 389 VideoFullRangeFlag: true, 390 ColourDescriptionPresentFlag: true, 391 ColourPrimaries: 1, 392 TransferCharacteristics: 1, 393 MatrixCoefficients: 1, 394 TimingInfo: &SPS_TimingInfo{ 395 NumUnitsInTick: 1000, 396 TimeScale: 50000, 397 FixedFrameRateFlag: true, 398 }, 399 NalHRD: &SPS_HRD{ 400 BitRateScale: 4, 401 CpbSizeScale: 3, 402 BitRateValueMinus1: []uint32{11948}, 403 CpbSizeValueMinus1: []uint32{95585}, 404 CbrFlag: []bool{false}, 405 InitialCpbRemovalDelayLengthMinus1: 23, 406 CpbRemovalDelayLengthMinus1: 15, 407 DpbOutputDelayLengthMinus1: 5, 408 TimeOffsetLength: 24, 409 }, 410 VclHRD: &SPS_HRD{ 411 BitRateScale: 4, 412 CpbSizeScale: 3, 413 BitRateValueMinus1: []uint32{11948}, 414 CpbSizeValueMinus1: []uint32{95585}, 415 CbrFlag: []bool{false}, 416 InitialCpbRemovalDelayLengthMinus1: 23, 417 CpbRemovalDelayLengthMinus1: 15, 418 DpbOutputDelayLengthMinus1: 5, 419 TimeOffsetLength: 24, 420 }, 421 PicStructPresentFlag: true, 422 }, 423 }, 424 1920, 425 1080, 426 25, 427 }, 428 { 429 "1920x1080 mbs_only_flag = 0", 430 []byte{ 431 0x67, 0x4d, 0x40, 0x28, 0xab, 0x60, 0x3c, 0x02, 432 0x23, 0xef, 0x01, 0x10, 0x00, 0x00, 0x03, 0x00, 433 0x10, 0x00, 0x00, 0x03, 0x03, 0x2e, 0x94, 0x00, 434 0x35, 0x64, 0x06, 0xb2, 0x85, 0x08, 0x0e, 0xe2, 435 0xc5, 0x22, 0xc0, 436 }, 437 SPS{ 438 ProfileIdc: 77, 439 ChromaFormatIdc: 1, 440 ConstraintSet1Flag: true, 441 LevelIdc: 40, 442 Log2MaxFrameNumMinus4: 1, 443 Log2MaxPicOrderCntLsbMinus4: 2, 444 MaxNumRefFrames: 2, 445 PicWidthInMbsMinus1: 119, 446 PicHeightInMapUnitsMinus1: 33, 447 Direct8x8InferenceFlag: true, 448 FrameCropping: &SPS_FrameCropping{ 449 BottomOffset: 2, 450 }, 451 VUI: &SPS_VUI{ 452 AspectRatioInfoPresentFlag: true, 453 AspectRatioIdc: 1, 454 TimingInfo: &SPS_TimingInfo{ 455 NumUnitsInTick: 1, 456 TimeScale: 50, 457 FixedFrameRateFlag: true, 458 }, 459 NalHRD: &SPS_HRD{ 460 BitRateScale: 4, 461 CpbSizeScale: 10, 462 BitRateValueMinus1: []uint32{3416}, 463 CpbSizeValueMinus1: []uint32{213}, 464 CbrFlag: []bool{false}, 465 InitialCpbRemovalDelayLengthMinus1: 20, 466 CpbRemovalDelayLengthMinus1: 5, 467 DpbOutputDelayLengthMinus1: 1, 468 }, 469 PicStructPresentFlag: true, 470 BitstreamRestriction: &SPS_BitstreamRestriction{ 471 MotionVectorsOverPicBoundariesFlag: true, 472 MaxBytesPerPicDenom: 2, 473 Log2MaxMvLengthHorizontal: 10, 474 Log2MaxMvLengthVertical: 9, 475 MaxNumReorderFrames: 1, 476 MaxDecFrameBuffering: 4, 477 }, 478 }, 479 }, 480 1920, 481 1080, 482 25, 483 }, 484 } { 485 t.Run(ca.name, func(t *testing.T) { 486 var sps SPS 487 err := sps.Unmarshal(ca.byts) 488 require.NoError(t, err) 489 require.Equal(t, ca.sps, sps) 490 require.Equal(t, ca.width, sps.Width()) 491 require.Equal(t, ca.height, sps.Height()) 492 require.Equal(t, ca.fps, sps.FPS()) 493 }) 494 } 495 } 496 497 func BenchmarkSPSUnmarshal(b *testing.B) { 498 for i := 0; i < b.N; i++ { 499 var sps SPS 500 sps.Unmarshal([]byte{ //nolint:errcheck 501 103, 77, 0, 41, 154, 100, 3, 192, 502 17, 63, 46, 2, 220, 4, 4, 5, 503 0, 0, 3, 3, 232, 0, 0, 195, 504 80, 232, 96, 0, 186, 180, 0, 2, 505 234, 196, 187, 203, 141, 12, 0, 23, 506 86, 128, 0, 93, 88, 151, 121, 112, 507 160, 508 }) 509 } 510 } 511 512 func FuzzSPSUnmarshal(f *testing.F) { 513 f.Fuzz(func(_ *testing.T, b []byte) { 514 var sps SPS 515 sps.Unmarshal(b) //nolint:errcheck 516 }) 517 }