Go-based FM stereo transmitter with RDS, Windows-first and cross-platform
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

69 řádky
1.8KB

  1. package aoiprxkit
  2. import (
  3. "encoding/binary"
  4. "errors"
  5. )
  6. type RTPPacket struct {
  7. Version uint8
  8. Padding bool
  9. Extension bool
  10. CSRCCount uint8
  11. Marker bool
  12. PayloadType uint8
  13. SequenceNumber uint16
  14. Timestamp uint32
  15. SSRC uint32
  16. Payload []byte
  17. }
  18. func ParseRTPPacket(buf []byte) (RTPPacket, error) {
  19. if len(buf) < 12 {
  20. return RTPPacket{}, errors.New("RTP packet too short")
  21. }
  22. b0 := buf[0]
  23. b1 := buf[1]
  24. p := RTPPacket{
  25. Version: b0 >> 6,
  26. Padding: (b0 & 0x20) != 0,
  27. Extension: (b0 & 0x10) != 0,
  28. CSRCCount: b0 & 0x0F,
  29. Marker: (b1 & 0x80) != 0,
  30. PayloadType: b1 & 0x7F,
  31. SequenceNumber: binary.BigEndian.Uint16(buf[2:4]),
  32. Timestamp: binary.BigEndian.Uint32(buf[4:8]),
  33. SSRC: binary.BigEndian.Uint32(buf[8:12]),
  34. }
  35. if p.Version != 2 {
  36. return RTPPacket{}, errors.New("unsupported RTP version")
  37. }
  38. headerLen := 12 + int(p.CSRCCount)*4
  39. if len(buf) < headerLen {
  40. return RTPPacket{}, errors.New("RTP packet too short for CSRC list")
  41. }
  42. if p.Extension {
  43. if len(buf) < headerLen+4 {
  44. return RTPPacket{}, errors.New("RTP packet too short for extension")
  45. }
  46. extLenWords := int(binary.BigEndian.Uint16(buf[headerLen+2 : headerLen+4]))
  47. headerLen += 4 + extLenWords*4
  48. if len(buf) < headerLen {
  49. return RTPPacket{}, errors.New("RTP packet too short for full extension")
  50. }
  51. }
  52. payload := buf[headerLen:]
  53. if p.Padding {
  54. if len(payload) == 0 {
  55. return RTPPacket{}, errors.New("RTP packet has invalid padding")
  56. }
  57. padLen := int(payload[len(payload)-1])
  58. if padLen <= 0 || padLen > len(payload) {
  59. return RTPPacket{}, errors.New("RTP packet has invalid pad length")
  60. }
  61. payload = payload[:len(payload)-padLen]
  62. }
  63. p.Payload = payload
  64. return p, nil
  65. }