commit 9c432babde8714bfa10488cf39bbabb0e476d3b5
parent 47d1cec1ab17a35dffdab92234fa96b52131e105
Author: Oliver Lowe <o@olowe.co>
Date: Wed, 8 May 2024 16:43:26 +1000
internal/scte35: implement decoding of splice info descriptors
Only a generic SpliceDescriptor. Decoding of specific descriptors will
come later.
Diffstat:
2 files changed, 39 insertions(+), 8 deletions(-)
diff --git a/internal/scte35/splice_descriptor.go b/internal/scte35/splice_descriptor.go
@@ -146,15 +146,38 @@ type AudioChannel struct {
FullService bool
}
+func DecodeAllDescriptors(buf []byte) ([]SpliceDescriptor, error) {
+ var sds []SpliceDescriptor
+ for len(buf) > 0 {
+ desc, err := UnmarshalSpliceDescriptor(buf)
+ if err != nil {
+ return sds, err
+ }
+ sds = append(sds, *desc)
+ // desc.Tag + desclength + desc.ID + data
+ dlen := 1 + 1 + 4 + len(desc.Data)
+ if dlen >= len(buf) {
+ break
+ }
+ buf = buf[dlen:]
+ fmt.Println("bytes left in decode loop:", len(buf))
+ }
+ return sds, nil
+}
+
func UnmarshalSpliceDescriptor(buf []byte) (*SpliceDescriptor, error) {
- if len(buf) < 5 {
+ if len(buf) < 6 {
return nil, fmt.Errorf("need at least 5 bytes")
}
- return &SpliceDescriptor{
- Tag: uint8(buf[0]),
- ID: binary.LittleEndian.Uint32(buf[1:4]),
- Data: buf[5:],
- }, nil
+ d := &SpliceDescriptor{
+ Tag: uint8(buf[0]),
+ ID: binary.LittleEndian.Uint32(buf[2:6]),
+ }
+ length := uint8(buf[1])
+ if uint8(buf[1]) > 0 {
+ d.Data = buf[6 : 6+length]
+ }
+ return d, nil
}
func encodeSegDescriptor(sd *SegmentationDescriptor) []byte {
diff --git a/internal/scte35/splice_info.go b/internal/scte35/splice_info.go
@@ -182,7 +182,7 @@ func decodeSpliceInfo(buf []byte) (*SpliceInfo, error) {
cmdbuf := buf[11 : 11+cmdlength]
switch cmd.Type {
case SpliceNull, BandwidthReservation:
- //
+ // nothing to decode
case TimeSignal:
// check if time specified flag is set.
if cmdbuf[0]&0x80 == 1<<7 {
@@ -196,8 +196,16 @@ func decodeSpliceInfo(buf []byte) (*SpliceInfo, error) {
cmd.TimeSignal = &t
}
default:
- return nil, fmt.Errorf("cannot decode command %s", cmd.Type)
+ return nil, fmt.Errorf("cannot decode command type %s", cmd.Type)
}
info.Command = &cmd
+ buf = buf[11+cmdlength:]
+
+ desclen := binary.BigEndian.Uint16([]byte{buf[0], buf[1]})
+ descriptors, err := DecodeAllDescriptors(buf[2 : 2+desclen])
+ if err != nil {
+ return nil, fmt.Errorf("decode splice descriptors: %w", err)
+ }
+ info.Descriptors = descriptors
return &info, nil
}