package rtp
import (
"time"
)
type Payloader interface {
Payload (mtu uint16 , payload []byte ) [][]byte
}
type Packetizer interface {
Packetize (payload []byte , samples uint32 ) []*Packet
GeneratePadding (samples uint32 ) []*Packet
EnableAbsSendTime (value int )
SkipSamples (skippedSamples uint32 )
}
type packetizer struct {
MTU uint16
PayloadType uint8
SSRC uint32
Payloader Payloader
Sequencer Sequencer
Timestamp uint32
ClockRate uint32
extensionNumbers struct {
AbsSendTime int
}
timegen func () time .Time
}
func NewPacketizer (
mtu uint16 ,
pt uint8 ,
ssrc uint32 ,
payloader Payloader ,
sequencer Sequencer ,
clockRate uint32 ,
) Packetizer {
return &packetizer {
MTU : mtu ,
PayloadType : pt ,
SSRC : ssrc ,
Payloader : payloader ,
Sequencer : sequencer ,
Timestamp : globalMathRandomGenerator .Uint32 (),
ClockRate : clockRate ,
timegen : time .Now ,
}
}
func WithSSRC (ssrc uint32 ) func (*packetizer ) {
return func (p *packetizer ) {
p .SSRC = ssrc
}
}
func WithPayloadType (pt uint8 ) func (*packetizer ) {
return func (p *packetizer ) {
p .PayloadType = pt
}
}
func WithTimestamp (timestamp uint32 ) func (*packetizer ) {
return func (p *packetizer ) {
p .Timestamp = timestamp
}
}
type PacketizerOption func (*packetizer )
func NewPacketizerWithOptions (
mtu uint16 ,
payloader Payloader ,
sequencer Sequencer ,
clockRate uint32 ,
options ...PacketizerOption ,
) Packetizer {
packetizerInstance := &packetizer {
MTU : mtu ,
Payloader : payloader ,
Sequencer : sequencer ,
Timestamp : globalMathRandomGenerator .Uint32 (),
ClockRate : clockRate ,
timegen : time .Now ,
}
for _ , option := range options {
option (packetizerInstance )
}
return packetizerInstance
}
func (p *packetizer ) EnableAbsSendTime (value int ) {
p .extensionNumbers .AbsSendTime = value
}
func (p *packetizer ) Packetize (payload []byte , samples uint32 ) []*Packet {
if len (payload ) == 0 {
return nil
}
payloads := p .Payloader .Payload (p .MTU -12 , payload )
packets := make ([]*Packet , len (payloads ))
for i , pp := range payloads {
packets [i ] = &Packet {
Header : Header {
Version : 2 ,
Padding : false ,
Extension : false ,
Marker : i == len (payloads )-1 ,
PayloadType : p .PayloadType ,
SequenceNumber : p .Sequencer .NextSequenceNumber (),
Timestamp : p .Timestamp ,
SSRC : p .SSRC ,
CSRC : []uint32 {},
},
Payload : pp ,
}
}
p .Timestamp += samples
if len (packets ) != 0 && p .extensionNumbers .AbsSendTime != 0 {
sendTime := NewAbsSendTimeExtension (p .timegen ())
b , err := sendTime .Marshal ()
if err != nil {
return nil
}
err = packets [len (packets )-1 ].SetExtension (uint8 (p .extensionNumbers .AbsSendTime ), b )
if err != nil {
return nil
}
}
return packets
}
func (p *packetizer ) GeneratePadding (samples uint32 ) []*Packet {
if samples == 0 {
return nil
}
packets := make ([]*Packet , samples )
for i := 0 ; i < int (samples ); i ++ {
packets [i ] = &Packet {
Header : Header {
Version : 2 ,
Padding : true ,
Extension : false ,
Marker : false ,
PayloadType : p .PayloadType ,
SequenceNumber : p .Sequencer .NextSequenceNumber (),
Timestamp : p .Timestamp ,
SSRC : p .SSRC ,
CSRC : []uint32 {},
PaddingSize : 255 ,
},
}
}
return packets
}
func (p *packetizer ) SkipSamples (skippedSamples uint32 ) {
p .Timestamp += skippedSamples
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .