packet.go 2.8 KB

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