diff --git a/stream/mts/psi/psi.go b/stream/mts/psi/psi.go index 3fb57c86..7366ee3b 100644 --- a/stream/mts/psi/psi.go +++ b/stream/mts/psi/psi.go @@ -21,6 +21,10 @@ const ( PMTTableID = 0x02 ) +const ( + timestampDescTag = 234 +) + // Program specific information type PSI struct { Pf byte // Point field @@ -59,7 +63,7 @@ type PMT struct { Pcrpid uint16 // Program clock reference pid Pil uint16 // Program info length Pd []Desc // Program descriptors - Essd []ESSD // Elementary stream specific data + Essd ESSD // Elementary stream specific data } // Elementary stream specific data @@ -113,17 +117,68 @@ func readTSS(data []byte, p *PSI) *TSS { pos++ tss.Lsn = data[pos] pos++ - if p.Tid == PATTableID { - tss.Sd = readPAT(data, &tss) - } else if p.Tid == PMTTableID { - tss.Sd = readPMT(data, &tss) - } else { + switch p.Tid { + case PATTableID: + tss.Sd = readPAT(data[pos:], &tss) + case PMTTableID: + tss.Sd = readPMT(data[pos:], &tss) + default: panic("Can't yet deal with tables that are not PAT or PMT") } + return &tss +} +func readPAT(data []byte, p *TSS) *PAT { + pat := PAT{} + pos := 0 + pat.Pn = uint16(data[pos])<<8 | uint16(data[pos+1]) + pos += 2 + pat.Pmpid = uint16(data[pos]&0x1f)<<8 | uint16(data[pos+1]) + return &pat +} + +func readPMT(data []byte, p *TSS) *PAT { + pmt := PMT{} + pos := 0 + pmt.Pcrpid = uint16(data[pos]&0x1f)<<8 | uint16(data[pos+1]) + pos += 2 + pmt.Pil = uint16(data[pos]&0x03)<<8 | uint16(data[pos+1]) + pos += 2 + if pmt.Pil != 0 { + pmt.Pd = readDescs(data[pos:], int(pmt.Pil)) + } + pos += int(pmt.Pil) + // TODO Read ES stuff + pmt.Essd = readEssd(data[pos:]) return nil } +// readDescs reads provides a slice of Descs given a byte slice that represents Descs +// and the no of bytes that the descs accumilate +func readDescs(data []byte, descLen int) (o []Desc) { + pos := 0 + o = make([]Desc, 1) + o[0].Dt = data[pos] + pos++ + o[0].Dl = data[pos] + pos++ + o[0].Dd = make([]byte, o[0].Dl) + for i := 0; i < int(o[0].Dl); i++ { + o[0].Dd[i] = data[pos] + pos++ + } + if 2+len(o[0].Dd) != descLen { + panic("No support for reading more than one descriptor") + } + return +} + +func readEssd(data []byte) *ESSD { + essd := ESSD{} + pos := 0 + essd.St = data[pos] +} + // Bytes outputs a byte slice representation of the PSI func (p *PSI) Bytes() []byte { l := 1 + len(p.Pfb) @@ -177,9 +232,7 @@ func (p *PMT) Bytes() []byte { for _, d := range p.Pd { out = append(out, d.Bytes()...) } - for _, e := range p.Essd { - out = append(out, e.Bytes()...) - } + out = append(out, p.Essd.Bytes()...) return out } @@ -206,18 +259,18 @@ func (e *ESSD) Bytes() []byte { return out } -func boolToByte(b bool) byte { +func boolToByte(b bool) (o byte) { if b { - return 0x01 + o = 0x01 } - return 0x00 + return } -func byteToBool(b byte) bool { - if b == 0 { - return false +func byteToBool(b byte) (o bool) { + if b != 0 { + o = true } - return true + return } func crc32_MakeTable(poly uint32) *crc32.Table {