forked from futzu/cuei
-
Notifications
You must be signed in to change notification settings - Fork 0
/
commands.go
191 lines (168 loc) · 4.5 KB
/
commands.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
package cuei
import (
"fmt"
)
/*
Command
These Splice Command types are consolidated into Command.
0x0: Splice Null,
0x5: Splice Insert,
0x6: Time Signal,
0x7: Bandwidth Reservation,
0xff: Private,
*/
type Command struct {
Name string
CommandType uint8
PrivateBytes []byte `json:",omitempty"`
Identifier uint32 `json:",omitempty"`
SpliceEventID uint32 `json:",omitempty"`
SpliceEventCancelIndicator bool `json:",omitempty"`
OutOfNetworkIndicator bool `json:",omitempty"`
ProgramSpliceFlag bool `json:",omitempty"`
DurationFlag bool `json:",omitempty"`
BreakAutoReturn bool `json:",omitempty"`
BreakDuration float64 `json:",omitempty"`
SpliceImmediateFlag bool `json:",omitempty"`
UniqueProgramID uint16 `json:",omitempty"`
AvailNum uint8 `json:",omitempty"`
AvailExpected uint8 `json:",omitempty"`
TimeSpecifiedFlag bool `json:",omitempty"`
PTS float64 `json:",omitempty"`
}
// Return Command as JSON
func (cmd *Command)Json() string{
return mkJson(cmd)
}
// Print Command as JSON
func (cmd *Command)Show(){
fmt.Printf(cmd.Json())
}
// Decode a Splice Command
func (cmd *Command) Decode(cmdtype uint8, bd *bitDecoder) {
cmd.CommandType = cmdtype
switch cmdtype {
case 0x0:
cmd.decodeSpliceNull(bd)
case 0x5:
cmd.decodeSpliceInsert(bd)
case 0x6:
cmd.decodeTimeSignal(bd)
case 0x7:
cmd.decodeBandwidthReservation(bd)
case 0xff:
cmd.decodePrivate(bd)
}
}
// Encode a Splice Command and return the bytes
// mostly used by cuei.Cue
func (cmd *Command) Encode() []byte {
blank := []byte{}
switch cmd.CommandType {
case 0x5:
return cmd.encodeSpliceInsert()
case 0x6:
return cmd.encodeTimeSignal()
}
return blank
}
// bandwidth Reservation
func (cmd *Command) decodeBandwidthReservation(bd *bitDecoder) {
cmd.Name = "Bandwidth Reservation"
bd.goForward(0)
}
// private Command
func (cmd *Command) decodePrivate(bd *bitDecoder) {
cmd.Name = "Private Command"
cmd.Identifier = bd.uInt32(32)
cmd.PrivateBytes = bd.asBytes(24)
}
// splice Null
func (cmd *Command) decodeSpliceNull(bd *bitDecoder) {
cmd.Name = "Splice Null"
bd.goForward(0)
}
// splice Insert
func (cmd *Command) decodeSpliceInsert(bd *bitDecoder) {
cmd.Name = "Splice Insert"
cmd.SpliceEventID = bd.uInt32(32)
cmd.SpliceEventCancelIndicator = bd.asFlag()
bd.goForward(7)
cmd.OutOfNetworkIndicator = bd.asFlag()
cmd.ProgramSpliceFlag = bd.asFlag()
cmd.DurationFlag = bd.asFlag()
cmd.SpliceImmediateFlag = bd.asFlag()
bd.goForward(4)
if !cmd.SpliceImmediateFlag {
cmd.spliceTime(bd)
}
if cmd.DurationFlag == true {
cmd.parseBreak(bd)
}
cmd.UniqueProgramID = bd.uInt16(16)
cmd.AvailNum = bd.uInt8(8)
cmd.AvailExpected = bd.uInt8(8)
}
// encode Splice Insert Splice Command
func (cmd *Command) encodeSpliceInsert() []byte {
be := &bitEncoder{}
be.Add(1, 8) //bumper
be.Add(cmd.SpliceEventID, 32)
be.Add(cmd.SpliceEventCancelIndicator, 1)
be.Reserve(7)
be.Add(cmd.OutOfNetworkIndicator, 1)
be.Add(cmd.ProgramSpliceFlag, 1)
be.Add(cmd.DurationFlag, 1)
be.Add(cmd.SpliceImmediateFlag, 1)
be.Reserve(4)
if !cmd.SpliceImmediateFlag {
cmd.encodeSpliceTime(be)
}
if cmd.DurationFlag {
cmd.encodeBreak(be)
}
be.Add(cmd.UniqueProgramID, 16)
be.Add(cmd.AvailNum, 8)
be.Add(cmd.AvailExpected, 8)
return be.Bites.Bytes()[1:] // drop Bytes[0] it's just a bumper to allow leading zero values
}
func (cmd *Command) encodeBreak(be *bitEncoder) {
be.Add(cmd.BreakAutoReturn, 1)
be.Reserve(6)
be.Add(cmd.BreakDuration, 33)
}
// encode PTS splice times
func (cmd *Command) encodeSpliceTime(be *bitEncoder) {
be.Add(cmd.TimeSpecifiedFlag, 1)
if cmd.TimeSpecifiedFlag == true {
be.Reserve(6)
be.Add(cmd.PTS, 33)
return
}
be.Reserve(7)
}
func (cmd *Command) parseBreak(bd *bitDecoder) {
cmd.BreakAutoReturn = bd.asFlag()
bd.goForward(6)
cmd.BreakDuration = bd.as90k(33)
}
func (cmd *Command) spliceTime(bd *bitDecoder) {
cmd.TimeSpecifiedFlag = bd.asFlag()
if cmd.TimeSpecifiedFlag {
bd.goForward(6)
cmd.PTS = bd.as90k(33)
} else {
bd.goForward(7)
}
}
// decode Time Signal Splice Commands
func (cmd *Command) decodeTimeSignal(bd *bitDecoder) {
cmd.Name = "Time Signal"
cmd.spliceTime(bd)
}
// encode Time Signal Splice Commands
func (cmd *Command) encodeTimeSignal() []byte {
be := &bitEncoder{}
cmd.encodeSpliceTime(be)
return be.Bites.Bytes()
}