header.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. package rtcp
  2. import (
  3. "encoding/binary"
  4. )
  5. // PacketType specifies the type of an RTCP packet
  6. type PacketType uint8
  7. // RTCP packet types registered with IANA. See: https://www.iana.org/assignments/rtp-parameters/rtp-parameters.xhtml#rtp-parameters-4
  8. const (
  9. TypeSenderReport PacketType = 200 // RFC 3550, 6.4.1
  10. TypeReceiverReport PacketType = 201 // RFC 3550, 6.4.2
  11. TypeSourceDescription PacketType = 202 // RFC 3550, 6.5
  12. TypeGoodbye PacketType = 203 // RFC 3550, 6.6
  13. TypeApplicationDefined PacketType = 204 // RFC 3550, 6.7 (unimplemented)
  14. TypeTransportSpecificFeedback PacketType = 205 // RFC 4585, 6051
  15. TypePayloadSpecificFeedback PacketType = 206 // RFC 4585, 6.3
  16. TypeExtendedReport PacketType = 207 // RFC 3611
  17. )
  18. // Transport and Payload specific feedback messages overload the count field to act as a message type. those are listed here
  19. const (
  20. FormatSLI uint8 = 2
  21. FormatPLI uint8 = 1
  22. FormatFIR uint8 = 4
  23. FormatTLN uint8 = 1
  24. FormatRRR uint8 = 5
  25. FormatREMB uint8 = 15
  26. // https://tools.ietf.org/html/draft-holmer-rmcat-transport-wide-cc-extensions-01#page-5
  27. FormatTCC uint8 = 15
  28. )
  29. func (p PacketType) String() string {
  30. switch p {
  31. case TypeSenderReport:
  32. return "SR"
  33. case TypeReceiverReport:
  34. return "RR"
  35. case TypeSourceDescription:
  36. return "SDES"
  37. case TypeGoodbye:
  38. return "BYE"
  39. case TypeApplicationDefined:
  40. return "APP"
  41. case TypeTransportSpecificFeedback:
  42. return "TSFB"
  43. case TypePayloadSpecificFeedback:
  44. return "PSFB"
  45. case TypeExtendedReport:
  46. return "XR"
  47. default:
  48. return string(p)
  49. }
  50. }
  51. const rtpVersion = 2
  52. // A Header is the common header shared by all RTCP packets
  53. type Header struct {
  54. // If the padding bit is set, this individual RTCP packet contains
  55. // some additional padding octets at the end which are not part of
  56. // the control information but are included in the length field.
  57. Padding bool
  58. // The number of reception reports, sources contained or FMT in this packet (depending on the Type)
  59. Count uint8
  60. // The RTCP packet type for this packet
  61. Type PacketType
  62. // The length of this RTCP packet in 32-bit words minus one,
  63. // including the header and any padding.
  64. Length uint16
  65. }
  66. const (
  67. headerLength = 4
  68. versionShift = 6
  69. versionMask = 0x3
  70. paddingShift = 5
  71. paddingMask = 0x1
  72. countShift = 0
  73. countMask = 0x1f
  74. countMax = (1 << 5) - 1
  75. )
  76. // Marshal encodes the Header in binary
  77. func (h Header) Marshal() ([]byte, error) {
  78. /*
  79. * 0 1 2 3
  80. * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  81. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  82. * |V=2|P| RC | PT=SR=200 | length |
  83. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  84. */
  85. rawPacket := make([]byte, headerLength)
  86. rawPacket[0] |= rtpVersion << versionShift
  87. if h.Padding {
  88. rawPacket[0] |= 1 << paddingShift
  89. }
  90. if h.Count > 31 {
  91. return nil, errInvalidHeader
  92. }
  93. rawPacket[0] |= h.Count << countShift
  94. rawPacket[1] = uint8(h.Type)
  95. binary.BigEndian.PutUint16(rawPacket[2:], h.Length)
  96. return rawPacket, nil
  97. }
  98. // Unmarshal decodes the Header from binary
  99. func (h *Header) Unmarshal(rawPacket []byte) error {
  100. if len(rawPacket) < headerLength {
  101. return errPacketTooShort
  102. }
  103. /*
  104. * 0 1 2 3
  105. * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  106. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  107. * |V=2|P| RC | PT | length |
  108. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  109. */
  110. version := rawPacket[0] >> versionShift & versionMask
  111. if version != rtpVersion {
  112. return errBadVersion
  113. }
  114. h.Padding = (rawPacket[0] >> paddingShift & paddingMask) > 0
  115. h.Count = rawPacket[0] >> countShift & countMask
  116. h.Type = PacketType(rawPacket[1])
  117. h.Length = binary.BigEndian.Uint16(rawPacket[2:])
  118. return nil
  119. }