packetizer.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  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. GeneratePadding(samples uint32) []*Packet
  15. EnableAbsSendTime(value int)
  16. SkipSamples(skippedSamples uint32)
  17. }
  18. type packetizer struct {
  19. MTU uint16
  20. PayloadType uint8
  21. SSRC uint32
  22. Payloader Payloader
  23. Sequencer Sequencer
  24. Timestamp uint32
  25. // Deprecated: will be removed in a future version.
  26. ClockRate uint32
  27. extensionNumbers struct { // put extension numbers in here. If they're 0, the extension is disabled (0 is not a legal extension number)
  28. AbsSendTime int // http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
  29. }
  30. timegen func() time.Time
  31. }
  32. // NewPacketizer returns a new instance of a Packetizer for a specific payloader
  33. func NewPacketizer(mtu uint16, pt uint8, ssrc uint32, payloader Payloader, sequencer Sequencer, clockRate uint32) Packetizer {
  34. return &packetizer{
  35. MTU: mtu,
  36. PayloadType: pt,
  37. SSRC: ssrc,
  38. Payloader: payloader,
  39. Sequencer: sequencer,
  40. Timestamp: globalMathRandomGenerator.Uint32(),
  41. ClockRate: clockRate,
  42. timegen: time.Now,
  43. }
  44. }
  45. func (p *packetizer) EnableAbsSendTime(value int) {
  46. p.extensionNumbers.AbsSendTime = value
  47. }
  48. // Packetize packetizes the payload of an RTP packet and returns one or more RTP packets
  49. func (p *packetizer) Packetize(payload []byte, samples uint32) []*Packet {
  50. // Guard against an empty payload
  51. if len(payload) == 0 {
  52. return nil
  53. }
  54. payloads := p.Payloader.Payload(p.MTU-12, payload)
  55. packets := make([]*Packet, len(payloads))
  56. for i, pp := range payloads {
  57. packets[i] = &Packet{
  58. Header: Header{
  59. Version: 2,
  60. Padding: false,
  61. Extension: false,
  62. Marker: i == len(payloads)-1,
  63. PayloadType: p.PayloadType,
  64. SequenceNumber: p.Sequencer.NextSequenceNumber(),
  65. Timestamp: p.Timestamp, // Figure out how to do timestamps
  66. SSRC: p.SSRC,
  67. CSRC: []uint32{},
  68. },
  69. Payload: pp,
  70. }
  71. }
  72. p.Timestamp += samples
  73. if len(packets) != 0 && p.extensionNumbers.AbsSendTime != 0 {
  74. sendTime := NewAbsSendTimeExtension(p.timegen())
  75. // apply http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
  76. b, err := sendTime.Marshal()
  77. if err != nil {
  78. return nil // never happens
  79. }
  80. err = packets[len(packets)-1].SetExtension(uint8(p.extensionNumbers.AbsSendTime), b)
  81. if err != nil {
  82. return nil // never happens
  83. }
  84. }
  85. return packets
  86. }
  87. // GeneratePadding returns required padding-only packages
  88. func (p *packetizer) GeneratePadding(samples uint32) []*Packet {
  89. // Guard against an empty payload
  90. if samples == 0 {
  91. return nil
  92. }
  93. packets := make([]*Packet, samples)
  94. for i := 0; i < int(samples); i++ {
  95. pp := make([]byte, 255)
  96. pp[254] = 255
  97. packets[i] = &Packet{
  98. Header: Header{
  99. Version: 2,
  100. Padding: true,
  101. Extension: false,
  102. Marker: false,
  103. PayloadType: p.PayloadType,
  104. SequenceNumber: p.Sequencer.NextSequenceNumber(),
  105. Timestamp: p.Timestamp, // Use latest timestamp
  106. SSRC: p.SSRC,
  107. CSRC: []uint32{},
  108. },
  109. Payload: pp,
  110. }
  111. }
  112. return packets
  113. }
  114. // SkipSamples causes a gap in sample count between Packetize requests so the
  115. // RTP payloads produced have a gap in timestamps
  116. func (p *packetizer) SkipSamples(skippedSamples uint32) {
  117. p.Timestamp += skippedSamples
  118. }