mirror of
				https://github.com/ossrs/srs.git
				synced 2025-03-09 15:49:59 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			98 lines
		
	
	
	
		
			2.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			98 lines
		
	
	
	
		
			2.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package rtp
 | 
						|
 | 
						|
import (
 | 
						|
	"time"
 | 
						|
)
 | 
						|
 | 
						|
// Payloader payloads a byte array for use as rtp.Packet payloads
 | 
						|
type Payloader interface {
 | 
						|
	Payload(mtu uint16, payload []byte) [][]byte
 | 
						|
}
 | 
						|
 | 
						|
// Packetizer packetizes a payload
 | 
						|
type Packetizer interface {
 | 
						|
	Packetize(payload []byte, 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 { // put extension numbers in here. If they're 0, the extension is disabled (0 is not a legal extension number)
 | 
						|
		AbsSendTime int // http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
 | 
						|
	}
 | 
						|
	timegen func() time.Time
 | 
						|
}
 | 
						|
 | 
						|
// NewPacketizer returns a new instance of a Packetizer for a specific payloader
 | 
						|
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 (p *packetizer) EnableAbsSendTime(value int) {
 | 
						|
	p.extensionNumbers.AbsSendTime = value
 | 
						|
}
 | 
						|
 | 
						|
// Packetize packetizes the payload of an RTP packet and returns one or more RTP packets
 | 
						|
func (p *packetizer) Packetize(payload []byte, samples uint32) []*Packet {
 | 
						|
	// Guard against an empty payload
 | 
						|
	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, // Figure out how to do timestamps
 | 
						|
				SSRC:           p.SSRC,
 | 
						|
			},
 | 
						|
			Payload: pp,
 | 
						|
		}
 | 
						|
	}
 | 
						|
	p.Timestamp += samples
 | 
						|
 | 
						|
	if len(packets) != 0 && p.extensionNumbers.AbsSendTime != 0 {
 | 
						|
		sendTime := NewAbsSendTimeExtension(p.timegen())
 | 
						|
		// apply http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
 | 
						|
		b, err := sendTime.Marshal()
 | 
						|
		if err != nil {
 | 
						|
			return nil // never happens
 | 
						|
		}
 | 
						|
		err = packets[len(packets)-1].SetExtension(uint8(p.extensionNumbers.AbsSendTime), b)
 | 
						|
		if err != nil {
 | 
						|
			return nil // never happens
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return packets
 | 
						|
}
 | 
						|
 | 
						|
// SkipSamples causes a gap in sample count between Packetize requests so the
 | 
						|
// RTP payloads produced have a gap in timestamps
 | 
						|
func (p *packetizer) SkipSamples(skippedSamples uint32) {
 | 
						|
	p.Timestamp += skippedSamples
 | 
						|
}
 |