av/stream/mts/psi/psi.go

150 lines
3.2 KiB
Go
Raw Normal View History

package psi
const (
2018-12-05 17:11:53 +03:00
ESSDDefLen = 5
DescDefLen = 2
PMTDefLen = 4
PATLen = 4
TSSDefLen = 5
PSIDefLen = 3
)
// Program specific information
type PSI struct {
pf byte // Point field
pfb []byte // Pointer filler bytes
tid byte // Table ID
ssi bool // Section syntax indicator (1 for PAT, PMT, CAT)
pb bool // Private bit (0 for PAT, PMT, CAT)
sl uint16 // Section length
tss *TSS // Table syntax section (length defined by SL) if length 0 then nil
crc uint32 // crc32 of entire table excluding pointer field, pointer filler bytes and the trailing CRC32
}
// Table syntax section
type TSS struct {
tide uint16 // Table ID extension
v byte // Version number
cni bool // Current/next indicator
sn byte // Section number
lsn byte // Last section number
sd SD // Specific data PAT/PMT
}
// Specific Data, (could be PAT or PMT)
type SD interface {
Bytes() []byte
}
// Program association table, implements SD
type PAT struct {
pn uint16 // Program Number
pmpid uint16 // Program map PID
}
// Program mapping table, implements SD
type PMT struct {
2018-12-05 14:17:16 +03:00
pcrpid uint16 // Program clock reference pid
pil uint16 // Program info length
pd []Desc // Program descriptors
essd []ESSD // Elementary stream specific data
}
// Elementary stream specific data
type ESSD struct {
2018-12-05 14:17:16 +03:00
st byte // Stream type
2018-12-05 17:04:29 +03:00
epid uint16 // Elementary pid
2018-12-05 14:17:16 +03:00
esil uint16 // Elementary stream
esd []Desc // Elementary stream desriptors
}
// Descriptor
type Desc struct {
dt byte // Descriptor tag
dl byte // Descriptor length
dd []byte // Descriptor data
}
// TODO: Implement this
func ReadPSI(data []byte) *PSI {
return nil
}
func (p *PSI) Bytes() []byte {
l := 1 + len(p.pfb)
out := make([]byte, l+PSIDefLen)
out[0] = p.pf
for i, b := range p.pfb {
out[1+i] = b
}
out[l] = p.tid
out[l+1] = 0x80 | 0x40 | 0x30 | (0x03 & byte(p.sl>>8))
out[l+2] = byte(p.sl)
out = append(out, p.tss.Bytes()...)
crc32 := crc32_op()
return nil
}
func (t *TSS) Bytes() []byte {
out := make([]byte, TSSDefLen)
out[0] = byte(t.tide >> 8)
out[1] = byte(t.tide)
out[2] = 0xc0 | (0x3e & (t.v << 1)) | (0x01 & boolToByte(t.cni))
out[3] = t.sn
out[4] = t.lsn
out = append(out, t.sd.Bytes()...)
return out
}
2018-12-05 17:11:53 +03:00
func (p *PAT) Bytes() []byte {
out := make([]byte, PATLen)
out[0] = byte(p.pn >> 8)
out[1] = byte(p.pn)
out[2] = 0xe0 | (0x1f & byte(p.pmpid>>8))
out[3] = byte(p.pmpid)
return out
}
2018-12-05 17:04:29 +03:00
func (p *PMT) Bytes() []byte {
2018-12-05 17:11:53 +03:00
out := make([]byte, PMTDefLen)
2018-12-05 17:04:29 +03:00
out[0] = 0xe0 | (0x1f & byte(p.pcrpid>>8))
out[1] = byte(p.pcrpid)
out[2] = 0xf0 | (0x03 & byte(p.pil>>8))
out[3] = byte(p.pil)
for _, d := range p.pd {
out = append(out, d.Bytes()...)
}
for _, e := range p.essd {
out = append(out, e.Bytes()...)
}
return out
}
2018-12-05 17:04:29 +03:00
func (d *Desc) Bytes() []byte {
2018-12-05 17:11:53 +03:00
out := make([]byte, DescDefLen)
out[0] = d.dt
out[1] = d.dl
out = append(out, d.dd...)
2018-12-05 17:04:29 +03:00
return out
}
2018-12-05 17:04:29 +03:00
func (e *ESSD) Bytes() []byte {
2018-12-05 17:11:53 +03:00
out := make([]byte, ESSDDefLen)
out[0] = e.st
2018-12-05 17:04:29 +03:00
out[1] = 0xe0 | (0x1f & byte(e.epid>>8))
out[2] = byte(e.epid)
out[3] = 0xf0 | (0x03 & byte(e.esil>>8))
out[4] = byte(e.esil)
for _, d := range e.esd {
out = append(out, d.Bytes()...)
}
2018-12-05 17:04:29 +03:00
return out
}
func boolToByte(b bool) byte {
if b {
return 0x01
}
return 0x00
}