| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- package rtcp
- import "encoding/binary"
- // A ReceptionReport block conveys statistics on the reception of RTP packets
- // from a single synchronization source.
- type ReceptionReport struct {
- // The SSRC identifier of the source to which the information in this
- // reception report block pertains.
- SSRC uint32
- // The fraction of RTP data packets from source SSRC lost since the
- // previous SR or RR packet was sent, expressed as a fixed point
- // number with the binary point at the left edge of the field.
- FractionLost uint8
- // The total number of RTP data packets from source SSRC that have
- // been lost since the beginning of reception.
- TotalLost uint32
- // The low 16 bits contain the highest sequence number received in an
- // RTP data packet from source SSRC, and the most significant 16
- // bits extend that sequence number with the corresponding count of
- // sequence number cycles.
- LastSequenceNumber uint32
- // An estimate of the statistical variance of the RTP data packet
- // interarrival time, measured in timestamp units and expressed as an
- // unsigned integer.
- Jitter uint32
- // The middle 32 bits out of 64 in the NTP timestamp received as part of
- // the most recent RTCP sender report (SR) packet from source SSRC. If no
- // SR has been received yet, the field is set to zero.
- LastSenderReport uint32
- // The delay, expressed in units of 1/65536 seconds, between receiving the
- // last SR packet from source SSRC and sending this reception report block.
- // If no SR packet has been received yet from SSRC, the field is set to zero.
- Delay uint32
- }
- const (
- receptionReportLength = 24
- fractionLostOffset = 4
- totalLostOffset = 5
- lastSeqOffset = 8
- jitterOffset = 12
- lastSROffset = 16
- delayOffset = 20
- )
- // Marshal encodes the ReceptionReport in binary
- func (r ReceptionReport) Marshal() ([]byte, error) {
- /*
- * 0 1 2 3
- * 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
- * +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
- * | SSRC |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | fraction lost | cumulative number of packets lost |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | extended highest sequence number received |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | interarrival jitter |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | last SR (LSR) |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | delay since last SR (DLSR) |
- * +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
- */
- rawPacket := make([]byte, receptionReportLength)
- binary.BigEndian.PutUint32(rawPacket, r.SSRC)
- rawPacket[fractionLostOffset] = r.FractionLost
- // pack TotalLost into 24 bits
- if r.TotalLost >= (1 << 25) {
- return nil, errInvalidTotalLost
- }
- tlBytes := rawPacket[totalLostOffset:]
- tlBytes[0] = byte(r.TotalLost >> 16)
- tlBytes[1] = byte(r.TotalLost >> 8)
- tlBytes[2] = byte(r.TotalLost)
- binary.BigEndian.PutUint32(rawPacket[lastSeqOffset:], r.LastSequenceNumber)
- binary.BigEndian.PutUint32(rawPacket[jitterOffset:], r.Jitter)
- binary.BigEndian.PutUint32(rawPacket[lastSROffset:], r.LastSenderReport)
- binary.BigEndian.PutUint32(rawPacket[delayOffset:], r.Delay)
- return rawPacket, nil
- }
- // Unmarshal decodes the ReceptionReport from binary
- func (r *ReceptionReport) Unmarshal(rawPacket []byte) error {
- if len(rawPacket) < receptionReportLength {
- return errPacketTooShort
- }
- /*
- * 0 1 2 3
- * 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
- * +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
- * | SSRC |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | fraction lost | cumulative number of packets lost |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | extended highest sequence number received |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | interarrival jitter |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | last SR (LSR) |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | delay since last SR (DLSR) |
- * +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
- */
- r.SSRC = binary.BigEndian.Uint32(rawPacket)
- r.FractionLost = rawPacket[fractionLostOffset]
- tlBytes := rawPacket[totalLostOffset:]
- r.TotalLost = uint32(tlBytes[2]) | uint32(tlBytes[1])<<8 | uint32(tlBytes[0])<<16
- r.LastSequenceNumber = binary.BigEndian.Uint32(rawPacket[lastSeqOffset:])
- r.Jitter = binary.BigEndian.Uint32(rawPacket[jitterOffset:])
- r.LastSenderReport = binary.BigEndian.Uint32(rawPacket[lastSROffset:])
- r.Delay = binary.BigEndian.Uint32(rawPacket[delayOffset:])
- return nil
- }
- func (r *ReceptionReport) len() int {
- return receptionReportLength
- }
|