streaming

Media streaming and broadcast systems in Go
Log | Files | Refs | README | LICENSE

commit 428cba521cef3f708f964286f6f6a7b8e08f91c3
parent 1fbc9b17002d187c9cbeceaf8f63ac8226fdc52d
Author: Oliver Lowe <o@olowe.co>
Date:   Fri, 10 May 2024 16:14:14 +1000

internal/scte35: correct slice indices

Nothing much to say; we had this wrong according to spec!

Diffstat:
Minternal/scte35/splice_descriptor.go | 46++++++++++++++++++++++++++--------------------
Minternal/scte35/splice_info.go | 4++--
2 files changed, 28 insertions(+), 22 deletions(-)

diff --git a/internal/scte35/splice_descriptor.go b/internal/scte35/splice_descriptor.go @@ -85,13 +85,13 @@ func (d DTMFDescriptor) Data() []byte { type DeliveryRestrictions uint8 const ( - WebDeliveryAllowed DeliveryRestrictions = 1<<4 + iota + WebDeliveryAllowed DeliveryRestrictions = 1<<4 - iota NoRegionalBlackout ArchiveAllowed DeviceRestrictGroup0 = 0x00 - DeviceRestrictGroup1 = 0x40 - DeviceRestrictGroup2 = 0x80 - DeviceRestrictionsNone = 0xc0 + DeviceRestrictGroup1 = 0x01 + DeviceRestrictGroup2 = 0x02 + DeviceRestrictionsNone = 0x03 ) // SegmentationDescriptor represents the segmentation_descriptor @@ -165,11 +165,11 @@ func (d SegmentationDescriptor) Data() []byte { func unmarshalSegDescriptor(buf []byte) SegmentationDescriptor { var desc SegmentationDescriptor - desc.EventID = binary.BigEndian.Uint32(buf[:5]) - if buf[1]&0b10000000 > 0 { + desc.EventID = binary.BigEndian.Uint32(buf[:4]) + if buf[4]&0b10000000 > 0 { desc.Cancel = true } - if buf[1]&0b01000000 > 0 { + if buf[4]&0b01000000 > 0 { desc.EventIDCompliance = true } // next 6 bits are reserved @@ -178,14 +178,18 @@ func unmarshalSegDescriptor(buf []byte) SegmentationDescriptor { // we don't support the deprecated component mode. if !desc.Cancel { - desc.Restrictions = DeliveryRestrictions(buf[5] & 0b00111111) // remaining 6 bits + // left-most 2 bits are flags for later. + desc.Restrictions = DeliveryRestrictions(buf[5] & 0b00111111) + // is segmentation duration flag set? if buf[5]&0b01000000 > 0 { - b := buf[5:10] // get 40-bit integer - b = append(b, 0x00, 0x00, 0x00) + b := make([]byte, 3) + b = append(b, buf[6:11]...) + // b := buf[6:11] // get 40-bit integer + // b = append(b, 0x00, 0x00, 0x00) dur := binary.BigEndian.Uint64(b) desc.Duration = &dur - buf = buf[10:] + buf = buf[11:] } else { buf = buf[6:] } @@ -204,8 +208,10 @@ func unmarshalSegDescriptor(buf []byte) SegmentationDescriptor { switch desc.Type { // TODO(otl): use named constants from section 10.3.3.1 Table 23 - segmentation_type_id case 0x34, 0x30, 0x32, 0x36, 0x38, 0x3a, 0x44, 0x46: - desc.SubNumber = uint8(buf[3]) - desc.SubExpected = uint8(buf[4]) + if desc.Expected > 0 { + desc.SubNumber = uint8(buf[3]) + desc.SubExpected = uint8(buf[4]) + } } } @@ -309,17 +315,17 @@ func (d AudioDescriptor) Data() []byte { func DecodeAllDescriptors(buf []byte) ([]SpliceDescriptor, error) { var sds []SpliceDescriptor for len(buf) >= 6 { - desc, err := UnmarshalSpliceDescriptor(buf) + // first byte is tag, second is length of next descriptor. + dlen := uint8(buf[1]) + desc, err := UnmarshalSpliceDescriptor(buf[:2+dlen]) 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) { + if int(dlen) >= len(buf) { break } - buf = buf[dlen:] + buf = buf[2+dlen:] fmt.Println("bytes left in decode loop:", len(buf)) } return sds, nil @@ -332,8 +338,8 @@ func UnmarshalSpliceDescriptor(buf []byte) (SpliceDescriptor, error) { } tag := uint8(buf[0]) length := uint8(buf[1]) - if len(buf[2:]) < int(length) { - return nil, fmt.Errorf("short slice: want %d bytes, have %d", length, len(buf)) + if len(buf[2:]) != int(length) { + return nil, fmt.Errorf("need %d bytes, have %d", int(length), len(buf[2:])) } buf = buf[2 : 2+length] id := binary.BigEndian.Uint32(buf[:4]) diff --git a/internal/scte35/splice_info.go b/internal/scte35/splice_info.go @@ -185,13 +185,13 @@ func decodeSpliceInfo(buf []byte) (*SpliceInfo, error) { buf = buf[10+cmdlen+1:] desclen := binary.BigEndian.Uint16([]byte{buf[0], buf[1]}) - descriptors, err := DecodeAllDescriptors(buf[2 : 2+desclen+1]) + descriptors, err := DecodeAllDescriptors(buf[2 : 2+desclen]) if err != nil { return nil, fmt.Errorf("decode splice descriptors: %w", err) } info.Descriptors = descriptors - buf = buf[2+desclen+1:] + buf = buf[2+desclen:] if info.Encrypted { // TODO(otl): handle alignment_stuffing for encrypted packets. // skip past E_CRC_32; we don't store it.