package rtpbuffer
import (
"encoding/binary"
"io"
"sync"
"github.com/pion/rtp"
)
const rtxSsrcByteLength = 2
type PacketFactory interface {
NewPacket (header *rtp .Header , payload []byte , rtxSsrc uint32 , rtxPayloadType uint8 ) (*RetainablePacket , error )
}
type PacketFactoryCopy struct {
headerPool *sync .Pool
payloadPool *sync .Pool
rtxSequencer rtp .Sequencer
}
func NewPacketFactoryCopy () *PacketFactoryCopy {
return &PacketFactoryCopy {
headerPool : &sync .Pool {
New : func () interface {} {
return &rtp .Header {}
},
},
payloadPool : &sync .Pool {
New : func () interface {} {
buf := make ([]byte , maxPayloadLen )
return &buf
},
},
rtxSequencer : rtp .NewRandomSequencer (),
}
}
func (m *PacketFactoryCopy ) NewPacket (
header *rtp .Header , payload []byte , rtxSsrc uint32 , rtxPayloadType uint8 ,
) (*RetainablePacket , error ) {
if len (payload ) > maxPayloadLen {
return nil , io .ErrShortBuffer
}
retainablePacket := &RetainablePacket {
onRelease : m .releasePacket ,
sequenceNumber : header .SequenceNumber ,
count : 1 ,
}
var ok bool
retainablePacket .header , ok = m .headerPool .Get ().(*rtp .Header )
if !ok {
return nil , errFailedToCastHeaderPool
}
*retainablePacket .header = header .Clone ()
if payload != nil {
retainablePacket .buffer , ok = m .payloadPool .Get ().(*[]byte )
if !ok {
return nil , errFailedToCastPayloadPool
}
if rtxSsrc != 0 && rtxPayloadType != 0 {
size := copy ((*retainablePacket .buffer )[rtxSsrcByteLength :], payload )
retainablePacket .payload = (*retainablePacket .buffer )[:size +rtxSsrcByteLength ]
} else {
size := copy (*retainablePacket .buffer , payload )
retainablePacket .payload = (*retainablePacket .buffer )[:size ]
}
}
if rtxSsrc != 0 && rtxPayloadType != 0 {
if payload == nil {
retainablePacket .buffer , ok = m .payloadPool .Get ().(*[]byte )
if !ok {
return nil , errFailedToCastPayloadPool
}
retainablePacket .payload = (*retainablePacket .buffer )[:rtxSsrcByteLength ]
}
binary .BigEndian .PutUint16 (retainablePacket .payload , retainablePacket .header .SequenceNumber )
retainablePacket .header .SSRC = rtxSsrc
retainablePacket .header .PayloadType = rtxPayloadType
retainablePacket .header .SequenceNumber = m .rtxSequencer .NextSequenceNumber ()
if retainablePacket .header .Padding {
if retainablePacket .header .PaddingSize == 0 && len (retainablePacket .payload ) > 0 {
paddingLength := int (retainablePacket .payload [len (retainablePacket .payload )-1 ])
if paddingLength > len (retainablePacket .payload ) {
return nil , errPaddingOverflow
}
retainablePacket .payload = (*retainablePacket .buffer )[:len (retainablePacket .payload )-paddingLength ]
}
retainablePacket .header .Padding = false
retainablePacket .header .PaddingSize = 0
}
}
return retainablePacket , nil
}
func (m *PacketFactoryCopy ) releasePacket (header *rtp .Header , payload *[]byte ) {
m .headerPool .Put (header )
if payload != nil {
m .payloadPool .Put (payload )
}
}
type PacketFactoryNoOp struct {}
func (f *PacketFactoryNoOp ) NewPacket (
header *rtp .Header , payload []byte , _ uint32 , _ uint8 ,
) (*RetainablePacket , error ) {
return &RetainablePacket {
onRelease : f .releasePacket ,
count : 1 ,
header : header ,
payload : payload ,
sequenceNumber : header .SequenceNumber ,
}, nil
}
func (f *PacketFactoryNoOp ) releasePacket (_ *rtp .Header , _ *[]byte ) {
}
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 .