packet.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. // SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
  2. // SPDX-License-Identifier: MIT
  3. package rtcp
  4. // Packet represents an RTCP packet, a protocol used for out-of-band statistics and control information for an RTP session
  5. type Packet interface {
  6. // DestinationSSRC returns an array of SSRC values that this packet refers to.
  7. DestinationSSRC() []uint32
  8. Marshal() ([]byte, error)
  9. Unmarshal(rawPacket []byte) error
  10. }
  11. // Unmarshal takes an entire udp datagram (which may consist of multiple RTCP packets) and
  12. // returns the unmarshaled packets it contains.
  13. //
  14. // If this is a reduced-size RTCP packet a feedback packet (Goodbye, SliceLossIndication, etc)
  15. // will be returned. Otherwise, the underlying type of the returned packet will be
  16. // CompoundPacket.
  17. func Unmarshal(rawData []byte) ([]Packet, error) {
  18. var packets []Packet
  19. for len(rawData) != 0 {
  20. p, processed, err := unmarshal(rawData)
  21. if err != nil {
  22. return nil, err
  23. }
  24. packets = append(packets, p)
  25. rawData = rawData[processed:]
  26. }
  27. switch len(packets) {
  28. // Empty packet
  29. case 0:
  30. return nil, errInvalidHeader
  31. // Multiple Packets
  32. default:
  33. return packets, nil
  34. }
  35. }
  36. // Marshal takes an array of Packets and serializes them to a single buffer
  37. func Marshal(packets []Packet) ([]byte, error) {
  38. out := make([]byte, 0)
  39. for _, p := range packets {
  40. data, err := p.Marshal()
  41. if err != nil {
  42. return nil, err
  43. }
  44. out = append(out, data...)
  45. }
  46. return out, nil
  47. }
  48. // unmarshal is a factory which pulls the first RTCP packet from a bytestream,
  49. // and returns it's parsed representation, and the amount of data that was processed.
  50. func unmarshal(rawData []byte) (packet Packet, bytesprocessed int, err error) {
  51. var h Header
  52. err = h.Unmarshal(rawData)
  53. if err != nil {
  54. return nil, 0, err
  55. }
  56. bytesprocessed = int(h.Length+1) * 4
  57. if bytesprocessed > len(rawData) {
  58. return nil, 0, errPacketTooShort
  59. }
  60. inPacket := rawData[:bytesprocessed]
  61. switch h.Type {
  62. case TypeSenderReport:
  63. packet = new(SenderReport)
  64. case TypeReceiverReport:
  65. packet = new(ReceiverReport)
  66. case TypeSourceDescription:
  67. packet = new(SourceDescription)
  68. case TypeGoodbye:
  69. packet = new(Goodbye)
  70. case TypeTransportSpecificFeedback:
  71. switch h.Count {
  72. case FormatTLN:
  73. packet = new(TransportLayerNack)
  74. case FormatRRR:
  75. packet = new(RapidResynchronizationRequest)
  76. case FormatTCC:
  77. packet = new(TransportLayerCC)
  78. case FormatCCFB:
  79. packet = new(CCFeedbackReport)
  80. default:
  81. packet = new(RawPacket)
  82. }
  83. case TypePayloadSpecificFeedback:
  84. switch h.Count {
  85. case FormatPLI:
  86. packet = new(PictureLossIndication)
  87. case FormatSLI:
  88. packet = new(SliceLossIndication)
  89. case FormatREMB:
  90. packet = new(ReceiverEstimatedMaximumBitrate)
  91. case FormatFIR:
  92. packet = new(FullIntraRequest)
  93. default:
  94. packet = new(RawPacket)
  95. }
  96. case TypeExtendedReport:
  97. packet = new(ExtendedReport)
  98. default:
  99. packet = new(RawPacket)
  100. }
  101. err = packet.Unmarshal(inPacket)
  102. return packet, bytesprocessed, err
  103. }