Skip to content

Commit

Permalink
Added local time offset descriptor
Browse files Browse the repository at this point in the history
  • Loading branch information
asticode committed Nov 25, 2017
1 parent 71d651c commit beda8c6
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 24 deletions.
2 changes: 1 addition & 1 deletion data_eit.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func parseEITSection(i []byte, offset *int, offsetSectionsEnd int, tableIDExtens
e.StartTime = parseDVBTime(i, offset)

// Duration
e.Duration = parseDVBDuration(i, offset)
e.Duration = parseDVBDurationSeconds(i, offset)

// Running status
e.RunningStatus = uint8(i[*offset]) >> 5
Expand Down
22 changes: 11 additions & 11 deletions data_eit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
var eit = &EITData{
Events: []*EITDataEvent{{
Descriptors: descriptors,
Duration: dvbDuration,
Duration: dvbDurationSeconds,
EventID: 6,
HasFreeCSAMode: true,
RunningStatus: 7,
Expand All @@ -25,16 +25,16 @@ var eit = &EITData{

func eitBytes() []byte {
w := astibinary.New()
w.Write(uint16(2)) // Transport stream ID
w.Write(uint16(3)) // Original network ID
w.Write(uint8(4)) // Segment last section number
w.Write(uint8(5)) // Last table id
w.Write(uint16(6)) // Event #1 id
w.Write(dvbTimeBytes) // Event #1 start time
w.Write(dvbDurationBytes) // Event #1 duration
w.Write("111") // Event #1 running status
w.Write("1") // Event #1 free CA mode
descriptorsBytes(w) // Event #1 descriptors
w.Write(uint16(2)) // Transport stream ID
w.Write(uint16(3)) // Original network ID
w.Write(uint8(4)) // Segment last section number
w.Write(uint8(5)) // Last table id
w.Write(uint16(6)) // Event #1 id
w.Write(dvbTimeBytes) // Event #1 start time
w.Write(dvbDurationSecondsBytes) // Event #1 duration
w.Write("111") // Event #1 running status
w.Write("1") // Event #1 free CA mode
descriptorsBytes(w) // Event #1 descriptors
return w.Bytes()
}

Expand Down
60 changes: 59 additions & 1 deletion descriptor.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package astits

import (
"time"

"github.com/asticode/go-astilog"
)

Expand All @@ -22,6 +24,7 @@ const (
DescriptorTagExtendedEvent = 0x4e
DescriptorTagExtension = 0x7f
DescriptorTagISO639LanguageAndAudioType = 0xa
DescriptorTagLocalTimeOffset = 0x58
DescriptorTagMaximumBitrate = 0xe
DescriptorTagNetworkName = 0x40
DescriptorTagParentalRating = 0x55
Expand Down Expand Up @@ -65,6 +68,7 @@ type Descriptor struct {
Extension *DescriptorExtension
ISO639LanguageAndAudioType *DescriptorISO639LanguageAndAudioType
Length uint8
LocalTimeOffset *DescriptorLocalTimeOffset
MaximumBitrate *DescriptorMaximumBitrate
NetworkName *DescriptorNetworkName
ParentalRating *DescriptorParentalRating
Expand Down Expand Up @@ -421,6 +425,56 @@ func newDescriptorISO639LanguageAndAudioType(i []byte) *DescriptorISO639Language
}
}

// DescriptorLocalTimeOffset represents a local time offset descriptor
// Page: 84 | Link: https://www.dvb.org/resources/public/standards/a38_dvb-si_specification.pdf
type DescriptorLocalTimeOffset struct {
Items []*DescriptorLocalTimeOffsetItem
}

// DescriptorLocalTimeOffsetItem represents a local time offset item descriptor
type DescriptorLocalTimeOffsetItem struct {
CountryCode []byte
CountryRegionID uint8
LocalTimeOffset time.Duration
LocalTimeOffsetPolarity bool
NextTimeOffset time.Duration
TimeOfChange time.Time
}

func newDescriptorLocalTimeOffset(i []byte) (d *DescriptorLocalTimeOffset) {
// Init
d = &DescriptorLocalTimeOffset{}
var offset int

// Add items
for offset < len(i) {
// Init
var itm = &DescriptorLocalTimeOffsetItem{}
d.Items = append(d.Items, itm)

// Country code
itm.CountryCode = i[offset : offset+3]
offset += 3

// Country region ID
itm.CountryRegionID = uint8(i[offset] >> 2)

// Local time offset polarity
itm.LocalTimeOffsetPolarity = i[offset]&0x1 > 0
offset += 1

// Local time offset
itm.LocalTimeOffset = parseDVBDurationMinutes(i, &offset)

// Time of change
itm.TimeOfChange = parseDVBTime(i, &offset)

// Next time offset
itm.NextTimeOffset = parseDVBDurationMinutes(i, &offset)
}
return
}

// DescriptorMaximumBitrate represents a maximum bitrate descriptor
type DescriptorMaximumBitrate struct {
Bitrate uint32 // In bytes/second
Expand All @@ -432,7 +486,9 @@ func newDescriptorMaximumBitrate(i []byte) *DescriptorMaximumBitrate {

// DescriptorNetworkName represents a network name descriptor
// Page: 93 | Chapter: 6.2.27 | Link: https://www.dvb.org/resources/public/standards/a38_dvb-si_specification.pdf
type DescriptorNetworkName struct{ Name []byte }
type DescriptorNetworkName struct {
Name []byte
}

func newDescriptorNetworkName(i []byte) *DescriptorNetworkName {
return &DescriptorNetworkName{Name: i}
Expand Down Expand Up @@ -627,6 +683,8 @@ func parseDescriptors(i []byte, offset *int) (o []*Descriptor) {
d.Extension = newDescriptorExtension(b)
case DescriptorTagISO639LanguageAndAudioType:
d.ISO639LanguageAndAudioType = newDescriptorISO639LanguageAndAudioType(b)
case DescriptorTagLocalTimeOffset:
d.LocalTimeOffset = newDescriptorLocalTimeOffset(b)
case DescriptorTagMaximumBitrate:
d.MaximumBitrate = newDescriptorMaximumBitrate(b)
case DescriptorTagNetworkName:
Expand Down
20 changes: 19 additions & 1 deletion descriptor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func descriptorsBytes(w *astibinary.Writer) {
func TestParseDescriptor(t *testing.T) {
// Init
w := astibinary.New()
w.Write(uint16(177)) // Descriptors length
w.Write(uint16(193)) // Descriptors length
// AC3
w.Write(uint8(DescriptorTagAC3)) // Tag
w.Write(uint8(9)) // Length
Expand Down Expand Up @@ -154,6 +154,16 @@ func TestParseDescriptor(t *testing.T) {
w.Write(uint8(4)) // Length
w.Write([]byte("cou")) // Item #1 country code
w.Write(uint8(2)) // Item #1 rating
// Local time offset
w.Write(uint8(DescriptorTagLocalTimeOffset)) // Tag
w.Write(uint8(13)) // Length
w.Write([]byte("cou")) // Country code
w.Write("101010") // Country region ID
w.Write("1") // Reserved
w.Write("1") // Local time offset polarity
w.Write(dvbDurationMinutesBytes) // Local time offset
w.Write(dvbTimeBytes) // Time of change
w.Write(dvbDurationMinutesBytes) // Next time offset

// Assert
var offset int
Expand Down Expand Up @@ -266,4 +276,12 @@ func TestParseDescriptor(t *testing.T) {
CountryCode: []byte("cou"),
Rating: 2,
}}})
assert.Equal(t, *ds[15].LocalTimeOffset, DescriptorLocalTimeOffset{Items: []*DescriptorLocalTimeOffsetItem{{
CountryCode: []byte("cou"),
CountryRegionID: 42,
LocalTimeOffset: dvbDurationMinutes,
LocalTimeOffsetPolarity: true,
NextTimeOffset: dvbDurationMinutes,
TimeOfChange: dvbTime,
}}})
}
14 changes: 11 additions & 3 deletions dvb.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,21 @@ func parseDVBTime(i []byte, offset *int) (t time.Time) {
*offset += 2

// Time
t = t.Add(parseDVBDuration(i, offset))
t = t.Add(parseDVBDurationSeconds(i, offset))
return
}

// parseDVBDuration parses a duration
// parseDVBDurationMinutes parses a minutes duration
// 16 bit field containing the duration of the event in hours, minutes. format: 4 digits, 4 - bit BCD = 18 bit
func parseDVBDurationMinutes(i []byte, offset *int) (d time.Duration) {
d = parseDVBDurationByte(i[*offset])*time.Hour + parseDVBDurationByte(i[*offset+1])*time.Minute
*offset += 2
return
}

// parseDVBDurationSeconds parses a seconds duration
// 24 bit field containing the duration of the event in hours, minutes, seconds. format: 6 digits, 4 - bit BCD = 24 bit
func parseDVBDuration(i []byte, offset *int) (d time.Duration) {
func parseDVBDurationSeconds(i []byte, offset *int) (d time.Duration) {
d = parseDVBDurationByte(i[*offset])*time.Hour + parseDVBDurationByte(i[*offset+1])*time.Minute + parseDVBDurationByte(i[*offset+2])*time.Second
*offset += 3
return
Expand Down
23 changes: 16 additions & 7 deletions dvb_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ import (
)

var (
dvbDuration = time.Hour + 45*time.Minute + 30*time.Second
dvbDurationBytes = []byte{0x1, 0x45, 0x30} // 014530
dvbTime, _ = time.Parse("2006-01-02 15:04:05", "1993-10-13 12:45:00")
dvbTimeBytes = []byte{0xc0, 0x79, 0x12, 0x45, 0x0} // C079124500
dvbDurationMinutes = time.Hour + 45*time.Minute
dvbDurationMinutesBytes = []byte{0x1, 0x45} // 0145
dvbDurationSeconds = time.Hour + 45*time.Minute + 30*time.Second
dvbDurationSecondsBytes = []byte{0x1, 0x45, 0x30} // 014530
dvbTime, _ = time.Parse("2006-01-02 15:04:05", "1993-10-13 12:45:00")
dvbTimeBytes = []byte{0xc0, 0x79, 0x12, 0x45, 0x0} // C079124500
)

func TestParseDVBTime(t *testing.T) {
Expand All @@ -21,9 +23,16 @@ func TestParseDVBTime(t *testing.T) {
assert.Equal(t, 5, offset)
}

func TestParseDVBDuration(t *testing.T) {
func TestParseDVBDurationMinutes(t *testing.T) {
var offset int
d := parseDVBDuration(dvbDurationBytes, &offset)
assert.Equal(t, dvbDuration, d)
d := parseDVBDurationMinutes(dvbDurationMinutesBytes, &offset)
assert.Equal(t, dvbDurationMinutes, d)
assert.Equal(t, 2, offset)
}

func TestParseDVBDurationSeconds(t *testing.T) {
var offset int
d := parseDVBDurationSeconds(dvbDurationSecondsBytes, &offset)
assert.Equal(t, dvbDurationSeconds, d)
assert.Equal(t, 3, offset)
}

0 comments on commit beda8c6

Please sign in to comment.