header.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  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. FormatCCFB uint8 = 11
  26. FormatREMB uint8 = 15
  27. // https://tools.ietf.org/html/draft-holmer-rmcat-transport-wide-cc-extensions-01#page-5
  28. FormatTCC uint8 = 15
  29. )
  30. func (p PacketType) String() string {
  31. switch p {
  32. case TypeSenderReport:
  33. return "SR"
  34. case TypeReceiverReport:
  35. return "RR"
  36. case TypeSourceDescription:
  37. return "SDES"
  38. case TypeGoodbye:
  39. return "BYE"
  40. case TypeApplicationDefined:
  41. return "APP"
  42. case TypeTransportSpecificFeedback:
  43. return "TSFB"
  44. case TypePayloadSpecificFeedback:
  45. return "PSFB"
  46. case TypeExtendedReport:
  47. return "XR"
  48. default:
  49. return string(p)
  50. }
  51. }
  52. const rtpVersion = 2
  53. // A Header is the common header shared by all RTCP packets
  54. type Header struct {
  55. // If the padding bit is set, this individual RTCP packet contains
  56. // some additional padding octets at the end which are not part of
  57. // the control information but are included in the length field.
  58. Padding bool
  59. // The number of reception reports, sources contained or FMT in this packet (depending on the Type)
  60. Count uint8
  61. // The RTCP packet type for this packet
  62. Type PacketType
  63. // The length of this RTCP packet in 32-bit words minus one,
  64. // including the header and any padding.
  65. Length uint16
  66. }
  67. const (
  68. headerLength = 4
  69. versionShift = 6
  70. versionMask = 0x3
  71. paddingShift = 5
  72. paddingMask = 0x1
  73. countShift = 0
  74. countMask = 0x1f
  75. countMax = (1 << 5) - 1
  76. )
  77. // Marshal encodes the Header in binary
  78. func (h Header) Marshal() ([]byte, error) {
  79. /*
  80. * 0 1 2 3
  81. * 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
  82. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  83. * |V=2|P| RC | PT=SR=200 | length |
  84. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  85. */
  86. rawPacket := make([]byte, headerLength)
  87. rawPacket[0] |= rtpVersion << versionShift
  88. if h.Padding {
  89. rawPacket[0] |= 1 << paddingShift
  90. }
  91. if h.Count > 31 {
  92. return nil, errInvalidHeader
  93. }
  94. rawPacket[0] |= h.Count << countShift
  95. rawPacket[1] = uint8(h.Type)
  96. binary.BigEndian.PutUint16(rawPacket[2:], h.Length)
  97. return rawPacket, nil
  98. }
  99. // Unmarshal decodes the Header from binary
  100. func (h *Header) Unmarshal(rawPacket []byte) error {
  101. if len(rawPacket) < headerLength {
  102. return errPacketTooShort
  103. }
  104. /*
  105. * 0 1 2 3
  106. * 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
  107. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  108. * |V=2|P| RC | PT | length |
  109. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  110. */
  111. version := rawPacket[0] >> versionShift & versionMask
  112. if version != rtpVersion {
  113. return errBadVersion
  114. }
  115. h.Padding = (rawPacket[0] >> paddingShift & paddingMask) > 0
  116. h.Count = rawPacket[0] >> countShift & countMask
  117. h.Type = PacketType(rawPacket[1])
  118. h.Length = binary.BigEndian.Uint16(rawPacket[2:])
  119. return nil
  120. }