packet.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533
  1. // SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
  2. // SPDX-License-Identifier: MIT
  3. package rtp
  4. import (
  5. "encoding/binary"
  6. "fmt"
  7. "io"
  8. )
  9. // Extension RTP Header extension
  10. type Extension struct {
  11. id uint8
  12. payload []byte
  13. }
  14. // Header represents an RTP packet header
  15. type Header struct {
  16. Version uint8
  17. Padding bool
  18. Extension bool
  19. Marker bool
  20. PayloadType uint8
  21. SequenceNumber uint16
  22. Timestamp uint32
  23. SSRC uint32
  24. CSRC []uint32
  25. ExtensionProfile uint16
  26. Extensions []Extension
  27. // Deprecated: will be removed in a future version.
  28. PayloadOffset int
  29. }
  30. // Packet represents an RTP Packet
  31. type Packet struct {
  32. Header
  33. Payload []byte
  34. PaddingSize byte
  35. // Deprecated: will be removed in a future version.
  36. Raw []byte
  37. }
  38. const (
  39. headerLength = 4
  40. versionShift = 6
  41. versionMask = 0x3
  42. paddingShift = 5
  43. paddingMask = 0x1
  44. extensionShift = 4
  45. extensionMask = 0x1
  46. extensionProfileOneByte = 0xBEDE
  47. extensionProfileTwoByte = 0x1000
  48. extensionIDReserved = 0xF
  49. ccMask = 0xF
  50. markerShift = 7
  51. markerMask = 0x1
  52. ptMask = 0x7F
  53. seqNumOffset = 2
  54. seqNumLength = 2
  55. timestampOffset = 4
  56. timestampLength = 4
  57. ssrcOffset = 8
  58. ssrcLength = 4
  59. csrcOffset = 12
  60. csrcLength = 4
  61. )
  62. // String helps with debugging by printing packet information in a readable way
  63. func (p Packet) String() string {
  64. out := "RTP PACKET:\n"
  65. out += fmt.Sprintf("\tVersion: %v\n", p.Version)
  66. out += fmt.Sprintf("\tMarker: %v\n", p.Marker)
  67. out += fmt.Sprintf("\tPayload Type: %d\n", p.PayloadType)
  68. out += fmt.Sprintf("\tSequence Number: %d\n", p.SequenceNumber)
  69. out += fmt.Sprintf("\tTimestamp: %d\n", p.Timestamp)
  70. out += fmt.Sprintf("\tSSRC: %d (%x)\n", p.SSRC, p.SSRC)
  71. out += fmt.Sprintf("\tPayload Length: %d\n", len(p.Payload))
  72. return out
  73. }
  74. // Unmarshal parses the passed byte slice and stores the result in the Header.
  75. // It returns the number of bytes read n and any error.
  76. func (h *Header) Unmarshal(buf []byte) (n int, err error) { //nolint:gocognit
  77. if len(buf) < headerLength {
  78. return 0, fmt.Errorf("%w: %d < %d", errHeaderSizeInsufficient, len(buf), headerLength)
  79. }
  80. /*
  81. * 0 1 2 3
  82. * 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
  83. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  84. * |V=2|P|X| CC |M| PT | sequence number |
  85. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  86. * | timestamp |
  87. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  88. * | synchronization source (SSRC) identifier |
  89. * +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
  90. * | contributing source (CSRC) identifiers |
  91. * | .... |
  92. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  93. */
  94. h.Version = buf[0] >> versionShift & versionMask
  95. h.Padding = (buf[0] >> paddingShift & paddingMask) > 0
  96. h.Extension = (buf[0] >> extensionShift & extensionMask) > 0
  97. nCSRC := int(buf[0] & ccMask)
  98. if cap(h.CSRC) < nCSRC || h.CSRC == nil {
  99. h.CSRC = make([]uint32, nCSRC)
  100. } else {
  101. h.CSRC = h.CSRC[:nCSRC]
  102. }
  103. n = csrcOffset + (nCSRC * csrcLength)
  104. if len(buf) < n {
  105. return n, fmt.Errorf("size %d < %d: %w", len(buf), n,
  106. errHeaderSizeInsufficient)
  107. }
  108. h.Marker = (buf[1] >> markerShift & markerMask) > 0
  109. h.PayloadType = buf[1] & ptMask
  110. h.SequenceNumber = binary.BigEndian.Uint16(buf[seqNumOffset : seqNumOffset+seqNumLength])
  111. h.Timestamp = binary.BigEndian.Uint32(buf[timestampOffset : timestampOffset+timestampLength])
  112. h.SSRC = binary.BigEndian.Uint32(buf[ssrcOffset : ssrcOffset+ssrcLength])
  113. for i := range h.CSRC {
  114. offset := csrcOffset + (i * csrcLength)
  115. h.CSRC[i] = binary.BigEndian.Uint32(buf[offset:])
  116. }
  117. if h.Extensions != nil {
  118. h.Extensions = h.Extensions[:0]
  119. }
  120. if h.Extension {
  121. if expected := n + 4; len(buf) < expected {
  122. return n, fmt.Errorf("size %d < %d: %w",
  123. len(buf), expected,
  124. errHeaderSizeInsufficientForExtension,
  125. )
  126. }
  127. h.ExtensionProfile = binary.BigEndian.Uint16(buf[n:])
  128. n += 2
  129. extensionLength := int(binary.BigEndian.Uint16(buf[n:])) * 4
  130. n += 2
  131. extensionEnd := n + extensionLength
  132. if len(buf) < extensionEnd {
  133. return n, fmt.Errorf("size %d < %d: %w", len(buf), extensionEnd, errHeaderSizeInsufficientForExtension)
  134. }
  135. if h.ExtensionProfile == extensionProfileOneByte || h.ExtensionProfile == extensionProfileTwoByte {
  136. var (
  137. extid uint8
  138. payloadLen int
  139. )
  140. for n < extensionEnd {
  141. if buf[n] == 0x00 { // padding
  142. n++
  143. continue
  144. }
  145. if h.ExtensionProfile == extensionProfileOneByte {
  146. extid = buf[n] >> 4
  147. payloadLen = int(buf[n]&^0xF0 + 1)
  148. n++
  149. if extid == extensionIDReserved {
  150. break
  151. }
  152. } else {
  153. extid = buf[n]
  154. n++
  155. if len(buf) <= n {
  156. return n, fmt.Errorf("size %d < %d: %w", len(buf), n, errHeaderSizeInsufficientForExtension)
  157. }
  158. payloadLen = int(buf[n])
  159. n++
  160. }
  161. if extensionPayloadEnd := n + payloadLen; len(buf) <= extensionPayloadEnd {
  162. return n, fmt.Errorf("size %d < %d: %w", len(buf), extensionPayloadEnd, errHeaderSizeInsufficientForExtension)
  163. }
  164. extension := Extension{id: extid, payload: buf[n : n+payloadLen]}
  165. h.Extensions = append(h.Extensions, extension)
  166. n += payloadLen
  167. }
  168. } else {
  169. // RFC3550 Extension
  170. extension := Extension{id: 0, payload: buf[n:extensionEnd]}
  171. h.Extensions = append(h.Extensions, extension)
  172. n += len(h.Extensions[0].payload)
  173. }
  174. }
  175. return n, nil
  176. }
  177. // Unmarshal parses the passed byte slice and stores the result in the Packet.
  178. func (p *Packet) Unmarshal(buf []byte) error {
  179. n, err := p.Header.Unmarshal(buf)
  180. if err != nil {
  181. return err
  182. }
  183. end := len(buf)
  184. if p.Header.Padding {
  185. p.PaddingSize = buf[end-1]
  186. end -= int(p.PaddingSize)
  187. }
  188. if end < n {
  189. return errTooSmall
  190. }
  191. p.Payload = buf[n:end]
  192. return nil
  193. }
  194. // Marshal serializes the header into bytes.
  195. func (h Header) Marshal() (buf []byte, err error) {
  196. buf = make([]byte, h.MarshalSize())
  197. n, err := h.MarshalTo(buf)
  198. if err != nil {
  199. return nil, err
  200. }
  201. return buf[:n], nil
  202. }
  203. // MarshalTo serializes the header and writes to the buffer.
  204. func (h Header) MarshalTo(buf []byte) (n int, err error) {
  205. /*
  206. * 0 1 2 3
  207. * 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
  208. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  209. * |V=2|P|X| CC |M| PT | sequence number |
  210. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  211. * | timestamp |
  212. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  213. * | synchronization source (SSRC) identifier |
  214. * +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
  215. * | contributing source (CSRC) identifiers |
  216. * | .... |
  217. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  218. */
  219. size := h.MarshalSize()
  220. if size > len(buf) {
  221. return 0, io.ErrShortBuffer
  222. }
  223. // The first byte contains the version, padding bit, extension bit,
  224. // and csrc size.
  225. buf[0] = (h.Version << versionShift) | uint8(len(h.CSRC))
  226. if h.Padding {
  227. buf[0] |= 1 << paddingShift
  228. }
  229. if h.Extension {
  230. buf[0] |= 1 << extensionShift
  231. }
  232. // The second byte contains the marker bit and payload type.
  233. buf[1] = h.PayloadType
  234. if h.Marker {
  235. buf[1] |= 1 << markerShift
  236. }
  237. binary.BigEndian.PutUint16(buf[2:4], h.SequenceNumber)
  238. binary.BigEndian.PutUint32(buf[4:8], h.Timestamp)
  239. binary.BigEndian.PutUint32(buf[8:12], h.SSRC)
  240. n = 12
  241. for _, csrc := range h.CSRC {
  242. binary.BigEndian.PutUint32(buf[n:n+4], csrc)
  243. n += 4
  244. }
  245. if h.Extension {
  246. extHeaderPos := n
  247. binary.BigEndian.PutUint16(buf[n+0:n+2], h.ExtensionProfile)
  248. n += 4
  249. startExtensionsPos := n
  250. switch h.ExtensionProfile {
  251. // RFC 8285 RTP One Byte Header Extension
  252. case extensionProfileOneByte:
  253. for _, extension := range h.Extensions {
  254. buf[n] = extension.id<<4 | (uint8(len(extension.payload)) - 1)
  255. n++
  256. n += copy(buf[n:], extension.payload)
  257. }
  258. // RFC 8285 RTP Two Byte Header Extension
  259. case extensionProfileTwoByte:
  260. for _, extension := range h.Extensions {
  261. buf[n] = extension.id
  262. n++
  263. buf[n] = uint8(len(extension.payload))
  264. n++
  265. n += copy(buf[n:], extension.payload)
  266. }
  267. default: // RFC3550 Extension
  268. extlen := len(h.Extensions[0].payload)
  269. if extlen%4 != 0 {
  270. // the payload must be in 32-bit words.
  271. return 0, io.ErrShortBuffer
  272. }
  273. n += copy(buf[n:], h.Extensions[0].payload)
  274. }
  275. // calculate extensions size and round to 4 bytes boundaries
  276. extSize := n - startExtensionsPos
  277. roundedExtSize := ((extSize + 3) / 4) * 4
  278. binary.BigEndian.PutUint16(buf[extHeaderPos+2:extHeaderPos+4], uint16(roundedExtSize/4))
  279. // add padding to reach 4 bytes boundaries
  280. for i := 0; i < roundedExtSize-extSize; i++ {
  281. buf[n] = 0
  282. n++
  283. }
  284. }
  285. return n, nil
  286. }
  287. // MarshalSize returns the size of the header once marshaled.
  288. func (h Header) MarshalSize() int {
  289. // NOTE: Be careful to match the MarshalTo() method.
  290. size := 12 + (len(h.CSRC) * csrcLength)
  291. if h.Extension {
  292. extSize := 4
  293. switch h.ExtensionProfile {
  294. // RFC 8285 RTP One Byte Header Extension
  295. case extensionProfileOneByte:
  296. for _, extension := range h.Extensions {
  297. extSize += 1 + len(extension.payload)
  298. }
  299. // RFC 8285 RTP Two Byte Header Extension
  300. case extensionProfileTwoByte:
  301. for _, extension := range h.Extensions {
  302. extSize += 2 + len(extension.payload)
  303. }
  304. default:
  305. extSize += len(h.Extensions[0].payload)
  306. }
  307. // extensions size must have 4 bytes boundaries
  308. size += ((extSize + 3) / 4) * 4
  309. }
  310. return size
  311. }
  312. // SetExtension sets an RTP header extension
  313. func (h *Header) SetExtension(id uint8, payload []byte) error { //nolint:gocognit
  314. if h.Extension {
  315. switch h.ExtensionProfile {
  316. // RFC 8285 RTP One Byte Header Extension
  317. case extensionProfileOneByte:
  318. if id < 1 || id > 14 {
  319. return fmt.Errorf("%w actual(%d)", errRFC8285OneByteHeaderIDRange, id)
  320. }
  321. if len(payload) > 16 {
  322. return fmt.Errorf("%w actual(%d)", errRFC8285OneByteHeaderSize, len(payload))
  323. }
  324. // RFC 8285 RTP Two Byte Header Extension
  325. case extensionProfileTwoByte:
  326. if id < 1 || id > 255 {
  327. return fmt.Errorf("%w actual(%d)", errRFC8285TwoByteHeaderIDRange, id)
  328. }
  329. if len(payload) > 255 {
  330. return fmt.Errorf("%w actual(%d)", errRFC8285TwoByteHeaderSize, len(payload))
  331. }
  332. default: // RFC3550 Extension
  333. if id != 0 {
  334. return fmt.Errorf("%w actual(%d)", errRFC3550HeaderIDRange, id)
  335. }
  336. }
  337. // Update existing if it exists else add new extension
  338. for i, extension := range h.Extensions {
  339. if extension.id == id {
  340. h.Extensions[i].payload = payload
  341. return nil
  342. }
  343. }
  344. h.Extensions = append(h.Extensions, Extension{id: id, payload: payload})
  345. return nil
  346. }
  347. // No existing header extensions
  348. h.Extension = true
  349. switch payloadLen := len(payload); {
  350. case payloadLen <= 16:
  351. h.ExtensionProfile = extensionProfileOneByte
  352. case payloadLen > 16 && payloadLen < 256:
  353. h.ExtensionProfile = extensionProfileTwoByte
  354. }
  355. h.Extensions = append(h.Extensions, Extension{id: id, payload: payload})
  356. return nil
  357. }
  358. // GetExtensionIDs returns an extension id array
  359. func (h *Header) GetExtensionIDs() []uint8 {
  360. if !h.Extension {
  361. return nil
  362. }
  363. if len(h.Extensions) == 0 {
  364. return nil
  365. }
  366. ids := make([]uint8, 0, len(h.Extensions))
  367. for _, extension := range h.Extensions {
  368. ids = append(ids, extension.id)
  369. }
  370. return ids
  371. }
  372. // GetExtension returns an RTP header extension
  373. func (h *Header) GetExtension(id uint8) []byte {
  374. if !h.Extension {
  375. return nil
  376. }
  377. for _, extension := range h.Extensions {
  378. if extension.id == id {
  379. return extension.payload
  380. }
  381. }
  382. return nil
  383. }
  384. // DelExtension Removes an RTP Header extension
  385. func (h *Header) DelExtension(id uint8) error {
  386. if !h.Extension {
  387. return errHeaderExtensionsNotEnabled
  388. }
  389. for i, extension := range h.Extensions {
  390. if extension.id == id {
  391. h.Extensions = append(h.Extensions[:i], h.Extensions[i+1:]...)
  392. return nil
  393. }
  394. }
  395. return errHeaderExtensionNotFound
  396. }
  397. // Marshal serializes the packet into bytes.
  398. func (p Packet) Marshal() (buf []byte, err error) {
  399. buf = make([]byte, p.MarshalSize())
  400. n, err := p.MarshalTo(buf)
  401. if err != nil {
  402. return nil, err
  403. }
  404. return buf[:n], nil
  405. }
  406. // MarshalTo serializes the packet and writes to the buffer.
  407. func (p *Packet) MarshalTo(buf []byte) (n int, err error) {
  408. n, err = p.Header.MarshalTo(buf)
  409. if err != nil {
  410. return 0, err
  411. }
  412. // Make sure the buffer is large enough to hold the packet.
  413. if n+len(p.Payload)+int(p.PaddingSize) > len(buf) {
  414. return 0, io.ErrShortBuffer
  415. }
  416. m := copy(buf[n:], p.Payload)
  417. if p.Header.Padding {
  418. buf[n+m+int(p.PaddingSize-1)] = p.PaddingSize
  419. }
  420. return n + m + int(p.PaddingSize), nil
  421. }
  422. // MarshalSize returns the size of the packet once marshaled.
  423. func (p Packet) MarshalSize() int {
  424. return p.Header.MarshalSize() + len(p.Payload) + int(p.PaddingSize)
  425. }
  426. // Clone returns a deep copy of p.
  427. func (p Packet) Clone() *Packet {
  428. clone := &Packet{}
  429. clone.Header = p.Header.Clone()
  430. if p.Payload != nil {
  431. clone.Payload = make([]byte, len(p.Payload))
  432. copy(clone.Payload, p.Payload)
  433. }
  434. clone.PaddingSize = p.PaddingSize
  435. return clone
  436. }
  437. // Clone returns a deep copy h.
  438. func (h Header) Clone() Header {
  439. clone := h
  440. if h.CSRC != nil {
  441. clone.CSRC = make([]uint32, len(h.CSRC))
  442. copy(clone.CSRC, h.CSRC)
  443. }
  444. if h.Extensions != nil {
  445. ext := make([]Extension, len(h.Extensions))
  446. for i, e := range h.Extensions {
  447. ext[i] = e
  448. if e.payload != nil {
  449. ext[i].payload = make([]byte, len(e.payload))
  450. copy(ext[i].payload, e.payload)
  451. }
  452. }
  453. clone.Extensions = ext
  454. }
  455. return clone
  456. }