mirror of https://bitbucket.org/ausocean/av.git
container/mts: simplified Packet.Bytes(), and tested
This commit is contained in:
parent
0e362e6056
commit
3292ce0506
|
@ -264,7 +264,7 @@ func (e *Encoder) writePSI() error {
|
||||||
PUSI: true,
|
PUSI: true,
|
||||||
PID: PatPid,
|
PID: PatPid,
|
||||||
CC: e.ccFor(PatPid),
|
CC: e.ccFor(PatPid),
|
||||||
AFC: HasPayload,
|
AFC: hasPayload,
|
||||||
Payload: psi.AddPadding(patTable),
|
Payload: psi.AddPadding(patTable),
|
||||||
}
|
}
|
||||||
_, err := e.dst.Write(patPkt.Bytes(e.tsSpace[:PacketSize]))
|
_, err := e.dst.Write(patPkt.Bytes(e.tsSpace[:PacketSize]))
|
||||||
|
@ -282,7 +282,7 @@ func (e *Encoder) writePSI() error {
|
||||||
PUSI: true,
|
PUSI: true,
|
||||||
PID: PmtPid,
|
PID: PmtPid,
|
||||||
CC: e.ccFor(PmtPid),
|
CC: e.ccFor(PmtPid),
|
||||||
AFC: HasPayload,
|
AFC: hasPayload,
|
||||||
Payload: psi.AddPadding(pmtTable),
|
Payload: psi.AddPadding(pmtTable),
|
||||||
}
|
}
|
||||||
_, err = e.dst.Write(pmtPkt.Bytes(e.tsSpace[:PacketSize]))
|
_, err = e.dst.Write(pmtPkt.Bytes(e.tsSpace[:PacketSize]))
|
||||||
|
|
|
@ -27,7 +27,6 @@ package mts
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -53,6 +52,7 @@ func (d *destination) Write(p []byte) (int, error) {
|
||||||
return len(p), nil
|
return len(p), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
func TestEncodeVideo(t *testing.T) {
|
func TestEncodeVideo(t *testing.T) {
|
||||||
Meta = meta.New()
|
Meta = meta.New()
|
||||||
|
|
||||||
|
@ -126,6 +126,7 @@ func TestEncodeVideo(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// TestEncodePcm tests the mpegts encoder's ability to encode pcm audio data.
|
// TestEncodePcm tests the mpegts encoder's ability to encode pcm audio data.
|
||||||
// It reads and encodes input pcm data into mpegts, then decodes the mpegts and compares the result to the input pcm.
|
// It reads and encodes input pcm data into mpegts, then decodes the mpegts and compares the result to the input pcm.
|
||||||
|
|
|
@ -38,7 +38,7 @@ import (
|
||||||
// General mpegts packet properties.
|
// General mpegts packet properties.
|
||||||
const (
|
const (
|
||||||
PacketSize = 188
|
PacketSize = 188
|
||||||
PayloadSize = 176
|
MaxPayloadSize = 176
|
||||||
)
|
)
|
||||||
|
|
||||||
// Program ID for various types of ts packets.
|
// Program ID for various types of ts packets.
|
||||||
|
@ -194,17 +194,70 @@ func FindPid(d []byte, pid uint16) (pkt []byte, i int, err error) {
|
||||||
// FillPayload takes a channel and fills the packets Payload field until the
|
// FillPayload takes a channel and fills the packets Payload field until the
|
||||||
// channel is empty or we've the packet reaches capacity
|
// channel is empty or we've the packet reaches capacity
|
||||||
func (p *Packet) FillPayload(data []byte) int {
|
func (p *Packet) FillPayload(data []byte) int {
|
||||||
currentPktLen := 6 + asInt(p.PCRF)*6 + asInt(p.OPCRF)*6 +
|
currentPktLen := 6 + asInt(p.PCRF)*6
|
||||||
asInt(p.SPF)*1 + asInt(p.TPDF)*1 + len(p.TPD)
|
if len(data) > PacketSize-currentPktLen {
|
||||||
fmt.Printf("currentPktLen: %v\n", currentPktLen)
|
p.Payload = make([]byte, PacketSize-currentPktLen)
|
||||||
if len(data) > PayloadSize-currentPktLen {
|
|
||||||
p.Payload = make([]byte, PayloadSize-currentPktLen)
|
|
||||||
} else {
|
} else {
|
||||||
p.Payload = make([]byte, len(data))
|
p.Payload = make([]byte, len(data))
|
||||||
}
|
}
|
||||||
return copy(p.Payload, data)
|
return copy(p.Payload, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bytes interprets the fields of the ts packet instance and outputs a
|
||||||
|
// corresponding byte slice
|
||||||
|
func (p *Packet) Bytes(buf []byte) []byte {
|
||||||
|
if buf == nil || cap(buf) < PacketSize {
|
||||||
|
buf = make([]byte, PacketSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.OPCRF {
|
||||||
|
panic("original program clock reference field unsupported")
|
||||||
|
}
|
||||||
|
if p.SPF {
|
||||||
|
panic("splicing countdown unsupported")
|
||||||
|
}
|
||||||
|
if p.TPDF {
|
||||||
|
panic("transport private data unsupported")
|
||||||
|
}
|
||||||
|
if p.AFEF {
|
||||||
|
panic("adaptation field extension unsupported")
|
||||||
|
}
|
||||||
|
|
||||||
|
buf = buf[:6]
|
||||||
|
buf[0] = 0x47
|
||||||
|
buf[1] = (asByte(p.TEI)<<7 | asByte(p.PUSI)<<6 | asByte(p.Priority)<<5 | byte((p.PID&0xFF00)>>8))
|
||||||
|
buf[2] = byte(p.PID & 0x00FF)
|
||||||
|
buf[3] = (p.TSC<<6 | p.AFC<<4 | p.CC)
|
||||||
|
|
||||||
|
var maxPayloadSize int
|
||||||
|
if p.AFC & 0x2 != 0 {
|
||||||
|
maxPayloadSize = PacketSize - 6 - asInt(p.PCRF)*6
|
||||||
|
} else {
|
||||||
|
maxPayloadSize = PacketSize - 4
|
||||||
|
}
|
||||||
|
|
||||||
|
stuffingLen := maxPayloadSize -len(p.Payload)
|
||||||
|
if p.AFC & 0x2 != 0 {
|
||||||
|
buf[4] = byte(1 + stuffingLen + asInt(p.PCRF)*6)
|
||||||
|
buf[5] = (asByte(p.DI)<<7 | asByte(p.RAI)<<6 | asByte(p.ESPI)<<5 | asByte(p.PCRF)<<4 | asByte(p.OPCRF)<<3 | asByte(p.SPF)<<2 | asByte(p.TPDF)<<1 | asByte(p.AFEF))
|
||||||
|
} else {
|
||||||
|
buf = buf[:4]
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 40; p.PCRF && i >= 0; i -= 8 {
|
||||||
|
buf = append(buf, byte((p.PCR<<15)>>uint(i)))
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < stuffingLen; i++ {
|
||||||
|
buf = append(buf, 0xff)
|
||||||
|
}
|
||||||
|
curLen := len(buf)
|
||||||
|
buf = buf[:PacketSize]
|
||||||
|
copy(buf[curLen:],p.Payload)
|
||||||
|
return buf
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
func asInt(b bool) int {
|
func asInt(b bool) int {
|
||||||
if b {
|
if b {
|
||||||
return 1
|
return 1
|
||||||
|
@ -219,55 +272,6 @@ func asByte(b bool) byte {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bytes interprets the fields of the ts packet instance and outputs a
|
|
||||||
// corresponding byte slice
|
|
||||||
func (p *Packet) Bytes(buf []byte) []byte {
|
|
||||||
if buf == nil || cap(buf) != PacketSize {
|
|
||||||
buf = make([]byte, 0, PacketSize)
|
|
||||||
}
|
|
||||||
buf = buf[:0]
|
|
||||||
stuffingLength := 182 - len(p.Payload) - len(p.TPD) - asInt(p.PCRF)*6 -
|
|
||||||
asInt(p.OPCRF)*6 - asInt(p.SPF)
|
|
||||||
var stuffing []byte
|
|
||||||
if stuffingLength > 0 {
|
|
||||||
stuffing = make([]byte, stuffingLength)
|
|
||||||
}
|
|
||||||
for i := range stuffing {
|
|
||||||
stuffing[i] = 0xFF
|
|
||||||
}
|
|
||||||
afl := 1 + asInt(p.PCRF)*6 + asInt(p.OPCRF)*6 + asInt(p.SPF) + asInt(p.TPDF) + len(p.TPD) + len(stuffing)
|
|
||||||
buf = append(buf, []byte{
|
|
||||||
0x47,
|
|
||||||
(asByte(p.TEI)<<7 | asByte(p.PUSI)<<6 | asByte(p.Priority)<<5 | byte((p.PID&0xFF00)>>8)),
|
|
||||||
byte(p.PID & 0x00FF),
|
|
||||||
(p.TSC<<6 | p.AFC<<4 | p.CC),
|
|
||||||
}...)
|
|
||||||
|
|
||||||
if p.AFC == 3 || p.AFC == 2 {
|
|
||||||
buf = append(buf, []byte{
|
|
||||||
byte(afl), (asByte(p.DI)<<7 | asByte(p.RAI)<<6 | asByte(p.ESPI)<<5 |
|
|
||||||
asByte(p.PCRF)<<4 | asByte(p.OPCRF)<<3 | asByte(p.SPF)<<2 |
|
|
||||||
asByte(p.TPDF)<<1 | asByte(p.AFEF)),
|
|
||||||
}...)
|
|
||||||
for i := 40; p.PCRF && i >= 0; i -= 8 {
|
|
||||||
buf = append(buf, byte((p.PCR<<15)>>uint(i)))
|
|
||||||
}
|
|
||||||
for i := 40; p.OPCRF && i >= 0; i -= 8 {
|
|
||||||
buf = append(buf, byte(p.OPCR>>uint(i)))
|
|
||||||
}
|
|
||||||
if p.SPF {
|
|
||||||
buf = append(buf, p.SC)
|
|
||||||
}
|
|
||||||
if p.TPDF {
|
|
||||||
buf = append(buf, append([]byte{p.TPDL}, p.TPD...)...)
|
|
||||||
}
|
|
||||||
buf = append(buf, p.Ext...)
|
|
||||||
buf = append(buf, stuffing...)
|
|
||||||
}
|
|
||||||
buf = append(buf, p.Payload...)
|
|
||||||
return buf
|
|
||||||
}
|
|
||||||
|
|
||||||
type Option func(p *packet.Packet)
|
type Option func(p *packet.Packet)
|
||||||
|
|
||||||
// addAdaptationField adds an adaptation field to p, and applys the passed options to this field.
|
// addAdaptationField adds an adaptation field to p, and applys the passed options to this field.
|
||||||
|
|
Loading…
Reference in New Issue