Skip to content

Commit

Permalink
Correct EBP group ID parsing to read 7-bit ID field
Browse files Browse the repository at this point in the history
Code would previously include the extension flag bit in the group ID, causing literal group ID comparisons to incorrectly fail.

Also correct ebp.StreamSyncSignal() to search all available group IDs and not only the second.
  • Loading branch information
morrowa committed Aug 15, 2022
1 parent 4c4c4eb commit 62fa5de
Show file tree
Hide file tree
Showing 6 changed files with 130 additions and 24 deletions.
8 changes: 4 additions & 4 deletions ebp/baseebp.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,10 +146,10 @@ func (ebp *baseEbp) SetIsEmpty(value bool) {
// but Stream Sync and SCTE-35 were the only two ever to get implemented. MK was the only Transcoder to implement SCTE-35 within the
// Grouping ID section and we never leveraged that data on any downstream devices.
func (ebp *baseEbp) StreamSyncSignal() uint8 {
// The first byte is Grouping ID, the second byte is the sync signal
if len(ebp.Grouping) == 2 && ebp.Grouping[0] == 0x80 {
return ebp.Grouping[1]
for _, groupID := range ebp.Grouping {
if groupID == StreamSynchronized || groupID == StreamNotSynchronized {
return groupID
}
}

return InvalidStreamSyncSignal
}
21 changes: 14 additions & 7 deletions ebp/cablelabsebp.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,12 +122,15 @@ func readCableLabsEbp(data []byte) (ebp *cableLabsEbp, err error) {

if ebp.GroupingFlag() {
var group byte
group = data[index]
var groupExtFlag bool
groupExtFlag = data[index]&0x80 != 0
group = data[index] & 0x7F
ebp.Grouping = append(ebp.Grouping, group)
index += uint8(1)

for group&0x80 != 0 {
group = data[index]
for groupExtFlag {
groupExtFlag = data[index]&0x80 != 0
group = data[index] & 0x7F
ebp.Grouping = append(ebp.Grouping, group)
index += uint8(1)
}
Expand Down Expand Up @@ -182,11 +185,15 @@ func (ebp *cableLabsEbp) Data() []byte {

if ebp.GroupingFlag() {
for i := range ebp.Grouping {
ebp.Grouping[i] |= 0x80 // set flag because this is not the last ID
if i == len(ebp.Grouping)-1 {
ebp.Grouping[i] &= 0x7F // last index does not have this flag set
var group byte
if i < len(ebp.Grouping)-1 {
// add the ext flag for all but the last group
group = ebp.Grouping[i] | 0x80
} else {
// last group - no ext flag
group = ebp.Grouping[i]
}
binary.Write(data, ebpEncoding, ebp.Grouping[i])
binary.Write(data, ebpEncoding, group)
}
}

Expand Down
48 changes: 47 additions & 1 deletion ebp/cablelabsebp_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
MIT License
Copyright 2016 Comcast Cable Communications Management, LLC
# Copyright 2016 Comcast Cable Communications Management, LLC
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down Expand Up @@ -110,3 +110,49 @@ func TestCableLabsEBP(t *testing.T) {
)
}
}

func TestParseCableLabsEBPWithMultipleGroups(t *testing.T) {
var ebpBytes = []byte{0xdf, 0x11, 0x45, 0x42, 0x50, 0x30, 0x98, 0x80, 0xa3, 0xfe, 0x1d, 0xe6, 0xa1, 0x45, 0x18, 0xb8, 0x51, 0x00, 0x00}
ebp, err := readCableLabsEbp(ebpBytes)
if err != nil {
t.Logf("failed to parse CableLabs-style EBP: #{err}")
t.FailNow()
}
if ebp.StreamSyncSignal() != StreamSynchronized {
t.Errorf("Wrong stream sync signal (expected 0x1D, got #{ebp.StreamSyncSignal()})")
}
var expectedGroups = []uint8{0x00, 0x23, 0x7E, 0x1D}
if len(ebp.Grouping) != len(expectedGroups) {
t.Logf("Wrong number of group IDs (expected #{len(expectedGroups)}, got #{len(ebp.Grouping)}")
t.FailNow()
}
for i, gid := range expectedGroups {
other := ebp.Grouping[i]
if gid != other {
t.Errorf("Wrong group ID (expected #{gid}, got #{other})")
}
}
}

func TestParseCableLabsEBPWithSyncInMiddle(t *testing.T) {
var ebpBytes = []byte{0xdf, 0x12, 0x45, 0x42, 0x50, 0x30, 0x98, 0x80, 0xa3, 0xfe, 0x9d, 0x05, 0xe6, 0xa1, 0x45, 0x18, 0xb8, 0x51, 0x00, 0x00}
ebp, err := readCableLabsEbp(ebpBytes)
if err != nil {
t.Logf("failed to parse CableLabs-style EBP: #{err}")
t.FailNow()
}
if ebp.StreamSyncSignal() != StreamSynchronized {
t.Errorf("Wrong stream sync signal (expected 0x1D, got #{ebp.StreamSyncSignal()})")
}
var expectedGroups = []uint8{0x00, 0x23, 0x7E, 0x1D, 0x05}
if len(ebp.Grouping) != len(expectedGroups) {
t.Logf("Wrong number of group IDs (expected #{len(expectedGroups)}, got #{len(ebp.Grouping)}")
t.FailNow()
}
for i, gid := range expectedGroups {
other := ebp.Grouping[i]
if gid != other {
t.Errorf("Wrong group ID (expected #{gid}, got #{other})")
}
}
}
8 changes: 4 additions & 4 deletions v2/ebp/baseebp.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,10 +146,10 @@ func (ebp *baseEbp) SetIsEmpty(value bool) {
// but Stream Sync and SCTE-35 were the only two ever to get implemented. MK was the only Transcoder to implement SCTE-35 within the
// Grouping ID section and we never leveraged that data on any downstream devices.
func (ebp *baseEbp) StreamSyncSignal() uint8 {
// The first byte is Grouping ID, the second byte is the sync signal
if len(ebp.Grouping) == 2 && ebp.Grouping[0] == 0x80 {
return ebp.Grouping[1]
for _, groupID := range ebp.Grouping {
if groupID == StreamSynchronized || groupID == StreamNotSynchronized {
return groupID
}
}

return InvalidStreamSyncSignal
}
21 changes: 14 additions & 7 deletions v2/ebp/cablelabsebp.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,12 +122,15 @@ func readCableLabsEbp(data []byte) (ebp *cableLabsEbp, err error) {

if ebp.GroupingFlag() {
var group byte
group = data[index]
var groupExtFlag bool
groupExtFlag = data[index]&0x80 != 0
group = data[index] & 0x7F
ebp.Grouping = append(ebp.Grouping, group)
index += uint8(1)

for group&0x80 != 0 {
group = data[index]
for groupExtFlag {
groupExtFlag = data[index]&0x80 != 0
group = data[index] & 0x7F
ebp.Grouping = append(ebp.Grouping, group)
index += uint8(1)
}
Expand Down Expand Up @@ -182,11 +185,15 @@ func (ebp *cableLabsEbp) Data() []byte {

if ebp.GroupingFlag() {
for i := range ebp.Grouping {
ebp.Grouping[i] |= 0x80 // set flag because this is not the last ID
if i == len(ebp.Grouping)-1 {
ebp.Grouping[i] &= 0x7F // last index does not have this flag set
var group byte
if i < len(ebp.Grouping)-1 {
// add the ext flag for all but the last group
group = ebp.Grouping[i] | 0x80
} else {
// last group - no ext flag
group = ebp.Grouping[i]
}
binary.Write(data, ebpEncoding, ebp.Grouping[i])
binary.Write(data, ebpEncoding, group)
}
}

Expand Down
48 changes: 47 additions & 1 deletion v2/ebp/cablelabsebp_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
MIT License
Copyright 2016 Comcast Cable Communications Management, LLC
# Copyright 2016 Comcast Cable Communications Management, LLC
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down Expand Up @@ -110,3 +110,49 @@ func TestCableLabsEBP(t *testing.T) {
)
}
}

func TestParseCableLabsEBPWithMultipleGroups(t *testing.T) {
var ebpBytes = []byte{0xdf, 0x11, 0x45, 0x42, 0x50, 0x30, 0x98, 0x80, 0xa3, 0xfe, 0x1d, 0xe6, 0xa1, 0x45, 0x18, 0xb8, 0x51, 0x00, 0x00}
ebp, err := readCableLabsEbp(ebpBytes)
if err != nil {
t.Logf("failed to parse CableLabs-style EBP: #{err}")
t.FailNow()
}
if ebp.StreamSyncSignal() != StreamSynchronized {
t.Errorf("Wrong stream sync signal (expected 0x1D, got #{ebp.StreamSyncSignal()})")
}
var expectedGroups = []uint8{0x00, 0x23, 0x7E, 0x1D}
if len(ebp.Grouping) != len(expectedGroups) {
t.Logf("Wrong number of group IDs (expected #{len(expectedGroups)}, got #{len(ebp.Grouping)}")
t.FailNow()
}
for i, gid := range expectedGroups {
other := ebp.Grouping[i]
if gid != other {
t.Errorf("Wrong group ID (expected #{gid}, got #{other})")
}
}
}

func TestParseCableLabsEBPWithSyncInMiddle(t *testing.T) {
var ebpBytes = []byte{0xdf, 0x12, 0x45, 0x42, 0x50, 0x30, 0x98, 0x80, 0xa3, 0xfe, 0x9d, 0x05, 0xe6, 0xa1, 0x45, 0x18, 0xb8, 0x51, 0x00, 0x00}
ebp, err := readCableLabsEbp(ebpBytes)
if err != nil {
t.Logf("failed to parse CableLabs-style EBP: #{err}")
t.FailNow()
}
if ebp.StreamSyncSignal() != StreamSynchronized {
t.Errorf("Wrong stream sync signal (expected 0x1D, got #{ebp.StreamSyncSignal()})")
}
var expectedGroups = []uint8{0x00, 0x23, 0x7E, 0x1D, 0x05}
if len(ebp.Grouping) != len(expectedGroups) {
t.Logf("Wrong number of group IDs (expected #{len(expectedGroups)}, got #{len(ebp.Grouping)}")
t.FailNow()
}
for i, gid := range expectedGroups {
other := ebp.Grouping[i]
if gid != other {
t.Errorf("Wrong group ID (expected #{gid}, got #{other})")
}
}
}

0 comments on commit 62fa5de

Please sign in to comment.