container/mts: add constructors for standard PAT and PMT PSI tables in psi package and have MTS encoder use these.

This commit is contained in:
Saxon 2020-05-12 18:15:37 +09:30
parent 3f7306f2a8
commit a96f805e35
4 changed files with 71 additions and 62 deletions

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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