mirror of https://bitbucket.org/ausocean/av.git
rtp: started writing encoder for rtp. Needto work out what the packet type part of the header should be
This commit is contained in:
parent
1a15889522
commit
ddf25e1fbe
|
@ -26,3 +26,78 @@ LICENSE
|
|||
*/
|
||||
|
||||
package rtp
|
||||
|
||||
import (
|
||||
"io"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Time related constants.
|
||||
const (
|
||||
rtpVer = 2
|
||||
yes = 1
|
||||
no = 0
|
||||
ccCount = 0
|
||||
// pcrFreq is the base Program Clock Reference frequency.
|
||||
timestampFreq = 90000 // Hz
|
||||
)
|
||||
|
||||
type Encoder struct {
|
||||
dst io.Writer
|
||||
|
||||
clock time.Duration
|
||||
frameInterval time.Duration
|
||||
}
|
||||
|
||||
// NewEncoder returns an Encoder with the specified frame rate.
|
||||
func NewEncoder(dst io.Writer, fps float64) *Encoder {
|
||||
return &Encoder{
|
||||
dst: dst,
|
||||
frameInterval: time.Duration(float64(time.Second) / fps),
|
||||
}
|
||||
}
|
||||
|
||||
func (e *Encoder) Encode(nalu []byte) error {
|
||||
pkt := Pkt{
|
||||
Pkt{
|
||||
V: rtpVer, // version
|
||||
P: no, // padding
|
||||
X: no, // header extension
|
||||
CC: ccCount,
|
||||
M: no, // NOTE: need to check if this works (decoders should ignore this)
|
||||
PT: 6,
|
||||
SN: 167,
|
||||
TS: 160,
|
||||
SSRC: 10,
|
||||
Payload: []byte{0x00, 0x01, 0x07, 0xf0, 0x56, 0x37, 0x0a, 0x0f},
|
||||
Padding: 0,
|
||||
},
|
||||
}
|
||||
// Write rtp packet to
|
||||
_, err := e.dst.Write(pkt.Bytes())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
e.tick()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// tick advances the clock one frame interval.
|
||||
func (e *Encoder) tick() {
|
||||
e.clock += e.frameInterval
|
||||
}
|
||||
|
||||
// TODO: alter and make this work for rtp
|
||||
func (e *Encoder) pts() uint64 {
|
||||
return uint64((e.clock + e.ptsOffset).Seconds() * pcrFreq)
|
||||
}
|
||||
|
||||
// TODO: alter and apply this to rtp for sequence number
|
||||
func (e *Encoder) ccFor(pid int) byte {
|
||||
cc := e.continuity[pid]
|
||||
const continuityCounterMask = 0xf
|
||||
e.continuity[pid] = (cc + 1) & continuityCounterMask
|
||||
return cc
|
||||
}
|
||||
|
|
|
@ -31,8 +31,7 @@ LICENSE
|
|||
package rtp
|
||||
|
||||
const (
|
||||
rtpVer = 2
|
||||
defaultHeadSize = 3 * 4 // bytes
|
||||
rtpVer = 2
|
||||
)
|
||||
|
||||
type Pkt struct {
|
||||
|
@ -72,25 +71,22 @@ func (p *Pkt) Bytes() []byte {
|
|||
panic("rtp: CC (CSRC count) not 0, but CSRC headers not yet supported!")
|
||||
}
|
||||
|
||||
buf := make([]byte, defaultHeadSize, defaultHeadSize+len(p.Payload)+p.Padding)
|
||||
const headSize = 3 * 4 // bytes
|
||||
buf := make([]byte, headSize, headSize+len(p.Payload)+p.Padding)
|
||||
|
||||
// First 4 bytes
|
||||
buf[0] |= p.V<<6 | p.P<<5 | p.CC
|
||||
buf[1] |= p.M<<7 | p.PT
|
||||
buf[2] |= byte(p.SN >> 8)
|
||||
buf[3] |= byte(p.SN)
|
||||
// Second lot of 4 bytes
|
||||
buf[4] |= byte(p.TS >> 24)
|
||||
buf[5] |= byte(p.TS >> 16)
|
||||
buf[6] |= byte(p.TS >> 8)
|
||||
buf[7] |= byte(p.TS)
|
||||
// Third lot of 4 bytes
|
||||
buf[8] |= byte(p.SSRC >> 24)
|
||||
buf[9] |= byte(p.SSRC >> 16)
|
||||
buf[10] |= byte(p.SSRC >> 8)
|
||||
buf[11] |= byte(p.SSRC)
|
||||
|
||||
// Add payload and padding
|
||||
buf = append(buf, p.Payload...)
|
||||
if p.Padding != 0 {
|
||||
buf = append(buf, append(make([]byte, p.Padding-1, p.Padding), byte(p.Padding))...)
|
||||
|
|
|
@ -32,6 +32,7 @@ import (
|
|||
"testing"
|
||||
)
|
||||
|
||||
// TODO (saxon): add more tests
|
||||
var rtpTests = []struct {
|
||||
num int
|
||||
pkt Pkt
|
||||
|
@ -66,7 +67,8 @@ func TestRtpPktToByteSlice(t *testing.T) {
|
|||
for _, test := range rtpTests {
|
||||
got := test.pkt.Bytes()
|
||||
if !reflect.DeepEqual(got, test.want) {
|
||||
t.Errorf("unexpected error for test %v: got:%v want:%v", test.num, got, test.want)
|
||||
t.Errorf("unexpected error for test %v: got:%v want:%v", test.num, got,
|
||||
test.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue