github.com/bluenviron/mediacommon@v1.9.3/pkg/formats/fmp4/parts_test.go (about) 1 package fmp4 2 3 import ( 4 "bytes" 5 "testing" 6 7 "github.com/bluenviron/mediacommon/pkg/formats/fmp4/seekablebuffer" 8 "github.com/stretchr/testify/require" 9 ) 10 11 var casesParts = []struct { 12 name string 13 parts Parts 14 enc []byte 15 }{ 16 { 17 "single part", 18 Parts{{ 19 SequenceNumber: 4, 20 Tracks: []*PartTrack{ 21 { 22 ID: 256, 23 BaseTime: 90000, 24 Samples: []*PartSample{ 25 { 26 Duration: 30, 27 PTSOffset: 0, 28 IsNonSyncSample: false, 29 Payload: []byte{1, 2}, 30 }, 31 { 32 Duration: 60, 33 PTSOffset: 15, 34 IsNonSyncSample: true, 35 Payload: []byte{3, 4}, 36 }, 37 }, 38 }, 39 { 40 ID: 257, 41 BaseTime: 44100, 42 Samples: []*PartSample{ 43 { 44 Duration: 30, 45 Payload: []byte{5, 6}, 46 }, 47 { 48 Duration: 30, 49 Payload: []byte{7, 8}, 50 }, 51 }, 52 }, 53 }, 54 }}, 55 []byte{ 56 0x00, 0x00, 0x00, 0xc8, 0x6d, 0x6f, 0x6f, 0x66, 57 0x00, 0x00, 0x00, 0x10, 0x6d, 0x66, 0x68, 0x64, 58 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 59 0x00, 0x00, 0x00, 0x60, 0x74, 0x72, 0x61, 0x66, 60 0x00, 0x00, 0x00, 0x10, 0x74, 0x66, 0x68, 0x64, 61 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 62 0x00, 0x00, 0x00, 0x14, 0x74, 0x66, 0x64, 0x74, 63 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 64 0x00, 0x01, 0x5f, 0x90, 0x00, 0x00, 0x00, 0x34, 65 0x74, 0x72, 0x75, 0x6e, 0x01, 0x00, 0x0f, 0x01, 66 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xd0, 67 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x02, 68 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 69 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x02, 70 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 71 0x00, 0x00, 0x00, 0x50, 0x74, 0x72, 0x61, 0x66, 72 0x00, 0x00, 0x00, 0x10, 0x74, 0x66, 0x68, 0x64, 73 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 74 0x00, 0x00, 0x00, 0x14, 0x74, 0x66, 0x64, 0x74, 75 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 76 0x00, 0x00, 0xac, 0x44, 0x00, 0x00, 0x00, 0x24, 77 0x74, 0x72, 0x75, 0x6e, 0x01, 0x00, 0x03, 0x01, 78 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xd4, 79 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x02, 80 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x02, 81 0x00, 0x00, 0x00, 0x10, 0x6d, 0x64, 0x61, 0x74, 82 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 83 }, 84 }, 85 { 86 "concatenated parts", 87 Parts{ 88 { 89 SequenceNumber: 4, 90 Tracks: []*PartTrack{ 91 { 92 ID: 100, 93 BaseTime: 90000, 94 Samples: []*PartSample{ 95 { 96 Duration: 30, 97 PTSOffset: 0, 98 IsNonSyncSample: false, 99 Payload: []byte{1, 2}, 100 }, 101 }, 102 }, 103 }, 104 }, 105 { 106 SequenceNumber: 4, 107 Tracks: []*PartTrack{ 108 { 109 ID: 100, 110 BaseTime: 180000, 111 Samples: []*PartSample{ 112 { 113 Duration: 30, 114 PTSOffset: 0, 115 IsNonSyncSample: false, 116 Payload: []byte{3, 4}, 117 }, 118 }, 119 }, 120 }, 121 }, 122 }, 123 []byte{ 124 0x00, 0x00, 0x00, 0x60, 0x6d, 0x6f, 0x6f, 0x66, 125 0x00, 0x00, 0x00, 0x10, 0x6d, 0x66, 0x68, 0x64, 126 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 127 0x00, 0x00, 0x00, 0x48, 0x74, 0x72, 0x61, 0x66, 128 0x00, 0x00, 0x00, 0x10, 0x74, 0x66, 0x68, 0x64, 129 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 130 0x00, 0x00, 0x00, 0x14, 0x74, 0x66, 0x64, 0x74, 131 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 132 0x00, 0x01, 0x5f, 0x90, 0x00, 0x00, 0x00, 0x1c, 133 0x74, 0x72, 0x75, 0x6e, 0x01, 0x00, 0x03, 0x01, 134 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x68, 135 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x02, 136 0x00, 0x00, 0x00, 0x0a, 0x6d, 0x64, 0x61, 0x74, 137 0x01, 0x02, 0x00, 0x00, 0x00, 0x60, 0x6d, 0x6f, 138 0x6f, 0x66, 0x00, 0x00, 0x00, 0x10, 0x6d, 0x66, 139 0x68, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 140 0x00, 0x04, 0x00, 0x00, 0x00, 0x48, 0x74, 0x72, 141 0x61, 0x66, 0x00, 0x00, 0x00, 0x10, 0x74, 0x66, 142 0x68, 0x64, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 143 0x00, 0x64, 0x00, 0x00, 0x00, 0x14, 0x74, 0x66, 144 0x64, 0x74, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 145 0x00, 0x00, 0x00, 0x02, 0xbf, 0x20, 0x00, 0x00, 146 0x00, 0x1c, 0x74, 0x72, 0x75, 0x6e, 0x01, 0x00, 147 0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 148 0x00, 0x68, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 149 0x00, 0x02, 0x00, 0x00, 0x00, 0x0a, 0x6d, 0x64, 150 0x61, 0x74, 0x03, 0x04, 151 }, 152 }, 153 } 154 155 func TestPartsMarshal(t *testing.T) { 156 for _, ca := range casesParts { 157 t.Run(ca.name, func(t *testing.T) { 158 var buf seekablebuffer.Buffer 159 err := ca.parts.Marshal(&buf) 160 require.NoError(t, err) 161 require.Equal(t, ca.enc, buf.Bytes()) 162 }) 163 } 164 } 165 166 func TestPartsUnmarshal(t *testing.T) { 167 for _, ca := range casesParts { 168 t.Run(ca.name, func(t *testing.T) { 169 var parts Parts 170 err := parts.Unmarshal(ca.enc) 171 require.NoError(t, err) 172 require.Equal(t, ca.parts, parts) 173 }) 174 } 175 } 176 177 func FuzzPartsUnmarshal(f *testing.F) { 178 for _, ca := range casesParts { 179 f.Add(ca.enc) 180 } 181 182 f.Fuzz(func(_ *testing.T, b []byte) { 183 var parts Parts 184 parts.Unmarshal(b) //nolint:errcheck 185 }) 186 } 187 188 func BenchmarkPartsUnmarshal(b *testing.B) { 189 for i := 0; i < b.N; i++ { 190 for _, ca := range casesParts { 191 var parts Parts 192 parts.Unmarshal(ca.enc) //nolint:errcheck 193 } 194 } 195 } 196 197 func BenchmarkPartsMarshal(b *testing.B) { 198 parts := Parts{{ 199 Tracks: []*PartTrack{{ 200 ID: 1, 201 Samples: make([]*PartSample, 10000), 202 }}, 203 }} 204 205 for i := 0; i < 10000; i++ { 206 parts[0].Tracks[0].Samples[i] = &PartSample{ 207 Duration: 90000, 208 Payload: bytes.Repeat([]byte{1}, 16), 209 } 210 } 211 212 for i := 0; i < b.N; i++ { 213 var buf seekablebuffer.Buffer 214 parts.Marshal(&buf) //nolint:errcheck 215 } 216 }