Skip to content

Commit 9094259

Browse files
julijaneblahspam
andauthored
feat: SpliceInfoSection: add methods TimeSpecifiedFlag, SpliceTimePTS (#86)
This adds two methods to SpliceInfoSection. TimeSpecifiedFlag returns true if the splice command is either SpliceInsert or TimeSignal and a splice time (PTSTime) is specified. SpliceTimePTS returns the splice time PTS, adjusted by PTSAdjustment. If no time is specified, 0 is returned. Co-authored-by: Jeff Bailey <[email protected]>
1 parent be81d52 commit 9094259

File tree

2 files changed

+197
-0
lines changed

2 files changed

+197
-0
lines changed

pkg/scte35/splice_info_section.go

+37
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ const (
4444
SAPType3 = uint32(0x2)
4545
// SAPTypeNotSpecified indicates the type of SAP, if any, is not signaled.
4646
SAPTypeNotSpecified = uint32(0x3)
47+
48+
// MaxPTS is the maximum value for a 33-bit PTS value.
49+
MaxPTS = 1<<33 - 1
4750
)
4851

4952
// SpliceInfoSection shall be carried in transport packets whereby only one
@@ -210,6 +213,40 @@ func (sis *SpliceInfoSection) Durations() []Duration {
210213
return durations
211214
}
212215

216+
// TimeSpecifiedFlag returns true if the SpliceInfoSection contains a splice
217+
// command for a splice event for which the splice time is specified.
218+
func (sis *SpliceInfoSection) TimeSpecifiedFlag() bool {
219+
switch sc := sis.SpliceCommand.(type) {
220+
case *SpliceInsert:
221+
return sc.TimeSpecifiedFlag()
222+
case *TimeSignal:
223+
return sc.SpliceTime.TimeSpecifiedFlag()
224+
default:
225+
return false
226+
}
227+
}
228+
229+
// SpliceTimePTS returns the final PTS time of the splice event, i.e. the
230+
// splice time of the command adjusted by the PTS adjustment. If the splice
231+
// command does not have a splice even for which splice time is specified,
232+
// this method returns 0.
233+
func (sis *SpliceInfoSection) SpliceTimePTS() uint64 {
234+
switch sc := sis.SpliceCommand.(type) {
235+
case *SpliceInsert:
236+
if !sc.TimeSpecifiedFlag() {
237+
return 0
238+
}
239+
return (*sc.Program.SpliceTime.PTSTime + sis.PTSAdjustment) & MaxPTS
240+
case *TimeSignal:
241+
if !sc.SpliceTime.TimeSpecifiedFlag() {
242+
return 0
243+
}
244+
return (*sc.SpliceTime.PTSTime + sis.PTSAdjustment) & MaxPTS
245+
default:
246+
return 0
247+
}
248+
}
249+
213250
// Encode returns the binary representation of this SpliceInfoSection as a
214251
// byte array.
215252
func (sis *SpliceInfoSection) Encode() ([]byte, error) {

pkg/scte35/splice_info_section_test.go

+160
Original file line numberDiff line numberDiff line change
@@ -391,3 +391,163 @@ func TestDurations(t *testing.T) {
391391
})
392392
}
393393
}
394+
395+
func Test_TimeSpecifiedFlag(t *testing.T) {
396+
cases := map[string]struct {
397+
sis scte35.SpliceInfoSection
398+
expected bool
399+
}{
400+
"SpliceInsert": {
401+
sis: scte35.SpliceInfoSection{
402+
SpliceCommand: &scte35.SpliceInsert{
403+
Program: &scte35.SpliceInsertProgram{
404+
SpliceTime: scte35.SpliceTime{
405+
PTSTime: ptr(uint64(90000)),
406+
},
407+
},
408+
},
409+
},
410+
expected: true,
411+
},
412+
"SpliceInsertNoProgramSplice": {
413+
sis: scte35.SpliceInfoSection{
414+
SpliceCommand: &scte35.SpliceInsert{},
415+
},
416+
expected: false,
417+
},
418+
"SpliceInsertNoSpliceTime": {
419+
sis: scte35.SpliceInfoSection{
420+
SpliceCommand: &scte35.SpliceInsert{
421+
Program: &scte35.SpliceInsertProgram{},
422+
},
423+
},
424+
expected: false,
425+
},
426+
"TimeSignal": {
427+
sis: scte35.SpliceInfoSection{
428+
SpliceCommand: &scte35.TimeSignal{
429+
SpliceTime: scte35.SpliceTime{PTSTime: ptr(uint64(90000))},
430+
},
431+
},
432+
expected: true,
433+
},
434+
"TimeSignalNoSpliceTime": {
435+
sis: scte35.SpliceInfoSection{
436+
SpliceCommand: &scte35.TimeSignal{
437+
SpliceTime: scte35.SpliceTime{},
438+
},
439+
},
440+
expected: false,
441+
},
442+
}
443+
444+
for k, c := range cases {
445+
t.Run(k, func(t *testing.T) {
446+
require.Equal(t, c.expected, c.sis.TimeSpecifiedFlag())
447+
})
448+
}
449+
}
450+
451+
func Test_SpliceTimePTS(t *testing.T) {
452+
cases := map[string]struct {
453+
sis scte35.SpliceInfoSection
454+
expected uint64
455+
}{
456+
"SpliceInsert": {
457+
sis: scte35.SpliceInfoSection{
458+
SpliceCommand: &scte35.SpliceInsert{
459+
Program: &scte35.SpliceInsertProgram{
460+
SpliceTime: scte35.SpliceTime{
461+
PTSTime: ptr(uint64(90000)),
462+
},
463+
},
464+
},
465+
},
466+
expected: 90000,
467+
},
468+
"SpliceInsertPtsAdjustment": {
469+
sis: scte35.SpliceInfoSection{
470+
SpliceCommand: &scte35.SpliceInsert{
471+
Program: &scte35.SpliceInsertProgram{
472+
SpliceTime: scte35.SpliceTime{
473+
PTSTime: ptr(uint64(90000)),
474+
},
475+
},
476+
},
477+
PTSAdjustment: 90000,
478+
},
479+
expected: 180000,
480+
},
481+
"SpliceInsertPtsAdjustmentWrapping": {
482+
sis: scte35.SpliceInfoSection{
483+
SpliceCommand: &scte35.SpliceInsert{
484+
Program: &scte35.SpliceInsertProgram{
485+
SpliceTime: scte35.SpliceTime{
486+
PTSTime: ptr(uint64(8589844592)),
487+
},
488+
},
489+
},
490+
PTSAdjustment: 180000,
491+
},
492+
expected: 90000,
493+
},
494+
"SpliceInsertNoProgramSplice": {
495+
sis: scte35.SpliceInfoSection{
496+
SpliceCommand: &scte35.SpliceInsert{},
497+
},
498+
expected: 0,
499+
},
500+
"SpliceInsertNoSpliceTime": {
501+
sis: scte35.SpliceInfoSection{
502+
SpliceCommand: &scte35.SpliceInsert{
503+
Program: &scte35.SpliceInsertProgram{},
504+
},
505+
},
506+
expected: 0,
507+
},
508+
"TimeSignal": {
509+
sis: scte35.SpliceInfoSection{
510+
SpliceCommand: &scte35.TimeSignal{
511+
SpliceTime: scte35.SpliceTime{PTSTime: ptr(uint64(90000))},
512+
},
513+
},
514+
expected: 90000,
515+
},
516+
"TimeSingalPtsAdjustment": {
517+
sis: scte35.SpliceInfoSection{
518+
SpliceCommand: &scte35.TimeSignal{
519+
SpliceTime: scte35.SpliceTime{
520+
PTSTime: ptr(uint64(90000)),
521+
},
522+
},
523+
PTSAdjustment: 90000,
524+
},
525+
expected: 180000,
526+
},
527+
"TimeSignalPtsAdjustmentWrapping": {
528+
sis: scte35.SpliceInfoSection{
529+
SpliceCommand: &scte35.TimeSignal{
530+
SpliceTime: scte35.SpliceTime{
531+
PTSTime: ptr(uint64(8589844592)),
532+
},
533+
},
534+
PTSAdjustment: 180000,
535+
},
536+
expected: 90000,
537+
},
538+
"TimeSignalNoSpliceTime": {
539+
sis: scte35.SpliceInfoSection{
540+
SpliceCommand: &scte35.TimeSignal{
541+
SpliceTime: scte35.SpliceTime{},
542+
},
543+
},
544+
expected: 0,
545+
},
546+
}
547+
548+
for k, c := range cases {
549+
t.Run(k, func(t *testing.T) {
550+
require.Equal(t, c.expected, c.sis.SpliceTimePTS())
551+
})
552+
}
553+
}

0 commit comments

Comments
 (0)