reception_report.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. package rtcp
  2. import "encoding/binary"
  3. // A ReceptionReport block conveys statistics on the reception of RTP packets
  4. // from a single synchronization source.
  5. type ReceptionReport struct {
  6. // The SSRC identifier of the source to which the information in this
  7. // reception report block pertains.
  8. SSRC uint32
  9. // The fraction of RTP data packets from source SSRC lost since the
  10. // previous SR or RR packet was sent, expressed as a fixed point
  11. // number with the binary point at the left edge of the field.
  12. FractionLost uint8
  13. // The total number of RTP data packets from source SSRC that have
  14. // been lost since the beginning of reception.
  15. TotalLost uint32
  16. // The low 16 bits contain the highest sequence number received in an
  17. // RTP data packet from source SSRC, and the most significant 16
  18. // bits extend that sequence number with the corresponding count of
  19. // sequence number cycles.
  20. LastSequenceNumber uint32
  21. // An estimate of the statistical variance of the RTP data packet
  22. // interarrival time, measured in timestamp units and expressed as an
  23. // unsigned integer.
  24. Jitter uint32
  25. // The middle 32 bits out of 64 in the NTP timestamp received as part of
  26. // the most recent RTCP sender report (SR) packet from source SSRC. If no
  27. // SR has been received yet, the field is set to zero.
  28. LastSenderReport uint32
  29. // The delay, expressed in units of 1/65536 seconds, between receiving the
  30. // last SR packet from source SSRC and sending this reception report block.
  31. // If no SR packet has been received yet from SSRC, the field is set to zero.
  32. Delay uint32
  33. }
  34. const (
  35. receptionReportLength = 24
  36. fractionLostOffset = 4
  37. totalLostOffset = 5
  38. lastSeqOffset = 8
  39. jitterOffset = 12
  40. lastSROffset = 16
  41. delayOffset = 20
  42. )
  43. // Marshal encodes the ReceptionReport in binary
  44. func (r ReceptionReport) Marshal() ([]byte, error) {
  45. /*
  46. * 0 1 2 3
  47. * 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
  48. * +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
  49. * | SSRC |
  50. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  51. * | fraction lost | cumulative number of packets lost |
  52. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  53. * | extended highest sequence number received |
  54. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  55. * | interarrival jitter |
  56. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  57. * | last SR (LSR) |
  58. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  59. * | delay since last SR (DLSR) |
  60. * +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
  61. */
  62. rawPacket := make([]byte, receptionReportLength)
  63. binary.BigEndian.PutUint32(rawPacket, r.SSRC)
  64. rawPacket[fractionLostOffset] = r.FractionLost
  65. // pack TotalLost into 24 bits
  66. if r.TotalLost >= (1 << 25) {
  67. return nil, errInvalidTotalLost
  68. }
  69. tlBytes := rawPacket[totalLostOffset:]
  70. tlBytes[0] = byte(r.TotalLost >> 16)
  71. tlBytes[1] = byte(r.TotalLost >> 8)
  72. tlBytes[2] = byte(r.TotalLost)
  73. binary.BigEndian.PutUint32(rawPacket[lastSeqOffset:], r.LastSequenceNumber)
  74. binary.BigEndian.PutUint32(rawPacket[jitterOffset:], r.Jitter)
  75. binary.BigEndian.PutUint32(rawPacket[lastSROffset:], r.LastSenderReport)
  76. binary.BigEndian.PutUint32(rawPacket[delayOffset:], r.Delay)
  77. return rawPacket, nil
  78. }
  79. // Unmarshal decodes the ReceptionReport from binary
  80. func (r *ReceptionReport) Unmarshal(rawPacket []byte) error {
  81. if len(rawPacket) < receptionReportLength {
  82. return errPacketTooShort
  83. }
  84. /*
  85. * 0 1 2 3
  86. * 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
  87. * +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
  88. * | SSRC |
  89. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  90. * | fraction lost | cumulative number of packets lost |
  91. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  92. * | extended highest sequence number received |
  93. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  94. * | interarrival jitter |
  95. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  96. * | last SR (LSR) |
  97. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  98. * | delay since last SR (DLSR) |
  99. * +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
  100. */
  101. r.SSRC = binary.BigEndian.Uint32(rawPacket)
  102. r.FractionLost = rawPacket[fractionLostOffset]
  103. tlBytes := rawPacket[totalLostOffset:]
  104. r.TotalLost = uint32(tlBytes[2]) | uint32(tlBytes[1])<<8 | uint32(tlBytes[0])<<16
  105. r.LastSequenceNumber = binary.BigEndian.Uint32(rawPacket[lastSeqOffset:])
  106. r.Jitter = binary.BigEndian.Uint32(rawPacket[jitterOffset:])
  107. r.LastSenderReport = binary.BigEndian.Uint32(rawPacket[lastSROffset:])
  108. r.Delay = binary.BigEndian.Uint32(rawPacket[delayOffset:])
  109. return nil
  110. }
  111. func (r *ReceptionReport) len() int {
  112. return receptionReportLength
  113. }