mirror of https://bitbucket.org/ausocean/av.git
Merged in improve-rtp-encoder-performance (pull request #84)
Improve rtp encoder performance Approved-by: Alan Noble <anoble@gmail.com> Approved-by: kortschak <dan@kortschak.io>
This commit is contained in:
commit
a3fec17cb4
|
@ -40,7 +40,7 @@ const (
|
||||||
timestampFreq = 90000 // Hz
|
timestampFreq = 90000 // Hz
|
||||||
mtsSize = 188
|
mtsSize = 188
|
||||||
bufferSize = 1000
|
bufferSize = 1000
|
||||||
sendLength = 7 * 188
|
sendLen = 7 * 188
|
||||||
)
|
)
|
||||||
|
|
||||||
// Encoder implements io writer and provides functionality to wrap data into
|
// Encoder implements io writer and provides functionality to wrap data into
|
||||||
|
@ -53,6 +53,7 @@ type Encoder struct {
|
||||||
frameInterval time.Duration
|
frameInterval time.Duration
|
||||||
fps int
|
fps int
|
||||||
buffer []byte
|
buffer []byte
|
||||||
|
pktSpace [defPktSize]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewEncoder returns a new Encoder type given an io.Writer - the destination
|
// NewEncoder returns a new Encoder type given an io.Writer - the destination
|
||||||
|
@ -71,9 +72,9 @@ func NewEncoder(dst io.Writer, fps int) *Encoder {
|
||||||
// so that multiple layers of packetization can occur.
|
// so that multiple layers of packetization can occur.
|
||||||
func (e *Encoder) Write(data []byte) (int, error) {
|
func (e *Encoder) Write(data []byte) (int, error) {
|
||||||
e.buffer = append(e.buffer, data...)
|
e.buffer = append(e.buffer, data...)
|
||||||
for len(e.buffer) >= sendLength {
|
for len(e.buffer) >= sendLen {
|
||||||
e.Encode(e.buffer[:sendLength])
|
e.Encode(e.buffer[:sendLen])
|
||||||
e.buffer = e.buffer[sendLength:]
|
e.buffer = e.buffer[sendLen:]
|
||||||
}
|
}
|
||||||
return len(data), nil
|
return len(data), nil
|
||||||
}
|
}
|
||||||
|
@ -93,7 +94,7 @@ func (e *Encoder) Encode(payload []byte) error {
|
||||||
Payload: payload,
|
Payload: payload,
|
||||||
Padding: no,
|
Padding: no,
|
||||||
}
|
}
|
||||||
_, err := e.dst.Write(pkt.Bytes())
|
_, err := e.dst.Write(pkt.Bytes(e.pktSpace[:defPktSize]))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,9 @@ package rtp
|
||||||
|
|
||||||
const (
|
const (
|
||||||
rtpVer = 2
|
rtpVer = 2
|
||||||
|
headSize = 3 * 4 // Header size of an rtp packet.
|
||||||
|
defPayloadSize = sendLen // Default payload size for the rtp packet.
|
||||||
|
defPktSize = headSize + defPayloadSize // Default packet size is header size + payload size.
|
||||||
)
|
)
|
||||||
|
|
||||||
// Pkt provides fields consistent with RFC3550 definition of an rtp packet
|
// Pkt provides fields consistent with RFC3550 definition of an rtp packet
|
||||||
|
@ -53,7 +56,11 @@ type Pkt struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bytes provides a byte slice of the packet
|
// Bytes provides a byte slice of the packet
|
||||||
func (p *Pkt) Bytes() []byte {
|
func (p *Pkt) Bytes(buf []byte) []byte {
|
||||||
|
if buf == nil || len(buf) != defPktSize {
|
||||||
|
buf = make([]byte, headSize, defPktSize)
|
||||||
|
}
|
||||||
|
buf = buf[:headSize]
|
||||||
if p.V == 0 {
|
if p.V == 0 {
|
||||||
p.V = rtpVer
|
p.V = rtpVer
|
||||||
}
|
}
|
||||||
|
@ -74,9 +81,6 @@ func (p *Pkt) Bytes() []byte {
|
||||||
panic("rtp: CC (CSRC count) not 0, but CSRC headers not yet supported.")
|
panic("rtp: CC (CSRC count) not 0, but CSRC headers not yet supported.")
|
||||||
}
|
}
|
||||||
|
|
||||||
const headSize = 3 * 4 // bytes
|
|
||||||
buf := make([]byte, headSize, headSize+len(p.Payload)+int(p.Padding))
|
|
||||||
|
|
||||||
buf[0] = p.V<<6 | p.p<<5 | p.CC
|
buf[0] = p.V<<6 | p.p<<5 | p.CC
|
||||||
buf[1] = p.M<<7 | p.PT
|
buf[1] = p.M<<7 | p.PT
|
||||||
buf[2] = byte(p.SN >> 8)
|
buf[2] = byte(p.SN >> 8)
|
||||||
|
|
|
@ -65,7 +65,7 @@ var rtpTests = []struct {
|
||||||
|
|
||||||
func TestRtpPktToByteSlice(t *testing.T) {
|
func TestRtpPktToByteSlice(t *testing.T) {
|
||||||
for _, test := range rtpTests {
|
for _, test := range rtpTests {
|
||||||
got := test.pkt.Bytes()
|
got := test.pkt.Bytes(nil)
|
||||||
if !reflect.DeepEqual(got, test.want) {
|
if !reflect.DeepEqual(got, test.want) {
|
||||||
t.Errorf("unexpected error for test %v: got:%v want:%v", test.num, got,
|
t.Errorf("unexpected error for test %v: got:%v want:%v", test.num, got,
|
||||||
test.want)
|
test.want)
|
||||||
|
|
Loading…
Reference in New Issue