mirror of https://bitbucket.org/ausocean/av.git
generator: refactor main processing loop and improve commentary
This commit is contained in:
parent
7d1bfcefe9
commit
3279a4746d
|
@ -57,10 +57,17 @@ const (
|
|||
patPid = 0
|
||||
pmtPid = 4096
|
||||
videoPid = 256
|
||||
streamID = 0xe0
|
||||
streamID = 0xe0 // First video stream ID.
|
||||
)
|
||||
|
||||
// Time related constants.
|
||||
const (
|
||||
// ptsOffset is the offset added to the clock to determine
|
||||
// the current presentation timestamp,
|
||||
ptsOffset = 700 * time.Millisecond
|
||||
ptsFreq = 90000 // Hz
|
||||
maxCC = 0xf
|
||||
|
||||
// pcrFreq is the base Program Clock Reference frequency.
|
||||
pcrFreq = 90000 // Hz
|
||||
)
|
||||
|
||||
// tsGenerator encapsulates properties of an mpegts generator.
|
||||
|
@ -112,14 +119,46 @@ func (g *tsGenerator) OutputChan() <-chan []byte {
|
|||
return g.outputChan
|
||||
}
|
||||
|
||||
const (
|
||||
hasPayload = 0x1
|
||||
hasAdaptationField = 0x2
|
||||
)
|
||||
|
||||
const (
|
||||
hasDTS = 0x1
|
||||
hasPTS = 0x2
|
||||
)
|
||||
|
||||
// generate handles the incoming data and generates equivalent mpegts packets -
|
||||
// sending them to the output channel
|
||||
func (g *tsGenerator) generate() {
|
||||
for {
|
||||
nalu := <-g.nalInputChan
|
||||
|
||||
// Write PAT
|
||||
patPkt := mpegts.Packet{
|
||||
PUSI: true,
|
||||
PID: patPid,
|
||||
CC: g.ccFor(patPid),
|
||||
AFC: hasPayload,
|
||||
Payload: patTable,
|
||||
}
|
||||
g.outputChan <- patPkt.Bytes()
|
||||
|
||||
// Write PMT.
|
||||
pmtPkt := mpegts.Packet{
|
||||
PUSI: true,
|
||||
PID: pmtPid,
|
||||
CC: g.ccFor(pmtPid),
|
||||
AFC: hasPayload,
|
||||
Payload: pmtTable,
|
||||
}
|
||||
g.outputChan <- pmtPkt.Bytes()
|
||||
|
||||
// Prepare PES data.
|
||||
pesPkt := pes.Packet{
|
||||
StreamID: streamID,
|
||||
PDI: 2,
|
||||
PDI: hasPTS,
|
||||
PTS: g.pts(),
|
||||
Data: nalu,
|
||||
HeaderLength: 5,
|
||||
|
@ -133,44 +172,23 @@ func (g *tsGenerator) generate() {
|
|||
PID: videoPid,
|
||||
RAI: pusi,
|
||||
CC: g.ccFor(videoPid),
|
||||
AFC: 3,
|
||||
AFC: hasAdaptationField | hasPayload,
|
||||
PCRF: pusi,
|
||||
}
|
||||
n := pkt.FillPayload(buf)
|
||||
buf = buf[n:]
|
||||
|
||||
// TODO: create consts for AFC parameters
|
||||
if pusi {
|
||||
// Create pat table
|
||||
patPkt := mpegts.Packet{
|
||||
PUSI: pusi,
|
||||
PID: patPid,
|
||||
CC: g.ccFor(patPid),
|
||||
AFC: 1,
|
||||
Payload: patTable,
|
||||
}
|
||||
g.outputChan <- patPkt.Bytes()
|
||||
|
||||
// Create pmt table
|
||||
pmtPkt := mpegts.Packet{
|
||||
PUSI: pusi,
|
||||
PID: pmtPid,
|
||||
CC: g.ccFor(pmtPid),
|
||||
AFC: 1,
|
||||
Payload: pmtTable,
|
||||
}
|
||||
g.outputChan <- pmtPkt.Bytes()
|
||||
|
||||
// If pusi then we need to gen a pcr
|
||||
// If the packet has a Payload Unit Start Indicator
|
||||
// flag set then we need to write a PCR.
|
||||
pkt.PCR = g.pcr()
|
||||
|
||||
g.tick()
|
||||
|
||||
pusi = false
|
||||
}
|
||||
|
||||
g.outputChan <- pkt.Bytes()
|
||||
}
|
||||
|
||||
g.tick()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -181,17 +199,18 @@ func (g *tsGenerator) tick() {
|
|||
|
||||
// pts retuns the current presentation timestamp.
|
||||
func (g *tsGenerator) pts() uint64 {
|
||||
return uint64((g.clock + g.ptsOffset).Seconds() * ptsFreq)
|
||||
return uint64((g.clock + g.ptsOffset).Seconds() * pcrFreq)
|
||||
}
|
||||
|
||||
// pcr returns the current program clock reference.
|
||||
func (g *tsGenerator) pcr() uint64 {
|
||||
return uint64(g.clock.Seconds() * ptsFreq)
|
||||
return uint64(g.clock.Seconds() * pcrFreq)
|
||||
}
|
||||
|
||||
// ccFor returns the next continuity counter for pid.
|
||||
func (g *tsGenerator) ccFor(pid int) byte {
|
||||
cc := g.continuity[pid]
|
||||
g.continuity[pid] = (cc + 1) & maxCC
|
||||
const continuityCounterMask = 0xf
|
||||
g.continuity[pid] = (cc + 1) & continuityCounterMask
|
||||
return cc
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue