packetizer.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. // SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
  2. // SPDX-License-Identifier: MIT
  3. package rtp
  4. import (
  5. "time"
  6. )
  7. // Payloader payloads a byte array for use as rtp.Packet payloads
  8. type Payloader interface {
  9. Payload(mtu uint16, payload []byte) [][]byte
  10. }
  11. // Packetizer packetizes a payload
  12. type Packetizer interface {
  13. Packetize(payload []byte, samples uint32) []*Packet
  14. EnableAbsSendTime(value int)
  15. SkipSamples(skippedSamples uint32)
  16. }
  17. type packetizer struct {
  18. MTU uint16
  19. PayloadType uint8
  20. SSRC uint32
  21. Payloader Payloader
  22. Sequencer Sequencer
  23. Timestamp uint32
  24. // Deprecated: will be removed in a future version.
  25. ClockRate uint32
  26. extensionNumbers struct { // put extension numbers in here. If they're 0, the extension is disabled (0 is not a legal extension number)
  27. AbsSendTime int // http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
  28. }
  29. timegen func() time.Time
  30. }
  31. // NewPacketizer returns a new instance of a Packetizer for a specific payloader
  32. func NewPacketizer(mtu uint16, pt uint8, ssrc uint32, payloader Payloader, sequencer Sequencer, clockRate uint32) Packetizer {
  33. return &packetizer{
  34. MTU: mtu,
  35. PayloadType: pt,
  36. SSRC: ssrc,
  37. Payloader: payloader,
  38. Sequencer: sequencer,
  39. Timestamp: globalMathRandomGenerator.Uint32(),
  40. ClockRate: clockRate,
  41. timegen: time.Now,
  42. }
  43. }
  44. func (p *packetizer) EnableAbsSendTime(value int) {
  45. p.extensionNumbers.AbsSendTime = value
  46. }
  47. // Packetize packetizes the payload of an RTP packet and returns one or more RTP packets
  48. func (p *packetizer) Packetize(payload []byte, samples uint32) []*Packet {
  49. // Guard against an empty payload
  50. if len(payload) == 0 {
  51. return nil
  52. }
  53. payloads := p.Payloader.Payload(p.MTU-12, payload)
  54. packets := make([]*Packet, len(payloads))
  55. for i, pp := range payloads {
  56. packets[i] = &Packet{
  57. Header: Header{
  58. Version: 2,
  59. Padding: false,
  60. Extension: false,
  61. Marker: i == len(payloads)-1,
  62. PayloadType: p.PayloadType,
  63. SequenceNumber: p.Sequencer.NextSequenceNumber(),
  64. Timestamp: p.Timestamp, // Figure out how to do timestamps
  65. SSRC: p.SSRC,
  66. CSRC: []uint32{},
  67. },
  68. Payload: pp,
  69. }
  70. }
  71. p.Timestamp += samples
  72. if len(packets) != 0 && p.extensionNumbers.AbsSendTime != 0 {
  73. sendTime := NewAbsSendTimeExtension(p.timegen())
  74. // apply http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
  75. b, err := sendTime.Marshal()
  76. if err != nil {
  77. return nil // never happens
  78. }
  79. err = packets[len(packets)-1].SetExtension(uint8(p.extensionNumbers.AbsSendTime), b)
  80. if err != nil {
  81. return nil // never happens
  82. }
  83. }
  84. return packets
  85. }
  86. // SkipSamples causes a gap in sample count between Packetize requests so the
  87. // RTP payloads produced have a gap in timestamps
  88. func (p *packetizer) SkipSamples(skippedSamples uint32) {
  89. p.Timestamp += skippedSamples
  90. }