mirror of https://bitbucket.org/ausocean/av.git
Merged in new-psi (pull request #409)
container/mts: add constructors for standard PAT and PMT PSI tables in PSI package and have MTS encoder use these. Approved-by: Trek Hopton <trek.hopton@gmail.com>
This commit is contained in:
commit
5699dc2f97
|
@ -106,44 +106,6 @@ const (
|
||||||
defaultMediaPID = PIDVideo
|
defaultMediaPID = PIDVideo
|
||||||
)
|
)
|
||||||
|
|
||||||
// Some common manifestations of PSI.
|
|
||||||
var (
|
|
||||||
// StandardPAT is a minimal PAT.
|
|
||||||
StandardPAT = psi.PSI{
|
|
||||||
Pf: 0x00,
|
|
||||||
Tid: 0x00,
|
|
||||||
Ssi: true,
|
|
||||||
Pb: false,
|
|
||||||
Sl: 0x0d,
|
|
||||||
Tss: &psi.TSS{
|
|
||||||
Tide: 0x01,
|
|
||||||
V: 0,
|
|
||||||
Cni: true,
|
|
||||||
Sn: 0,
|
|
||||||
Lsn: 0,
|
|
||||||
Sd: &psi.PAT{
|
|
||||||
Pn: 0x01,
|
|
||||||
Pmpid: 0x1000,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// Base PMT is a minimal PMT without specific data.
|
|
||||||
BasePMT = psi.PSI{
|
|
||||||
Pf: 0x00,
|
|
||||||
Tid: 0x02,
|
|
||||||
Ssi: true,
|
|
||||||
Sl: 0x12,
|
|
||||||
Tss: &psi.TSS{
|
|
||||||
Tide: 0x01,
|
|
||||||
V: 0,
|
|
||||||
Cni: true,
|
|
||||||
Sn: 0,
|
|
||||||
Lsn: 0,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// Meta allows addition of metadata to encoded mts from outside of this pkg.
|
// Meta allows addition of metadata to encoded mts from outside of this pkg.
|
||||||
// See meta pkg for usage.
|
// See meta pkg for usage.
|
||||||
//
|
//
|
||||||
|
@ -153,11 +115,6 @@ var Meta *meta.Data
|
||||||
// This will help us obtain a realtime for timestamp meta encoding.
|
// This will help us obtain a realtime for timestamp meta encoding.
|
||||||
var RealTime = realtime.NewRealTime()
|
var RealTime = realtime.NewRealTime()
|
||||||
|
|
||||||
var (
|
|
||||||
patTable = StandardPAT.Bytes()
|
|
||||||
pmtTable []byte
|
|
||||||
)
|
|
||||||
|
|
||||||
type logger interface {
|
type logger interface {
|
||||||
Debug(string, ...interface{})
|
Debug(string, ...interface{})
|
||||||
Info(string, ...interface{})
|
Info(string, ...interface{})
|
||||||
|
@ -188,6 +145,9 @@ type Encoder struct {
|
||||||
mediaPID uint16
|
mediaPID uint16
|
||||||
streamID byte
|
streamID byte
|
||||||
|
|
||||||
|
pmt *psi.PSI
|
||||||
|
patBytes, pmtBytes []byte
|
||||||
|
|
||||||
// log is a function that will be used through the encoder code for logging.
|
// log is a function that will be used through the encoder code for logging.
|
||||||
log logger
|
log logger
|
||||||
}
|
}
|
||||||
|
@ -205,6 +165,8 @@ func NewEncoder(dst io.WriteCloser, log logger, options ...func(*Encoder) error)
|
||||||
streamID: defaultStreamID,
|
streamID: defaultStreamID,
|
||||||
continuity: map[uint16]byte{PatPid: 0, PmtPid: 0, defaultMediaPID: 0},
|
continuity: map[uint16]byte{PatPid: 0, PmtPid: 0, defaultMediaPID: 0},
|
||||||
log: log,
|
log: log,
|
||||||
|
patBytes: psi.NewPATPSI().Bytes(),
|
||||||
|
pmt: psi.NewPMTPSI(),
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, option := range options {
|
for _, option := range options {
|
||||||
|
@ -215,17 +177,9 @@ func NewEncoder(dst io.WriteCloser, log logger, options ...func(*Encoder) error)
|
||||||
}
|
}
|
||||||
log.Debug("encoder options applied")
|
log.Debug("encoder options applied")
|
||||||
|
|
||||||
pmt := BasePMT
|
e.pmt.Tss.Sd.(*psi.PMT).Essd.St = e.streamID
|
||||||
pmt.Tss.Sd = &psi.PMT{
|
e.pmt.Tss.Sd.(*psi.PMT).Essd.Epid = e.mediaPID
|
||||||
Pcrpid: 0x0100,
|
e.pmtBytes = e.pmt.Bytes()
|
||||||
Pil: 0,
|
|
||||||
Essd: &psi.ESSD{
|
|
||||||
St: byte(e.streamID),
|
|
||||||
Epid: e.mediaPID,
|
|
||||||
Esil: 0x00,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
pmtTable = pmt.Bytes()
|
|
||||||
|
|
||||||
return e, nil
|
return e, nil
|
||||||
}
|
}
|
||||||
|
@ -324,7 +278,7 @@ func (e *Encoder) writePSI() error {
|
||||||
PID: PatPid,
|
PID: PatPid,
|
||||||
CC: e.ccFor(PatPid),
|
CC: e.ccFor(PatPid),
|
||||||
AFC: hasPayload,
|
AFC: hasPayload,
|
||||||
Payload: psi.AddPadding(patTable),
|
Payload: psi.AddPadding(e.patBytes),
|
||||||
}
|
}
|
||||||
_, err := e.dst.Write(patPkt.Bytes(e.tsSpace[:PacketSize]))
|
_, err := e.dst.Write(patPkt.Bytes(e.tsSpace[:PacketSize]))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -332,7 +286,7 @@ func (e *Encoder) writePSI() error {
|
||||||
}
|
}
|
||||||
e.pktCount++
|
e.pktCount++
|
||||||
|
|
||||||
pmtTable, err = updateMeta(pmtTable, e.log)
|
e.pmtBytes, err = updateMeta(e.pmtBytes, e.log)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -344,7 +298,7 @@ func (e *Encoder) writePSI() error {
|
||||||
PID: PmtPid,
|
PID: PmtPid,
|
||||||
CC: e.ccFor(PmtPid),
|
CC: e.ccFor(PmtPid),
|
||||||
AFC: hasPayload,
|
AFC: hasPayload,
|
||||||
Payload: psi.AddPadding(pmtTable),
|
Payload: psi.AddPadding(e.pmtBytes),
|
||||||
}
|
}
|
||||||
_, err = e.dst.Write(pmtPkt.Bytes(e.tsSpace[:PacketSize]))
|
_, err = e.dst.Write(pmtPkt.Bytes(e.tsSpace[:PacketSize]))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -98,13 +98,15 @@ func TestGetPTSRange1(t *testing.T) {
|
||||||
|
|
||||||
// writePSI is a helper function write the PSI found at the start of a clip.
|
// writePSI is a helper function write the PSI found at the start of a clip.
|
||||||
func writePSI(b *bytes.Buffer) error {
|
func writePSI(b *bytes.Buffer) error {
|
||||||
|
patBytes := psi.NewPATPSI().Bytes()
|
||||||
|
pmtBytes := psi.NewPMTPSI().Bytes()
|
||||||
// Write PAT.
|
// Write PAT.
|
||||||
pat := Packet{
|
pat := Packet{
|
||||||
PUSI: true,
|
PUSI: true,
|
||||||
PID: PatPid,
|
PID: PatPid,
|
||||||
CC: 0,
|
CC: 0,
|
||||||
AFC: HasPayload,
|
AFC: HasPayload,
|
||||||
Payload: psi.AddPadding(patTable),
|
Payload: psi.AddPadding(patBytes),
|
||||||
}
|
}
|
||||||
_, err := b.Write(pat.Bytes(nil))
|
_, err := b.Write(pat.Bytes(nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -117,7 +119,7 @@ func writePSI(b *bytes.Buffer) error {
|
||||||
PID: PmtPid,
|
PID: PmtPid,
|
||||||
CC: 0,
|
CC: 0,
|
||||||
AFC: HasPayload,
|
AFC: HasPayload,
|
||||||
Payload: psi.AddPadding(pmtTable),
|
Payload: psi.AddPadding(pmtBytes),
|
||||||
}
|
}
|
||||||
_, err = b.Write(pmt.Bytes(nil))
|
_, err = b.Write(pmt.Bytes(nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -137,13 +137,15 @@ func TestExtract(t *testing.T) {
|
||||||
|
|
||||||
// writePSIWithMeta writes PSI to b with updated metadata.
|
// writePSIWithMeta writes PSI to b with updated metadata.
|
||||||
func writePSIWithMeta(b *bytes.Buffer, t *testing.T) error {
|
func writePSIWithMeta(b *bytes.Buffer, t *testing.T) error {
|
||||||
|
patBytes := psi.NewPATPSI().Bytes()
|
||||||
|
pmtBytes := psi.NewPMTPSI().Bytes()
|
||||||
// Write PAT.
|
// Write PAT.
|
||||||
pat := Packet{
|
pat := Packet{
|
||||||
PUSI: true,
|
PUSI: true,
|
||||||
PID: PatPid,
|
PID: PatPid,
|
||||||
CC: 0,
|
CC: 0,
|
||||||
AFC: HasPayload,
|
AFC: HasPayload,
|
||||||
Payload: psi.AddPadding(patTable),
|
Payload: psi.AddPadding(patBytes),
|
||||||
}
|
}
|
||||||
_, err := b.Write(pat.Bytes(nil))
|
_, err := b.Write(pat.Bytes(nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -151,7 +153,7 @@ func writePSIWithMeta(b *bytes.Buffer, t *testing.T) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the meta in the pmt table.
|
// Update the meta in the pmt table.
|
||||||
pmtTable, err = updateMeta(pmtTable, (*testLogger)(t))
|
pmtBytes, err = updateMeta(pmtBytes, (*testLogger)(t))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -162,7 +164,7 @@ func writePSIWithMeta(b *bytes.Buffer, t *testing.T) error {
|
||||||
PID: PmtPid,
|
PID: PmtPid,
|
||||||
CC: 0,
|
CC: 0,
|
||||||
AFC: HasPayload,
|
AFC: HasPayload,
|
||||||
Payload: psi.AddPadding(pmtTable),
|
Payload: psi.AddPadding(pmtBytes),
|
||||||
}
|
}
|
||||||
_, err = b.Write(pmt.Bytes(nil))
|
_, err = b.Write(pmt.Bytes(nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -96,6 +96,57 @@ const DescriptorsIdx = ProgramInfoLenIdx2 + 1
|
||||||
// MetadataTag is the descriptor tag used for metadata.
|
// MetadataTag is the descriptor tag used for metadata.
|
||||||
const MetadataTag = 0x26
|
const MetadataTag = 0x26
|
||||||
|
|
||||||
|
// NewPATPSI will provide a standard program specific information (PSI) table
|
||||||
|
// with a program association table (PAT) specific data field.
|
||||||
|
func NewPATPSI() *PSI {
|
||||||
|
return &PSI{
|
||||||
|
Pf: 0x00,
|
||||||
|
Tid: 0x00,
|
||||||
|
Ssi: true,
|
||||||
|
Pb: false,
|
||||||
|
Sl: 0x0d,
|
||||||
|
Tss: &TSS{
|
||||||
|
Tide: 0x01,
|
||||||
|
V: 0,
|
||||||
|
Cni: true,
|
||||||
|
Sn: 0,
|
||||||
|
Lsn: 0,
|
||||||
|
Sd: &PAT{
|
||||||
|
Pn: 0x01,
|
||||||
|
Pmpid: 0x1000,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewPMTPSI will provide a standard program specific information (PSI) table
|
||||||
|
// with a program mapping table specific data field.
|
||||||
|
// NOTE: Media PID and stream ID are default to 0.
|
||||||
|
func NewPMTPSI() *PSI {
|
||||||
|
return &PSI{
|
||||||
|
Pf: 0x00,
|
||||||
|
Tid: 0x02,
|
||||||
|
Ssi: true,
|
||||||
|
Sl: 0x12,
|
||||||
|
Tss: &TSS{
|
||||||
|
Tide: 0x01,
|
||||||
|
V: 0,
|
||||||
|
Cni: true,
|
||||||
|
Sn: 0,
|
||||||
|
Lsn: 0,
|
||||||
|
Sd: &PMT{
|
||||||
|
Pcrpid: 0x0100,
|
||||||
|
Pil: 0,
|
||||||
|
Essd: &ESSD{
|
||||||
|
St: 0,
|
||||||
|
Epid: 0,
|
||||||
|
Esil: 0x00,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: get rid of these - not a good idea.
|
// TODO: get rid of these - not a good idea.
|
||||||
type (
|
type (
|
||||||
PSIBytes []byte
|
PSIBytes []byte
|
||||||
|
|
Loading…
Reference in New Issue