Added support for sending and receiving RTCP XR packets:
- Receiver reference time report block - DLRR report block (RFC3611). BUG=1613 R=mflodman@webrtc.org, stefan@webrtc.org Review URL: https://webrtc-codereview.appspot.com/2196010 git-svn-id: http://webrtc.googlecode.com/svn/trunk@4898 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
@ -13,6 +13,8 @@
|
||||
#include <assert.h> //assert
|
||||
#include <string.h> //memset
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
|
||||
#include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h"
|
||||
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
|
||||
@ -46,6 +48,8 @@ RTCPReceiver::RTCPReceiver(const int32_t id, Clock* clock,
|
||||
_remoteSenderInfo(),
|
||||
_lastReceivedSRNTPsecs(0),
|
||||
_lastReceivedSRNTPfrac(0),
|
||||
_lastReceivedXRNTPsecs(0),
|
||||
_lastReceivedXRNTPfrac(0),
|
||||
_receivedInfoMap(),
|
||||
_packetTimeOutMS(0),
|
||||
_lastReceivedRrMs(0),
|
||||
@ -259,6 +263,30 @@ RTCPReceiver::NTP(uint32_t *ReceivedNTPsecs,
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool RTCPReceiver::LastReceivedXrReferenceTimeInfo(
|
||||
RtcpReceiveTimeInfo* info) const {
|
||||
assert(info);
|
||||
CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
|
||||
if (_lastReceivedXRNTPsecs == 0 && _lastReceivedXRNTPfrac == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
info->sourceSSRC = _remoteXRReceiveTimeInfo.sourceSSRC;
|
||||
info->lastRR = _remoteXRReceiveTimeInfo.lastRR;
|
||||
|
||||
// Get the delay since last received report (RFC 3611).
|
||||
uint32_t receive_time = RTCPUtility::MidNtp(_lastReceivedXRNTPsecs,
|
||||
_lastReceivedXRNTPfrac);
|
||||
|
||||
uint32_t ntp_sec = 0;
|
||||
uint32_t ntp_frac = 0;
|
||||
_clock->CurrentNtp(ntp_sec, ntp_frac);
|
||||
uint32_t now = RTCPUtility::MidNtp(ntp_sec, ntp_frac);
|
||||
|
||||
info->delaySinceLastRR = now - receive_time;
|
||||
return true;
|
||||
}
|
||||
|
||||
int32_t
|
||||
RTCPReceiver::SenderInfoReceived(RTCPSenderInfo* senderInfo) const
|
||||
{
|
||||
@ -316,6 +344,15 @@ RTCPReceiver::IncomingRTCPPacket(RTCPPacketInformation& rtcpPacketInformation,
|
||||
case RTCPUtility::kRtcpSdesCode:
|
||||
HandleSDES(*rtcpParser);
|
||||
break;
|
||||
case RTCPUtility::kRtcpXrHeaderCode:
|
||||
HandleXrHeader(*rtcpParser, rtcpPacketInformation);
|
||||
break;
|
||||
case RTCPUtility::kRtcpXrReceiverReferenceTimeCode:
|
||||
HandleXrReceiveReferenceTime(*rtcpParser, rtcpPacketInformation);
|
||||
break;
|
||||
case RTCPUtility::kRtcpXrDlrrReportBlockCode:
|
||||
HandleXrDlrrReportBlock(*rtcpParser, rtcpPacketInformation);
|
||||
break;
|
||||
case RTCPUtility::kRtcpXrVoipMetricCode:
|
||||
HandleXRVOIPMetric(*rtcpParser, rtcpPacketInformation);
|
||||
break;
|
||||
@ -863,6 +900,85 @@ void RTCPReceiver::HandleBYE(RTCPUtility::RTCPParserV2& rtcpParser) {
|
||||
rtcpParser.Iterate();
|
||||
}
|
||||
|
||||
void RTCPReceiver::HandleXrHeader(
|
||||
RTCPUtility::RTCPParserV2& parser,
|
||||
RTCPPacketInformation& rtcpPacketInformation) {
|
||||
const RTCPUtility::RTCPPacket& packet = parser.Packet();
|
||||
|
||||
rtcpPacketInformation.xr_originator_ssrc = packet.XR.OriginatorSSRC;
|
||||
|
||||
parser.Iterate();
|
||||
}
|
||||
|
||||
void RTCPReceiver::HandleXrReceiveReferenceTime(
|
||||
RTCPUtility::RTCPParserV2& parser,
|
||||
RTCPPacketInformation& rtcpPacketInformation) {
|
||||
const RTCPUtility::RTCPPacket& packet = parser.Packet();
|
||||
|
||||
_remoteXRReceiveTimeInfo.sourceSSRC =
|
||||
rtcpPacketInformation.xr_originator_ssrc;
|
||||
|
||||
_remoteXRReceiveTimeInfo.lastRR = RTCPUtility::MidNtp(
|
||||
packet.XRReceiverReferenceTimeItem.NTPMostSignificant,
|
||||
packet.XRReceiverReferenceTimeItem.NTPLeastSignificant);
|
||||
|
||||
_clock->CurrentNtp(_lastReceivedXRNTPsecs, _lastReceivedXRNTPfrac);
|
||||
|
||||
rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrReceiverReferenceTime;
|
||||
|
||||
parser.Iterate();
|
||||
}
|
||||
|
||||
void RTCPReceiver::HandleXrDlrrReportBlock(
|
||||
RTCPUtility::RTCPParserV2& parser,
|
||||
RTCPPacketInformation& rtcpPacketInformation) {
|
||||
const RTCPUtility::RTCPPacket& packet = parser.Packet();
|
||||
// Iterate through sub-block(s), if any.
|
||||
RTCPUtility::RTCPPacketTypes packet_type = parser.Iterate();
|
||||
|
||||
while (packet_type == RTCPUtility::kRtcpXrDlrrReportBlockItemCode) {
|
||||
HandleXrDlrrReportBlockItem(packet, rtcpPacketInformation);
|
||||
packet_type = parser.Iterate();
|
||||
}
|
||||
}
|
||||
|
||||
void RTCPReceiver::HandleXrDlrrReportBlockItem(
|
||||
const RTCPUtility::RTCPPacket& packet,
|
||||
RTCPPacketInformation& rtcpPacketInformation) {
|
||||
if (registered_ssrcs_.find(packet.XRDLRRReportBlockItem.SSRC) ==
|
||||
registered_ssrcs_.end()) {
|
||||
// Not to us.
|
||||
return;
|
||||
}
|
||||
|
||||
rtcpPacketInformation.xr_dlrr_item = true;
|
||||
|
||||
// To avoid problem with acquiring _criticalSectionRTCPSender while holding
|
||||
// _criticalSectionRTCPReceiver.
|
||||
_criticalSectionRTCPReceiver->Leave();
|
||||
|
||||
int64_t send_time_ms;
|
||||
bool found = _rtpRtcp.SendTimeOfXrRrReport(
|
||||
packet.XRDLRRReportBlockItem.LastRR, &send_time_ms);
|
||||
|
||||
_criticalSectionRTCPReceiver->Enter();
|
||||
|
||||
if (!found) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The DelayLastRR field is in units of 1/65536 sec.
|
||||
// uint32_t delay_rr_ms =
|
||||
// (((packet.XRDLRRReportBlockItem.DelayLastRR & 0x0000ffff) * 1000) >> 16) +
|
||||
// (((packet.XRDLRRReportBlockItem.DelayLastRR & 0xffff0000) >> 16) * 1000);
|
||||
|
||||
// TODO(asapersson): Not yet used.
|
||||
// int32_t rtt =_clock->CurrentNtpInMilliseconds() - delay_rr_ms - send_time_ms;
|
||||
// rtt = std::max(rtt, 1);
|
||||
|
||||
rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrDlrrReportBlock;
|
||||
}
|
||||
|
||||
// no need for critsect we have _criticalSectionRTCPReceiver
|
||||
void
|
||||
RTCPReceiver::HandleXRVOIPMetric(RTCPUtility::RTCPParserV2& rtcpParser,
|
||||
|
||||
Reference in New Issue
Block a user