-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathpmt.go
476 lines (442 loc) · 23.5 KB
/
pmt.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
package mpeg2ts
import (
"fmt"
)
type StreamType byte
const (
StreamTypeReserved = StreamType(0x00) // ITU-T | ISO/IEC Reserved
StreamTypeISO11172_2_Video = StreamType(0x01) // ISO/IEC 11172-2 Video
StreamTypeISO13818_2_Video = StreamType(0x02) // Rec. ITU-T H.262 | ISO/IEC 13818-2 Video or ISO/IEC 11172-2 constrained parameter video stream
StreamTypeISO11172_3_Audio = StreamType(0x03) // ISO/IEC 11172-3 Audio
StreamTypeISO13818_3_Audio = StreamType(0x04) // ISO/IEC 13818-3 Audio
StreamTypeISO13818_1_PrivateSections = StreamType(0x05) // Rec. ITU-T H.222.0 | ISO/IEC 13818-1 private_sections
StreamTypeISO13818_1_PES = StreamType(0x06) // Rec. ITU-T H.222.0 | ISO/IEC 13818-1 PES packets containing private data
StreamTypeISO13522_MHEG = StreamType(0x07) // ISO/IEC 13522 MHEG
StreamTypeISO13818_AnnexA = StreamType(0x08) // Rec. ITU-T H.222.0 | ISO/IEC 13818-1 Annex A DSM-CC
StreamTypeH222_1 = StreamType(0x09) // Rec. ITU-T H.222.1
StreamTypeISO13818_6_TypeA = StreamType(0x0A) // ISO/IEC 13818-6 type A
StreamTypeISO13818_6_TypeB = StreamType(0x0B) // ISO/IEC 13818-6 type B
StreamTypeISO13818_6_TypeC = StreamType(0x0C) // ISO/IEC 13818-6 type C
StreamTypeISO13818_6_TypeD = StreamType(0x0D) // ISO/IEC 13818-6 type D
StreamTypeISO13818_1_Aux = StreamType(0x0E) // Rec. ITU-T H.222.0 | ISO/IEC 13818-1 auxiliary
StreamTypeISO13818_7_AudioWithADTS = StreamType(0x0F) // ISO/IEC 13818-7 Audio with ADTS transport syntax
StreamTypeISO14496_2_Visual = StreamType(0x10) // ISO/IEC 14496-2 Visual
StreamTypeISO14496_3_AudioWithLATM = StreamType(0x11) // ISO/IEC 14496-3 Audio with the LATM transport syntax as defined in ISO/IEC 14496-3
StreamTypeISO14496_1_PES = StreamType(0x12) // ISO/IEC 14496-1 SL-packetized stream or FlexMux stream carried in PES packets
StreamTypeISO14496_1_Sections = StreamType(0x13) // ISO/IEC 14496-1 SL-packetized stream or FlexMux stream carried in ISO/IEC 14496_sections
StreamTypeISO13818_6_SDP = StreamType(0x14) // ISO/IEC 13818-6 Synchronized Download Protocol
StreamTypeMetadataInPES = StreamType(0x15) // Metadata carried in PES packets
StreamTypeMetadataInSections = StreamType(0x16) // Metadata carried in metadata_sections
StreamTypeMetadataInDataCarousel = StreamType(0x17) // Metadata carried in ISO/IEC 13818-6 Data Carousel
StreamTypeMetadataInObjectCarousel = StreamType(0x18) // Metadata carried in ISO/IEC 13818-6 Object Carousel
StreamTypeMetadataInSDP = StreamType(0x19) // Metadata carried in ISO/IEC 13818-6 Synchronized Download Protocol
StreamTypeIPMP = StreamType(0x1A) // IPMP stream (defined in ISO/IEC 13818-11, MPEG-2 IPMP)
StreamTypeAVC = StreamType(0x1B) // AVC video stream conforming to one or more profiles defined in Annex A of Rec. ITU-T H.264 |
StreamTypeISO14496_3_Audio = StreamType(0x1C) // ISO/IEC 14496-3 Audio, without using any additional transport syntax, such as DST, ALS and SLS
StreamTypeISO14496_17_Text = StreamType(0x1D) // ISO/IEC 14496-17 Text
StreamTypeISO23002_3_AuxVideo = StreamType(0x1E) // Auxiliary video stream as defined in ISO/IEC 23002-3
StreamTypeISO14496_10_SVC = StreamType(0x1F) // SVC video sub-bitstream of an AVC video stream conforming to one or more profiles defined in Annex G of Rec. ITU-T H.264 | ISO/IEC 14496-10
StreamTypeISO14496_10_MVC = StreamType(0x20) // MVC video sub-bitstream of an AVC video stream conforming to one or more profiles defined in Annex H of Rec. ITU-T H.264 | ISO/IEC 14496-10
// StreamType = StreamType(0x21) // Video stream conforming to one or more profiles as defined in Rec. ITU-T T.800 | ISO/IEC 15444-1
// StreamType = StreamType(0x22) // Additional view Rec. ITU-T H.262 | ISO/IEC 13818-2 video stream for service-compatible stereoscopic 3D services (see Notes 3 and 4)
// StreamType = StreamType(0x23) // Additional view Rec. ITU-T H.264 | ISO/IEC 14496-10 video stream conforming to one or more profiles defined in Annex A for service-compatible stereoscopic 3D services (see Notes 3 and 4)
// StreamType = StreamType(0x24) // Rec. ITU-T H.265 | ISO/IEC 23008-2 video stream or an HEVC temporal video sub-bitstream
// StreamType = StreamType(0x25) // HEVC temporal video subset of an HEVC video stream conforming to one or more profiles defined in Annex A of Rec. ITU-T H.265 | ISO/IEC 23008-2
// StreamType = StreamType(0x26) // MVCD video sub-bitstream of an AVC video stream conforming to one or more profiles defined in Annex I of Rec. ITU-T H.264 | ISO/IEC 14496-10
// StreamType = StreamType(0x27) // Timeline and External Media Information Stream (see Annex U)
// StreamType = StreamType(0x28) // HEVC enhancement sub-partition which includes TemporalId 0 of an HEVC video stream where all NALs units contained in the stream conform to one or more profiles defined in Annex G of Rec. ITU-T H.265 | ISO/IEC 23008-2
// StreamType = StreamType(0x29) // HEVC temporal enhancement sub-partition of an HEVC video stream where all NAL units contained in the stream conform to one or more profiles defined in Annex G of Rec. ITU-T H.265 | ISO/IEC 23008-2
// StreamType = StreamType(0x2A) // HEVC enhancement sub-partition which includes TemporalId 0 of an HEVC video stream where all NAL units contained in the stream conform to one or more profiles defined in Annex H of Rec. ITU-T H.265 | ISO/IEC 23008-2
// StreamType = StreamType(0x2B) // HEVC temporal enhancement sub-partition of an HEVC video stream where all NAL units contained in the stream conform to one or more profiles defined in Annex H of Rec. ITU-T H.265 | ISO/IEC 23008-2
// StreamType = StreamType(0x2C) // Green access units carried in MPEG-2 sections
// StreamType = StreamType(0x2D) // ISO/IEC 23008-3 Audio with MHAS transport syntax – main stream
// StreamType = StreamType(0x2E) // ISO/IEC 23008-3 Audio with MHAS transport syntax – auxiliary stream
// StreamType = StreamType(0x2F) // Quality access units carried in sections
// StreamType = StreamType(0x30) // Media Orchestration Access Units carried in sections
// StreamType = StreamType(0x31) // Substream of a Rec. ITU-T H.265 | ISO/IEC 23008 2 video stream that contains a Motion Constrained Tile Set, parameter sets, slice headers or a combination thereof. See 2.17.5.1.
// StreamType = StreamType(0x32) // JPEG XS video stream conforming to one or more profiles as defined in ISO/IEC 21122-2
// StreamType = StreamType(0x33) // VVC video stream or a VVC temporal video sub-bitstream conforming to one or more profiles defined in Annex A of Rec. ITU-T H.266 | ISO/IEC 23090-3
// StreamType = StreamType(0x34) // VVC temporal video subset of a VVC video stream conforming to one or more profiles defined in Annex A of Rec. ITU-T H.266 | ISO/IEC 23090-3
// StreamType = StreamType(0x35) // EVC video stream or an EVC temporal video sub-bitstream conforming to one or more profiles defined in ISO/IEC 23094-1
// StreamType = StreamType(0x36) // .. 0x7E Rec. ITU-T H.222.0 | ISO/IEC 13818-1 reserved
// StreamType = StreamType(0x7F) // IPMP stream
StreamTypeUserPrivateMin = StreamType(0x80)
StreamTypeUserPrivateMax = StreamType(0xFF)
)
// Program Map Table
// Rec. ITU-T H.222.0 (06/2021) p.57
type PMT struct {
Pointer byte
TableID byte
SectionSyntaxIndicator bool
Reserved1 byte
SectionLength uint16
ProgramNumber uint16
Reserved2 byte
Version byte
CurrentNextIndicator bool
SectionNumber byte
LastSectionNumber byte
Reserved3 byte
PCR_PID PID
Reserved4 byte
ProgramInfoLength uint16
Descriptors []ProgramElementDescriptor
Streams []StreamInfo
CRC32 uint
}
type StreamInfo struct {
Type StreamType
Reserved1 byte
ElementaryPID PID
Reserved2 byte
ESInfoLength uint16
Descriptors []ProgramElementDescriptor
}
func (s *StreamInfo) IsUserPrivateStream() bool {
return s.Type >= StreamTypeUserPrivateMin && s.Type <= StreamTypeUserPrivateMax
}
type ProgramElementDescriptor struct {
Tag uint8
Length uint8
VideoStreamDescriptor
RegistrationDescriptor
ISO639LanguageDescriptor
UserPrivateDescriptor
MPEG4VideoDescriptor
MPEG4AudioDescriptor
AVCVideoDescriptor
}
type VideoStreamDescriptor struct {
MultipleFrameRateFlag bool
FrameRateCode uint8
MPEG1OnlyFlag bool
ConstrainedParameterFlag bool
StillPictureFlag bool
// MPEG1 Only
ProfileAndLevelIndication uint8
ChromaFormat uint8
FrameRateExtensionFlag bool
Reserved uint8
}
type RegistrationDescriptor struct {
// Rec. ITU-T H.222.0 (06-2021) pp.81-82
FormatIdentifier []byte
AdditionalIdentificationInfo []byte
}
type ISO639LanguageDescriptor struct {
// Rec. ITU-T H.222.0 (06-2021) pp.86-87
Languages []ISO639LanguageRelation
}
type ISO639LanguageRelation struct {
ISO639LanguageCode int // 24
AudioType uint8 // 8
}
type UserPrivateDescriptor struct {
Data []byte
}
type MPEG4VideoDescriptor struct {
// Rec. ITU-T H.222.0 (06-2021) p.92
VisualProfileAndLevel uint8
}
type MPEG4AudioDescriptor struct {
// Rec. ITU-T H.222.0 (06-2021) p.92
AudioProfileAndLevel uint8
}
type AVCVideoDescriptor struct {
// Rec. ITU-T H.222.0 (06-2021) pp.105-106
ProfileIDC uint8
ConstraintSet0Flag bool
ConstraintSet1Flag bool
ConstraintSet2Flag bool
ConstraintSet3Flag bool
ConstraintSet4Flag bool
ConstraintSet5Flag bool
AVCCompatibleFlags uint8
LevelIDC uint8
AVCStillPresent bool
AVC24HourPictureFlag bool
FramePackingSEINotPresentFlag bool
Reserved uint8
}
func (p *Packet) ParsePMT(disableCRCcheck bool) (PMT, error) {
pmt := PMT{}
payload, err := p.GetPayload()
if err != nil {
return PMT{}, err
}
// fmt.Printf("raw pmt dump %#v\r\n", payload)
// Rec. ITU-T H.222.0 (06-2021) pp.57-60,p.261
pmt.Pointer = payload[0]
pmt.TableID = payload[1] // 8
pmt.SectionSyntaxIndicator = ((payload[2] >> 7) & 0x01) == 1 // 1
if ((payload[2] >> 6) & 0x01) == 1 { // 1
return PMT{}, fmt.Errorf("invalid format")
}
pmt.Reserved1 = (payload[2] >> 4) & 0x03 // 2
pmt.SectionLength = uint16(payload[2]&0x0F)<<8 | uint16(payload[3]) // 12
pmt.ProgramNumber = uint16(payload[4])<<8 | uint16(payload[5]) // 16
pmt.Reserved2 = (payload[6] >> 6) & 0x03 // 2
pmt.Version = (payload[6] >> 1) & 0x1F // 5
pmt.CurrentNextIndicator = (payload[6] & 0x01) == 0x01 // 1
pmt.SectionNumber = payload[7] // 8
pmt.LastSectionNumber = payload[8] // 8
pmt.Reserved3 = (payload[9] >> 5) & 0x07 // 3
pmt.PCR_PID = PID(uint16(payload[9]&0x1f)<<8 | uint16(payload[10])) // 13
pmt.Reserved4 = (payload[11] >> 4) & 0x0f // 4
pmt.ProgramInfoLength = uint16(payload[11]&0x0F)<<8 | uint16(payload[12])
index := 13
// fmt.Printf("pmt %d dump %x table:%x synind:%t len:%d pid:%d pil:%d\r\n", p.Index, pmt.Pointer, pmt.TableID, pmt.SectionSyntaxIndicator, pmt.SectionLength, pmt.PCR_PID, pmt.ProgramInfoLength)
var diff int
for i := 0; i < int(pmt.ProgramInfoLength); i += diff { // N loop descriptors
pmt.Descriptors, diff, err = readDescriptor(payload, index, int(pmt.ProgramInfoLength))
if err != nil {
return PMT{}, err
}
index += diff
}
// Stream Descriptor
for index < int(pmt.SectionLength) {
si := StreamInfo{}
si.Type = StreamType(payload[index]) // 8
si.Reserved1 = (payload[index+1] >> 5) & 0x07 // 3
si.ElementaryPID = PID(uint16(payload[index+1]&0x1f)<<8 | uint16(payload[index+2])) // 13
si.Reserved2 = (payload[index+3] >> 4) & 0x0f // 4
si.ESInfoLength = uint16(payload[index+3]&0x0f)<<8 | uint16(payload[index+4]) // 12
index += 5
// N2 loop
si.Descriptors, diff, err = readDescriptor(payload, index, int(si.ESInfoLength))
if err != nil {
return PMT{}, err
}
pmt.Streams = append(pmt.Streams, si)
index += diff
}
pmt.CRC32 = uint(payload[index])<<24 | uint(payload[index+1])<<16 | uint(payload[index+2])<<8 | uint(payload[index+3])
// fmt.Printf("crc: %08x\n", pmt.CRC32)
if disableCRCcheck {
return pmt, nil
}
crc := calculateCRC(payload[1:pmt.SectionLength])
// fmt.Printf("calculated crc: %08x\n", crc)
// fmt.Printf("raw bytes: %#v\n", payload[1:pmt.SectionLength])
if uint32(pmt.CRC32) != crc {
return PMT{}, fmt.Errorf("CRC32 mismatch")
}
return pmt, nil
}
func readDescriptor(payload []byte, startIndex, length int) ([]ProgramElementDescriptor, int, error) {
// Rec. ITU-T H.222.0 (06-2021) pp.76-156,p.261
diffSum := 0
peds := []ProgramElementDescriptor{}
// fmt.Printf("piLen:%d\n", length)
endIndex := startIndex + length
for index := startIndex; index < endIndex; {
// fmt.Printf("desc index:%d max:%d len:%d\n", index, (startIndex + length), endIndex)
ped := ProgramElementDescriptor{}
ped.Tag = payload[index]
ped.Length = payload[index+1]
diff := 2
switch {
case ped.Tag == 2: //video_stream_descriptor
ped.VideoStreamDescriptor.MultipleFrameRateFlag = ((payload[index+2] >> 7) & 0x01) == 1 // 1
ped.VideoStreamDescriptor.FrameRateCode = (payload[index+2] >> 3) & 0x0f // 4
ped.VideoStreamDescriptor.MPEG1OnlyFlag = ((payload[index+2] >> 2) & 0x01) == 1 // 1
ped.VideoStreamDescriptor.ConstrainedParameterFlag = ((payload[index+2] >> 1) & 0x01) == 1 // 1
ped.VideoStreamDescriptor.StillPictureFlag = ((payload[index+2]) & 0x01) == 1 // 1
diff += 1
if ped.MPEG1OnlyFlag {
ped.VideoStreamDescriptor.ProfileAndLevelIndication = payload[index+3] //8
ped.VideoStreamDescriptor.ChromaFormat = (payload[index+4] >> 6) & 0x03 // 2
ped.VideoStreamDescriptor.FrameRateExtensionFlag = ((payload[index+4] >> 5) & 0x01) == 1 // 1
ped.VideoStreamDescriptor.Reserved = (payload[index+4]) & 0x1f // 5
diff += 2
}
case ped.Tag == 3: //audio_stream_descriptor
fmt.Println("[WARN] not implemented", ped.Tag)
case ped.Tag == 4: //hierarchy_descriptor
fmt.Println("[WARN] not implemented", ped.Tag)
case ped.Tag == 5: //registration_descriptor
ped.RegistrationDescriptor.FormatIdentifier = payload[index+2 : index+6]
if ped.Length > 4 {
ped.RegistrationDescriptor.AdditionalIdentificationInfo = make([]byte, ped.Length-4)
copy(ped.RegistrationDescriptor.AdditionalIdentificationInfo, payload[index+6:index+6+int(ped.Length)-4])
}
diff += int(ped.Length)
case ped.Tag == 6: //data_stream_alignment_descriptor
fmt.Println("[WARN] not implemented", ped.Tag)
diff += int(ped.Length)
case ped.Tag == 7: //target_background_grid_descriptor
fmt.Println("[WARN] not implemented", ped.Tag)
diff += int(ped.Length)
case ped.Tag == 8: //Video_window_descriptor
fmt.Println("[WARN] not implemented", ped.Tag)
diff += int(ped.Length)
case ped.Tag == 9: //CA_descriptor
fmt.Println("[WARN] not implemented", ped.Tag, ped.Length)
diff += int(ped.Length)
case ped.Tag == 10: //ISO_639_language_descriptor
ped.ISO639LanguageDescriptor.Languages = make([]ISO639LanguageRelation, ped.Length/4)
for i := 0; i < int(ped.Length)/4; i++ {
ped.ISO639LanguageDescriptor.Languages[i] = ISO639LanguageRelation{
ISO639LanguageCode: int(payload[index+2+(i*4)])<<16 | int(payload[index+2+(i*4)+1])<<8 | int(payload[index+2+(i*4)+2]),
AudioType: payload[index+2+(i*4)+3],
}
}
diff += int(ped.Length)
case ped.Tag == 11: //System_clock_descriptor
fmt.Println("[WARN] not implemented", ped.Tag)
diff += int(ped.Length)
case ped.Tag == 12: //Multiplex_buffer_utilization_descriptor
fmt.Println("[WARN] not implemented", ped.Tag)
diff += int(ped.Length)
case ped.Tag == 13: //Copyright_descriptor
fmt.Println("[WARN] not implemented", ped.Tag)
diff += int(ped.Length)
case ped.Tag == 14: // Maximum_bitrate_descriptor
fmt.Println("[WARN] not implemented", ped.Tag)
diff += int(ped.Length)
case ped.Tag == 15: //Private_data_indicator_descriptor
fmt.Println("[WARN] not implemented", ped.Tag)
diff += int(ped.Length)
case ped.Tag == 16: //Smoothing_buffer_descriptor
fmt.Println("[WARN] not implemented", ped.Tag)
diff += int(ped.Length)
case ped.Tag == 1: // STD_descriptor
fmt.Println("[WARN] not implemented", ped.Tag)
diff += int(ped.Length)
case ped.Tag == 18: //IBP_descriptor
fmt.Println("[WARN] not implemented", ped.Tag)
diff += int(ped.Length)
case ped.Tag == 27: //MPEG-4_video_descriptor
ped.MPEG4VideoDescriptor.VisualProfileAndLevel = payload[index+2]
diff += 1
case ped.Tag == 28: //MPEG-4_audio_descriptor
ped.MPEG4AudioDescriptor.AudioProfileAndLevel = payload[index+2]
diff += 1
case ped.Tag == 29: //IOD_descriptor
fmt.Println("[WARN] not implemented", ped.Tag)
diff += int(ped.Length)
case ped.Tag == 30: // SL_descriptor
fmt.Println("[WARN] not implemented", ped.Tag)
diff += int(ped.Length)
case ped.Tag == 31: //FMC_descriptor
fmt.Println("[WARN] not implemented", ped.Tag)
diff += int(ped.Length)
case ped.Tag == 32: //External_ES_ID_descriptor
fmt.Println("[WARN] not implemented", ped.Tag)
diff += int(ped.Length)
case ped.Tag == 33: //MuxCode_descriptor
fmt.Println("[WARN] not implemented", ped.Tag)
diff += int(ped.Length)
case ped.Tag == 34: // FmxBufferSize_descriptor
fmt.Println("[WARN] not implemented", ped.Tag)
diff += int(ped.Length)
case ped.Tag == 35: // multiplexBuffer_descriptor
fmt.Println("[WARN] not implemented", ped.Tag)
diff += int(ped.Length)
case ped.Tag == 36: // content_labeling_descriptor
fmt.Println("[WARN] not implemented", ped.Tag)
diff += int(ped.Length)
case ped.Tag == 37: // metadata_pointer_descriptor
fmt.Println("[WARN] not implemented", ped.Tag)
diff += int(ped.Length)
case ped.Tag == 38: // metadata_descriptor
fmt.Println("[WARN] not implemented", ped.Tag)
diff += int(ped.Length)
case ped.Tag == 39: // metadata_STD_descriptor
fmt.Println("[WARN] not implemented", ped.Tag)
diff += int(ped.Length)
case ped.Tag == 40: // AVC video descriptor
ped.AVCVideoDescriptor.ProfileIDC = payload[index+2]
ped.AVCVideoDescriptor.ConstraintSet0Flag = ((payload[index+3] >> 7) & 0x01) == 1
ped.AVCVideoDescriptor.ConstraintSet1Flag = ((payload[index+3] >> 6) & 0x01) == 1
ped.AVCVideoDescriptor.ConstraintSet2Flag = ((payload[index+3] >> 5) & 0x01) == 1
ped.AVCVideoDescriptor.ConstraintSet3Flag = ((payload[index+3] >> 4) & 0x01) == 1
ped.AVCVideoDescriptor.ConstraintSet4Flag = ((payload[index+3] >> 3) & 0x01) == 1
ped.AVCVideoDescriptor.ConstraintSet5Flag = ((payload[index+3] >> 2) & 0x01) == 1
ped.AVCVideoDescriptor.AVCCompatibleFlags = (payload[index+3] & 0x03)
ped.AVCVideoDescriptor.LevelIDC = payload[index+4]
ped.AVCVideoDescriptor.AVCStillPresent = ((payload[index+5] >> 7) & 0x01) == 1
ped.AVCVideoDescriptor.AVC24HourPictureFlag = ((payload[index+5] >> 6) & 0x01) == 1
ped.AVCVideoDescriptor.FramePackingSEINotPresentFlag = ((payload[index+5] >> 5) & 0x01) == 1
ped.AVCVideoDescriptor.Reserved = (payload[index+5] & 0x1f)
diff += 4
case ped.Tag == 41: // IPMP_descriptor (defined in ISO/IEC 13818-11, MPEG-2 IPMP)
fmt.Println("[WARN] not implemented", ped.Tag)
diff += int(ped.Length)
case ped.Tag == 42: // AVC timing and HRD descriptor
fmt.Println("[WARN] not implemented", ped.Tag)
diff += int(ped.Length)
case ped.Tag == 43: // MPEG-2_AAC_audio_descriptor
fmt.Println("[WARN] not implemented", ped.Tag)
diff += int(ped.Length)
case ped.Tag == 44: // FlexMuxTiming_descriptor
fmt.Println("[WARN] not implemented", ped.Tag)
diff += int(ped.Length)
case ped.Tag == 45: // MPEG-4_text_descriptor
fmt.Println("[WARN] not implemented", ped.Tag)
diff += int(ped.Length)
case ped.Tag == 46: // MPEG-4_audio_extension_descriptor
fmt.Println("[WARN] not implemented", ped.Tag)
diff += int(ped.Length)
case ped.Tag == 47: // Auxiliary_video_stream_descriptor
fmt.Println("[WARN] not implemented", ped.Tag)
diff += int(ped.Length)
case ped.Tag == 48: // SVC extension descriptor
fmt.Println("[WARN] not implemented", ped.Tag)
diff += int(ped.Length)
case ped.Tag == 49: // MVC extension descriptor
fmt.Println("[WARN] not implemented", ped.Tag)
diff += int(ped.Length)
case ped.Tag == 50: // J2K video descriptor
fmt.Println("[WARN] not implemented", ped.Tag)
diff += int(ped.Length)
case ped.Tag == 51: // MVC operation point descriptor
fmt.Println("[WARN] not implemented", ped.Tag)
diff += int(ped.Length)
case ped.Tag == 52: // MPEG2_stereoscopic_video_format_descriptor
fmt.Println("[WARN] not implemented", ped.Tag)
diff += int(ped.Length)
case ped.Tag == 53: // Stereoscopic_program_info_descriptor
fmt.Println("[WARN] not implemented", ped.Tag)
diff += int(ped.Length)
case ped.Tag == 54: // Stereoscopic_video_info_descriptor
fmt.Println("[WARN] not implemented", ped.Tag)
diff += int(ped.Length)
case ped.Tag == 55: // Transport_profile_descriptor
fmt.Println("[WARN] not implemented", ped.Tag)
diff += int(ped.Length)
case ped.Tag == 56: // HEVC video descriptor
fmt.Println("[WARN] not implemented", ped.Tag)
diff += int(ped.Length)
case ped.Tag == 57: // VVC video descriptor
fmt.Println("[WARN] not implemented", ped.Tag)
diff += int(ped.Length)
case ped.Tag == 58: // EVC video descriptor
fmt.Println("[WARN] not implemented", ped.Tag)
diff += int(ped.Length)
case ped.Tag == 0:
fmt.Println("[WARN] descriptor_tag value(0) is reserved")
diff += int(ped.Length)
case ped.Tag == 1: // forbidden
return nil, 0, fmt.Errorf("descriptor_tag value(1) is forbidden")
case ped.Tag >= 19 && ped.Tag <= 26: // Defined in ISO/IEC 13818-6
fmt.Println("[WARN] not implemented", ped.Tag)
diff += int(ped.Length)
case ped.Tag >= 59 && ped.Tag <= 62: // ITU-T Rec. H.222.0 | ISO/IEC 13818-1 Reserved
return nil, 0, fmt.Errorf("descriptor_tag value(%d) is reserved", ped.Tag)
case ped.Tag == 63: // Extension_descriptor
fmt.Println("[WARN] not implemented", ped.Tag)
case ped.Tag >= 64 && ped.Tag <= 255: // User Private
fmt.Printf("[WARN] user-private descriptor %02X %dbytes\n", ped.Tag, ped.Length)
ped.UserPrivateDescriptor.Data = payload[index+2 : int(ped.Length)+index+2]
diff += int(ped.Length)
}
// fmt.Printf("ped dump %#v\r\n", ped)
index += diff
diffSum += diff
peds = append(peds, ped)
}
return peds, diffSum, nil
}