packet.go 14 KB

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