Files
mediacommon/pkg/codecs/h264/sps_test.go
2023-04-01 10:53:17 +02:00

463 lines
12 KiB
Go

//go:build go1.18
// +build go1.18
package h264
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestSPSUnmarshal(t *testing.T) {
for _, ca := range []struct {
name string
byts []byte
sps SPS
width int
height int
fps float64
}{
{
"352x288",
[]byte{
0x67, 0x64, 0x00, 0x0c, 0xac, 0x3b, 0x50, 0xb0,
0x4b, 0x42, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00,
0x00, 0x03, 0x00, 0x3d, 0x08,
},
SPS{
ProfileIdc: 100,
LevelIdc: 12,
ChromeFormatIdc: 1,
Log2MaxFrameNumMinus4: 6,
PicOrderCntType: 2,
MaxNumRefFrames: 1,
GapsInFrameNumValueAllowedFlag: true,
PicWidthInMbsMinus1: 21,
PicHeightInMapUnitsMinus1: 17,
FrameMbsOnlyFlag: true,
Direct8x8InferenceFlag: true,
VUI: &SPS_VUI{
TimingInfo: &SPS_TimingInfo{
NumUnitsInTick: 1,
TimeScale: 30,
FixedFrameRateFlag: true,
},
},
},
352,
288,
15,
},
{
"1280x720",
[]byte{
0x67, 0x64, 0x00, 0x1f, 0xac, 0xd9, 0x40, 0x50,
0x05, 0xbb, 0x01, 0x6c, 0x80, 0x00, 0x00, 0x03,
0x00, 0x80, 0x00, 0x00, 0x1e, 0x07, 0x8c, 0x18,
0xcb,
},
SPS{
ProfileIdc: 100,
LevelIdc: 31,
ChromeFormatIdc: 1,
Log2MaxPicOrderCntLsbMinus4: 2,
MaxNumRefFrames: 4,
PicWidthInMbsMinus1: 79,
PicHeightInMapUnitsMinus1: 44,
FrameMbsOnlyFlag: true,
Direct8x8InferenceFlag: true,
VUI: &SPS_VUI{
AspectRatioInfoPresentFlag: true,
AspectRatioIdc: 1,
VideoSignalTypePresentFlag: true,
VideoFormat: 5,
VideoFullRangeFlag: true,
TimingInfo: &SPS_TimingInfo{
NumUnitsInTick: 1,
TimeScale: 60,
},
BitstreamRestriction: &SPS_BitstreamRestriction{
MotionVectorsOverPicBoundariesFlag: true,
Log2MaxMvLengthHorizontal: 11,
Log2MaxMvLengthVertical: 11,
MaxNumReorderFrames: 2,
MaxDecFrameBuffering: 4,
},
},
},
1280,
720,
30,
},
{
"1920x1080 baseline",
[]byte{
0x67, 0x42, 0xc0, 0x28, 0xd9, 0x00, 0x78, 0x02,
0x27, 0xe5, 0x84, 0x00, 0x00, 0x03, 0x00, 0x04,
0x00, 0x00, 0x03, 0x00, 0xf0, 0x3c, 0x60, 0xc9, 0x20,
},
SPS{
ProfileIdc: 66,
ConstraintSet0Flag: true,
ConstraintSet1Flag: true,
LevelIdc: 40,
PicOrderCntType: 2,
MaxNumRefFrames: 3,
PicWidthInMbsMinus1: 119,
PicHeightInMapUnitsMinus1: 67,
FrameMbsOnlyFlag: true,
Direct8x8InferenceFlag: true,
FrameCropping: &SPS_FrameCropping{
BottomOffset: 4,
},
VUI: &SPS_VUI{
TimingInfo: &SPS_TimingInfo{
NumUnitsInTick: 1,
TimeScale: 60,
},
BitstreamRestriction: &SPS_BitstreamRestriction{
MotionVectorsOverPicBoundariesFlag: true,
Log2MaxMvLengthHorizontal: 11,
Log2MaxMvLengthVertical: 11,
MaxDecFrameBuffering: 3,
},
},
},
1920,
1080,
30,
},
{
"1920x1080 nvidia",
[]byte{
0x67, 0x64, 0x00, 0x28, 0xac, 0xd9, 0x40, 0x78,
0x02, 0x27, 0xe5, 0x84, 0x00, 0x00, 0x03, 0x00,
0x04, 0x00, 0x00, 0x03, 0x00, 0xf0, 0x3c, 0x60,
0xc6, 0x58,
},
SPS{
ProfileIdc: 100,
LevelIdc: 40,
ChromeFormatIdc: 1,
Log2MaxPicOrderCntLsbMinus4: 2,
MaxNumRefFrames: 4,
PicWidthInMbsMinus1: 119,
PicHeightInMapUnitsMinus1: 67,
FrameMbsOnlyFlag: true,
Direct8x8InferenceFlag: true,
FrameCropping: &SPS_FrameCropping{
BottomOffset: 4,
},
VUI: &SPS_VUI{
TimingInfo: &SPS_TimingInfo{
NumUnitsInTick: 1,
TimeScale: 60,
},
BitstreamRestriction: &SPS_BitstreamRestriction{
MotionVectorsOverPicBoundariesFlag: true,
Log2MaxMvLengthHorizontal: 11,
Log2MaxMvLengthVertical: 11,
MaxNumReorderFrames: 2,
MaxDecFrameBuffering: 4,
},
},
},
1920,
1080,
30,
},
{
"1920x1080",
[]byte{
0x67, 0x64, 0x00, 0x29, 0xac, 0x13, 0x31, 0x40,
0x78, 0x04, 0x47, 0xde, 0x03, 0xea, 0x02, 0x02,
0x03, 0xe0, 0x00, 0x00, 0x03, 0x00, 0x20, 0x00,
0x00, 0x06, 0x52, // 0x80,
},
SPS{
ProfileIdc: 100,
LevelIdc: 41,
ChromeFormatIdc: 1,
Log2MaxFrameNumMinus4: 8,
Log2MaxPicOrderCntLsbMinus4: 5,
MaxNumRefFrames: 4,
PicWidthInMbsMinus1: 119,
PicHeightInMapUnitsMinus1: 33,
Direct8x8InferenceFlag: true,
FrameCropping: &SPS_FrameCropping{
BottomOffset: 2,
},
VUI: &SPS_VUI{
AspectRatioInfoPresentFlag: true,
AspectRatioIdc: 1,
OverscanInfoPresentFlag: true,
OverscanAppropriateFlag: true,
VideoSignalTypePresentFlag: true,
VideoFormat: 5,
ColourDescriptionPresentFlag: true,
ColourPrimaries: 1,
TransferCharacteristics: 1,
MatrixCoefficients: 1,
ChromaLocInfoPresentFlag: true,
TimingInfo: &SPS_TimingInfo{
NumUnitsInTick: 1,
TimeScale: 50,
FixedFrameRateFlag: true,
},
PicStructPresentFlag: true,
},
},
1920,
1084,
25,
},
{
"hikvision",
[]byte{103, 100, 0, 32, 172, 23, 42, 1, 64, 30, 104, 64, 0, 1, 194, 0, 0, 87, 228, 33},
SPS{
ProfileIdc: 100,
LevelIdc: 32,
ChromeFormatIdc: 1,
Log2MaxPicOrderCntLsbMinus4: 4,
MaxNumRefFrames: 1,
PicWidthInMbsMinus1: 79,
PicHeightInMapUnitsMinus1: 59,
FrameMbsOnlyFlag: true,
Direct8x8InferenceFlag: true,
Log2MaxFrameNumMinus4: 10,
VUI: &SPS_VUI{
TimingInfo: &SPS_TimingInfo{
NumUnitsInTick: 1800,
TimeScale: 90000,
FixedFrameRateFlag: true,
},
},
},
1280,
960,
25,
},
{
"scaling matrix",
[]byte{
103, 100, 0, 50, 173, 132, 1, 12, 32, 8, 97, 0, 67, 8, 2,
24, 64, 16, 194, 0, 132, 59, 80, 20, 0, 90, 211,
112, 16, 16, 20, 0, 0, 3, 0, 4, 0, 0, 3, 0, 162, 16,
},
SPS{
ProfileIdc: 100,
LevelIdc: 50,
ChromeFormatIdc: 1,
ScalingList4x4: [][]int32{
{
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
},
{
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
},
{
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
},
{
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
},
{
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
},
{
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
},
},
UseDefaultScalingMatrix4x4Flag: []bool{
false, false, false, false, false, false,
},
Log2MaxFrameNumMinus4: 6,
PicOrderCntType: 2,
MaxNumRefFrames: 1,
GapsInFrameNumValueAllowedFlag: true,
PicWidthInMbsMinus1: 159,
PicHeightInMapUnitsMinus1: 89,
FrameMbsOnlyFlag: true,
Direct8x8InferenceFlag: true,
VUI: &SPS_VUI{
VideoSignalTypePresentFlag: true,
VideoFormat: 5,
VideoFullRangeFlag: true,
ColourDescriptionPresentFlag: true,
ColourPrimaries: 1,
TransferCharacteristics: 1,
MatrixCoefficients: 1,
TimingInfo: &SPS_TimingInfo{
NumUnitsInTick: 1,
TimeScale: 40,
FixedFrameRateFlag: true,
},
},
},
2560,
1440,
20,
},
{
"1920x1080 nvenc hrd",
[]byte{
103, 100, 0, 42, 172, 44, 172, 7,
128, 34, 126, 92, 5, 168, 8, 8,
10, 0, 0, 7, 208, 0, 3, 169,
129, 192, 0, 0, 76, 75, 0, 0,
38, 37, 173, 222, 92, 20,
},
SPS{
ProfileIdc: 100,
LevelIdc: 42,
ChromeFormatIdc: 1,
Log2MaxFrameNumMinus4: 4,
Log2MaxPicOrderCntLsbMinus4: 4,
MaxNumRefFrames: 2,
PicWidthInMbsMinus1: 119,
PicHeightInMapUnitsMinus1: 67,
FrameMbsOnlyFlag: true,
Direct8x8InferenceFlag: true,
FrameCropping: &SPS_FrameCropping{
BottomOffset: 4,
},
VUI: &SPS_VUI{
AspectRatioInfoPresentFlag: true,
AspectRatioIdc: 1,
VideoSignalTypePresentFlag: true,
VideoFormat: 5,
ColourDescriptionPresentFlag: true,
ColourPrimaries: 1,
TransferCharacteristics: 1,
MatrixCoefficients: 1,
TimingInfo: &SPS_TimingInfo{
NumUnitsInTick: 1000,
TimeScale: 120000,
FixedFrameRateFlag: true,
},
NalHRD: &SPS_HRD{
BitRateValueMinus1: []uint32{39061},
CpbSizeValueMinus1: []uint32{156249},
CbrFlag: []bool{true},
InitialCpbRemovalDelayLengthMinus1: 23,
CpbRemovalDelayLengthMinus1: 15,
DpbOutputDelayLengthMinus1: 5,
TimeOffsetLength: 24,
},
PicStructPresentFlag: true,
},
},
1920,
1080,
60,
},
{
"1920x1080 hikvision nal hrd + vcl hrd",
[]byte{
103, 77, 0, 41, 154, 100, 3, 192,
17, 63, 46, 2, 220, 4, 4, 5,
0, 0, 3, 3, 232, 0, 0, 195,
80, 232, 96, 0, 186, 180, 0, 2,
234, 196, 187, 203, 141, 12, 0, 23,
86, 128, 0, 93, 88, 151, 121, 112,
160,
},
SPS{
ProfileIdc: 77,
LevelIdc: 41,
Log2MaxFrameNumMinus4: 5,
Log2MaxPicOrderCntLsbMinus4: 5,
MaxNumRefFrames: 1,
PicWidthInMbsMinus1: 119,
PicHeightInMapUnitsMinus1: 67,
FrameMbsOnlyFlag: true,
Direct8x8InferenceFlag: true,
FrameCropping: &SPS_FrameCropping{
BottomOffset: 4,
},
VUI: &SPS_VUI{
AspectRatioInfoPresentFlag: true,
AspectRatioIdc: 1,
VideoSignalTypePresentFlag: true,
VideoFormat: 5,
VideoFullRangeFlag: true,
ColourDescriptionPresentFlag: true,
ColourPrimaries: 1,
TransferCharacteristics: 1,
MatrixCoefficients: 1,
TimingInfo: &SPS_TimingInfo{
NumUnitsInTick: 1000,
TimeScale: 50000,
FixedFrameRateFlag: true,
},
NalHRD: &SPS_HRD{
BitRateScale: 4,
CpbSizeScale: 3,
BitRateValueMinus1: []uint32{11948},
CpbSizeValueMinus1: []uint32{95585},
CbrFlag: []bool{false},
InitialCpbRemovalDelayLengthMinus1: 23,
CpbRemovalDelayLengthMinus1: 15,
DpbOutputDelayLengthMinus1: 5,
TimeOffsetLength: 24,
},
VclHRD: &SPS_HRD{
BitRateScale: 4,
CpbSizeScale: 3,
BitRateValueMinus1: []uint32{11948},
CpbSizeValueMinus1: []uint32{95585},
CbrFlag: []bool{false},
InitialCpbRemovalDelayLengthMinus1: 23,
CpbRemovalDelayLengthMinus1: 15,
DpbOutputDelayLengthMinus1: 5,
TimeOffsetLength: 24,
},
PicStructPresentFlag: true,
},
},
1920,
1080,
25,
},
} {
t.Run(ca.name, func(t *testing.T) {
var sps SPS
err := sps.Unmarshal(ca.byts)
require.NoError(t, err)
require.Equal(t, ca.sps, sps)
require.Equal(t, ca.width, sps.Width())
require.Equal(t, ca.height, sps.Height())
require.Equal(t, ca.fps, sps.FPS())
})
}
}
func BenchmarkSPSUnmarshal(b *testing.B) {
for i := 0; i < b.N; i++ {
var sps SPS
sps.Unmarshal([]byte{
103, 77, 0, 41, 154, 100, 3, 192,
17, 63, 46, 2, 220, 4, 4, 5,
0, 0, 3, 3, 232, 0, 0, 195,
80, 232, 96, 0, 186, 180, 0, 2,
234, 196, 187, 203, 141, 12, 0, 23,
86, 128, 0, 93, 88, 151, 121, 112,
160,
})
}
}
func FuzzSPSUnmarshal(f *testing.F) {
f.Fuzz(func(t *testing.T, b []byte) {
var sps SPS
sps.Unmarshal(b)
})
}