// Copyright 2020, Chef. All rights reserved. // https://github.com/q191201771/lal // // Use of this source code is governed by a MIT-style license // that can be found in the License file. // // Author: Chef (191201771@qq.com) package rtprtcp import ( "github.com/q191201771/naza/pkg/bele" ) // ------------------------------------------- // rfc3550 6.4.1 SR: Sender Report RTCP Packet // ------------------------------------------- // // 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 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // header |V=2|P| RC | PT=SR=200 | length | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // | SSRC of sender | // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ // sender | NTP timestamp, most significant word | // info +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // | NTP timestamp, least significant word | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // | RTP timestamp | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // | sender's packet count | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // | sender's octet count | // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ // report | SSRC_1 (SSRC of first source) | // block +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // 1 | fraction lost | cumulative number of packets lost | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // | extended highest sequence number received | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // | interarrival jitter | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // | last SR (LSR) | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // | delay since last SR (DLSR) | // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ // report | SSRC_2 (SSRC of second source) | // block +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // 2 : ... : // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ // | profile-specific extensions | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // --------------------------------------------- // rfc3550 6.4.2 RR: Receiver Report RTCP Packet // --------------------------------------------- // // 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 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // header |V=2|P| RC | PT=RR=201 | length | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // | SSRC of packet sender | // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ // report | SSRC_1 (SSRC of first source) | // block +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // 1 | fraction lost | cumulative number of packets lost | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // | extended highest sequence number received | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // | interarrival jitter | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // | last SR (LSR) | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // | delay since last SR (DLSR) | // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ // report | SSRC_2 (SSRC of second source) | // block +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // 2 : ... : // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ // | profile-specific extensions | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ const ( RtcpPacketTypeSr = 200 // 0xc8 Sender Report RtcpPacketTypeRr = 201 // 0xc9 Receiver Report RtcpPacketTypeApp = 204 RtcpHeaderLength = 4 RtcpVersion = 2 ) type RtcpHeader struct { Version uint8 // 2b Padding uint8 // 1b CountOrFormat uint8 // 5b PacketType uint8 // 8b Length uint16 // 16b, whole packet byte length = (Length+1) * 4 } type Sr struct { SenderSsrc uint32 Msw uint32 // NTP timestamp, most significant word Lsw uint32 // NTP timestamp, least significant word Timestamp uint32 PktCnt uint32 OctetCnt uint32 } func ParseRtcpHeader(b []byte) RtcpHeader { var h RtcpHeader h.Version = b[0] >> 6 h.Padding = (b[0] >> 5) & 0x1 h.CountOrFormat = b[0] & 0x1F h.PacketType = b[1] h.Length = bele.BeUint16(b[2:]) return h } // rfc3550 6.4.1 // // @param b rtcp包,包含包头 func ParseSr(b []byte) Sr { var s Sr s.SenderSsrc = bele.BeUint32(b[4:]) s.Msw = bele.BeUint32(b[8:]) s.Lsw = bele.BeUint32(b[12:]) s.Timestamp = bele.BeUint32(b[16:]) s.PktCnt = bele.BeUint32(b[20:]) s.OctetCnt = bele.BeUint32(b[24:]) return s } // @param out 传出参数,注意,调用方保证长度>=4 func (r *RtcpHeader) PackTo(out []byte) { out[0] = r.Version<<6 | r.Padding<<5 | r.CountOrFormat out[1] = r.PacketType bele.BePutUint16(out[2:], r.Length) } func (s *Sr) GetMiddleNtp() uint32 { return uint32(((uint64(s.Msw)<<32 | uint64(s.Lsw)) << 16) >> 32) }