header_extension.go 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. package rtp
  2. import (
  3. "encoding/binary"
  4. "fmt"
  5. "io"
  6. )
  7. const (
  8. headerExtensionProfileOneByte = 0xBEDE
  9. headerExtensionProfileTwoByte = 0x1000
  10. headerExtensionIDReserved = 0xF
  11. )
  12. // HeaderExtension represents an RTP extension header.
  13. type HeaderExtension interface {
  14. Set(id uint8, payload []byte) error
  15. GetIDs() []uint8
  16. Get(id uint8) []byte
  17. Del(id uint8) error
  18. Unmarshal(buf []byte) (int, error)
  19. Marshal() ([]byte, error)
  20. MarshalTo(buf []byte) (int, error)
  21. MarshalSize() int
  22. }
  23. // OneByteHeaderExtension is an RFC8285 one-byte header extension.
  24. type OneByteHeaderExtension struct {
  25. payload []byte
  26. }
  27. // Set sets the extension payload for the specified ID.
  28. func (e *OneByteHeaderExtension) Set(id uint8, buf []byte) error {
  29. if id < 1 || id > 14 {
  30. return fmt.Errorf("%w actual(%d)", errRFC8285OneByteHeaderIDRange, id)
  31. }
  32. if len(buf) > 16 {
  33. return fmt.Errorf("%w actual(%d)", errRFC8285OneByteHeaderSize, len(buf))
  34. }
  35. for n := 4; n < len(e.payload); {
  36. if e.payload[n] == 0x00 { // padding
  37. n++
  38. continue
  39. }
  40. extid := e.payload[n] >> 4
  41. len := int(e.payload[n]&^0xF0 + 1)
  42. n++
  43. if extid == id {
  44. e.payload = append(e.payload[:n+1], append(buf, e.payload[n+1+len:]...)...)
  45. return nil
  46. }
  47. n += len
  48. }
  49. e.payload = append(e.payload, (id<<4 | uint8(len(buf)-1)))
  50. e.payload = append(e.payload, buf...)
  51. binary.BigEndian.PutUint16(e.payload[2:4], binary.BigEndian.Uint16(e.payload[2:4])+1)
  52. return nil
  53. }
  54. // GetIDs returns the available IDs.
  55. func (e *OneByteHeaderExtension) GetIDs() []uint8 {
  56. ids := make([]uint8, 0, binary.BigEndian.Uint16(e.payload[2:4]))
  57. for n := 4; n < len(e.payload); {
  58. if e.payload[n] == 0x00 { // padding
  59. n++
  60. continue
  61. }
  62. extid := e.payload[n] >> 4
  63. len := int(e.payload[n]&^0xF0 + 1)
  64. n++
  65. if extid == headerExtensionIDReserved {
  66. break
  67. }
  68. ids = append(ids, extid)
  69. n += len
  70. }
  71. return ids
  72. }
  73. // Get returns the payload of the extension with the given ID.
  74. func (e *OneByteHeaderExtension) Get(id uint8) []byte {
  75. for n := 4; n < len(e.payload); {
  76. if e.payload[n] == 0x00 { // padding
  77. n++
  78. continue
  79. }
  80. extid := e.payload[n] >> 4
  81. len := int(e.payload[n]&^0xF0 + 1)
  82. n++
  83. if extid == id {
  84. return e.payload[n : n+len]
  85. }
  86. n += len
  87. }
  88. return nil
  89. }
  90. // Del deletes the extension with the specified ID.
  91. func (e *OneByteHeaderExtension) Del(id uint8) error {
  92. for n := 4; n < len(e.payload); {
  93. if e.payload[n] == 0x00 { // padding
  94. n++
  95. continue
  96. }
  97. extid := e.payload[n] >> 4
  98. len := int(e.payload[n]&^0xF0 + 1)
  99. if extid == id {
  100. e.payload = append(e.payload[:n], e.payload[n+1+len:]...)
  101. return nil
  102. }
  103. n += len + 1
  104. }
  105. return errHeaderExtensionNotFound
  106. }
  107. // Unmarshal parses the extension payload.
  108. func (e *OneByteHeaderExtension) Unmarshal(buf []byte) (int, error) {
  109. profile := binary.BigEndian.Uint16(buf[0:2])
  110. if profile != headerExtensionProfileOneByte {
  111. return 0, fmt.Errorf("%w actual(%x)", errHeaderExtensionNotFound, buf[0:2])
  112. }
  113. e.payload = buf
  114. return len(buf), nil
  115. }
  116. // Marshal returns the extension payload.
  117. func (e OneByteHeaderExtension) Marshal() ([]byte, error) {
  118. return e.payload, nil
  119. }
  120. // MarshalTo writes the extension payload to the given buffer.
  121. func (e OneByteHeaderExtension) MarshalTo(buf []byte) (int, error) {
  122. size := e.MarshalSize()
  123. if size > len(buf) {
  124. return 0, io.ErrShortBuffer
  125. }
  126. return copy(buf, e.payload), nil
  127. }
  128. // MarshalSize returns the size of the extension payload.
  129. func (e OneByteHeaderExtension) MarshalSize() int {
  130. return len(e.payload)
  131. }
  132. // TwoByteHeaderExtension is an RFC8285 two-byte header extension.
  133. type TwoByteHeaderExtension struct {
  134. payload []byte
  135. }
  136. // Set sets the extension payload for the specified ID.
  137. func (e *TwoByteHeaderExtension) Set(id uint8, buf []byte) error {
  138. if id < 1 || id > 255 {
  139. return fmt.Errorf("%w actual(%d)", errRFC8285TwoByteHeaderIDRange, id)
  140. }
  141. if len(buf) > 255 {
  142. return fmt.Errorf("%w actual(%d)", errRFC8285TwoByteHeaderSize, len(buf))
  143. }
  144. for n := 4; n < len(e.payload); {
  145. if e.payload[n] == 0x00 { // padding
  146. n++
  147. continue
  148. }
  149. extid := e.payload[n]
  150. n++
  151. len := int(e.payload[n])
  152. n++
  153. if extid == id {
  154. e.payload = append(e.payload[:n+2], append(buf, e.payload[n+2+len:]...)...)
  155. return nil
  156. }
  157. n += len
  158. }
  159. e.payload = append(e.payload, id, uint8(len(buf)))
  160. e.payload = append(e.payload, buf...)
  161. binary.BigEndian.PutUint16(e.payload[2:4], binary.BigEndian.Uint16(e.payload[2:4])+1)
  162. return nil
  163. }
  164. // GetIDs returns the available IDs.
  165. func (e *TwoByteHeaderExtension) GetIDs() []uint8 {
  166. ids := make([]uint8, 0, binary.BigEndian.Uint16(e.payload[2:4]))
  167. for n := 4; n < len(e.payload); {
  168. if e.payload[n] == 0x00 { // padding
  169. n++
  170. continue
  171. }
  172. extid := e.payload[n]
  173. n++
  174. len := int(e.payload[n])
  175. n++
  176. ids = append(ids, extid)
  177. n += len
  178. }
  179. return ids
  180. }
  181. // Get returns the payload of the extension with the given ID.
  182. func (e *TwoByteHeaderExtension) Get(id uint8) []byte {
  183. for n := 4; n < len(e.payload); {
  184. if e.payload[n] == 0x00 { // padding
  185. n++
  186. continue
  187. }
  188. extid := e.payload[n]
  189. n++
  190. len := int(e.payload[n])
  191. n++
  192. if extid == id {
  193. return e.payload[n : n+len]
  194. }
  195. n += len
  196. }
  197. return nil
  198. }
  199. // Del deletes the extension with the specified ID.
  200. func (e *TwoByteHeaderExtension) Del(id uint8) error {
  201. for n := 4; n < len(e.payload); {
  202. if e.payload[n] == 0x00 { // padding
  203. n++
  204. continue
  205. }
  206. extid := e.payload[n]
  207. len := int(e.payload[n+1])
  208. if extid == id {
  209. e.payload = append(e.payload[:n], e.payload[n+2+len:]...)
  210. return nil
  211. }
  212. n += len + 2
  213. }
  214. return errHeaderExtensionNotFound
  215. }
  216. // Unmarshal parses the extension payload.
  217. func (e *TwoByteHeaderExtension) Unmarshal(buf []byte) (int, error) {
  218. profile := binary.BigEndian.Uint16(buf[0:2])
  219. if profile != headerExtensionProfileTwoByte {
  220. return 0, fmt.Errorf("%w actual(%x)", errHeaderExtensionNotFound, buf[0:2])
  221. }
  222. e.payload = buf
  223. return len(buf), nil
  224. }
  225. // Marshal returns the extension payload.
  226. func (e TwoByteHeaderExtension) Marshal() ([]byte, error) {
  227. return e.payload, nil
  228. }
  229. // MarshalTo marshals the extension to the given buffer.
  230. func (e TwoByteHeaderExtension) MarshalTo(buf []byte) (int, error) {
  231. size := e.MarshalSize()
  232. if size > len(buf) {
  233. return 0, io.ErrShortBuffer
  234. }
  235. return copy(buf, e.payload), nil
  236. }
  237. // MarshalSize returns the size of the extension payload.
  238. func (e TwoByteHeaderExtension) MarshalSize() int {
  239. return len(e.payload)
  240. }
  241. // RawExtension represents an RFC3550 header extension.
  242. type RawExtension struct {
  243. payload []byte
  244. }
  245. // Set sets the extension payload for the specified ID.
  246. func (e *RawExtension) Set(id uint8, payload []byte) error {
  247. if id != 0 {
  248. return fmt.Errorf("%w actual(%d)", errRFC3550HeaderIDRange, id)
  249. }
  250. e.payload = payload
  251. return nil
  252. }
  253. // GetIDs returns the available IDs.
  254. func (e *RawExtension) GetIDs() []uint8 {
  255. return []uint8{0}
  256. }
  257. // Get returns the payload of the extension with the given ID.
  258. func (e *RawExtension) Get(id uint8) []byte {
  259. if id == 0 {
  260. return e.payload
  261. }
  262. return nil
  263. }
  264. // Del deletes the extension with the specified ID.
  265. func (e *RawExtension) Del(id uint8) error {
  266. if id == 0 {
  267. e.payload = nil
  268. return nil
  269. }
  270. return fmt.Errorf("%w actual(%d)", errRFC3550HeaderIDRange, id)
  271. }
  272. // Unmarshal parses the extension from the given buffer.
  273. func (e *RawExtension) Unmarshal(buf []byte) (int, error) {
  274. profile := binary.BigEndian.Uint16(buf[0:2])
  275. if profile == headerExtensionProfileOneByte || profile == headerExtensionProfileTwoByte {
  276. return 0, fmt.Errorf("%w actual(%x)", errHeaderExtensionNotFound, buf[0:2])
  277. }
  278. e.payload = buf
  279. return len(buf), nil
  280. }
  281. // Marshal returns the raw extension payload.
  282. func (e RawExtension) Marshal() ([]byte, error) {
  283. return e.payload, nil
  284. }
  285. // MarshalTo marshals the extension to the given buffer.
  286. func (e RawExtension) MarshalTo(buf []byte) (int, error) {
  287. size := e.MarshalSize()
  288. if size > len(buf) {
  289. return 0, io.ErrShortBuffer
  290. }
  291. return copy(buf, e.payload), nil
  292. }
  293. // MarshalSize returns the size of the extension when marshaled.
  294. func (e RawExtension) MarshalSize() int {
  295. return len(e.payload)
  296. }