Use RtcpPacket to send XR (RTRR, DLRR, VOIP) in RtcpSender
BUG=webrtc:2450 R=asapersson@webrtc.org Review URL: https://codereview.webrtc.org/1304123003 . Cr-Commit-Position: refs/heads/master@{#9820}
This commit is contained in:
parent
c252dabbd6
commit
ca28fdcf9f
@ -858,9 +858,6 @@ RTCPSender::BuildResult RTCPSender::BuildBYE(RtcpContext* ctx) {
|
||||
|
||||
RTCPSender::BuildResult RTCPSender::BuildReceiverReferenceTime(
|
||||
RtcpContext* ctx) {
|
||||
const int kRrTimeBlockLength = 20;
|
||||
if (ctx->position + kRrTimeBlockLength >= IP_PACKET_SIZE)
|
||||
return BuildResult::kTruncated;
|
||||
|
||||
if (last_xr_rr_.size() >= RTCP_NUMBER_OF_SR)
|
||||
last_xr_rr_.erase(last_xr_rr_.begin());
|
||||
@ -868,147 +865,75 @@ RTCPSender::BuildResult RTCPSender::BuildReceiverReferenceTime(
|
||||
RTCPUtility::MidNtp(ctx->ntp_sec, ctx->ntp_frac),
|
||||
Clock::NtpToMs(ctx->ntp_sec, ctx->ntp_frac)));
|
||||
|
||||
// Add XR header.
|
||||
*ctx->AllocateData(1) = 0x80;
|
||||
*ctx->AllocateData(1) = 207;
|
||||
ByteWriter<uint16_t>::WriteBigEndian(ctx->AllocateData(2),
|
||||
4); // XR packet length.
|
||||
rtcp::Xr xr;
|
||||
xr.From(ssrc_);
|
||||
|
||||
// Add our own SSRC.
|
||||
ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), ssrc_);
|
||||
rtcp::Rrtr rrtr;
|
||||
rrtr.WithNtpSec(ctx->ntp_sec);
|
||||
rrtr.WithNtpFrac(ctx->ntp_frac);
|
||||
|
||||
// 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
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | BT=4 | reserved | block length = 2 |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | NTP timestamp, most significant word |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | NTP timestamp, least significant word |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
xr.WithRrtr(&rrtr);
|
||||
|
||||
// Add Receiver Reference Time Report block.
|
||||
*ctx->AllocateData(1) = 4; // BT.
|
||||
*ctx->AllocateData(1) = 0; // Reserved.
|
||||
ByteWriter<uint16_t>::WriteBigEndian(ctx->AllocateData(2),
|
||||
2); // Block length.
|
||||
// TODO(sprang): Merge XR report sending to contain all of RRTR, DLRR, VOIP?
|
||||
|
||||
// NTP timestamp.
|
||||
ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), ctx->ntp_sec);
|
||||
ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), ctx->ntp_frac);
|
||||
PacketBuiltCallback callback(ctx);
|
||||
if (!callback.BuildPacket(xr))
|
||||
return BuildResult::kTruncated;
|
||||
|
||||
return BuildResult::kSuccess;
|
||||
}
|
||||
|
||||
RTCPSender::BuildResult RTCPSender::BuildDlrr(RtcpContext* ctx) {
|
||||
const int kDlrrBlockLength = 24;
|
||||
if (ctx->position + kDlrrBlockLength >= IP_PACKET_SIZE)
|
||||
return BuildResult::kTruncated;
|
||||
|
||||
// Add XR header.
|
||||
*ctx->AllocateData(1) = 0x80;
|
||||
*ctx->AllocateData(1) = 207;
|
||||
ByteWriter<uint16_t>::WriteBigEndian(ctx->AllocateData(2),
|
||||
5); // XR packet length.
|
||||
|
||||
// Add our own SSRC.
|
||||
ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), ssrc_);
|
||||
|
||||
// 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
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | BT=5 | reserved | block length |
|
||||
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|
||||
// | SSRC_1 (SSRC of first receiver) | sub-
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
|
||||
// | last RR (LRR) | 1
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | delay since last RR (DLRR) |
|
||||
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|
||||
// | SSRC_2 (SSRC of second receiver) | sub-
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
|
||||
// : ... : 2
|
||||
|
||||
// Add DLRR sub block.
|
||||
*ctx->AllocateData(1) = 5; // BT.
|
||||
*ctx->AllocateData(1) = 0; // Reserved.
|
||||
ByteWriter<uint16_t>::WriteBigEndian(ctx->AllocateData(2),
|
||||
3); // Block length.
|
||||
|
||||
// NTP timestamp.
|
||||
rtcp::Xr xr;
|
||||
xr.From(ssrc_);
|
||||
|
||||
rtcp::Dlrr dlrr;
|
||||
const RtcpReceiveTimeInfo& info = ctx->feedback_state.last_xr_rr;
|
||||
ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), info.sourceSSRC);
|
||||
ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), info.lastRR);
|
||||
ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4),
|
||||
info.delaySinceLastRR);
|
||||
dlrr.WithDlrrItem(info.sourceSSRC, info.lastRR, info.delaySinceLastRR);
|
||||
|
||||
xr.WithDlrr(&dlrr);
|
||||
|
||||
PacketBuiltCallback callback(ctx);
|
||||
if (!callback.BuildPacket(xr))
|
||||
return BuildResult::kTruncated;
|
||||
|
||||
return BuildResult::kSuccess;
|
||||
}
|
||||
|
||||
// TODO(sprang): Add a unit test for this, or remove if the code isn't used.
|
||||
RTCPSender::BuildResult RTCPSender::BuildVoIPMetric(RtcpContext* ctx) {
|
||||
// sanity
|
||||
if (ctx->position + 44 >= IP_PACKET_SIZE)
|
||||
rtcp::Xr xr;
|
||||
xr.From(ssrc_);
|
||||
|
||||
rtcp::VoipMetric voip;
|
||||
voip.To(remote_ssrc_);
|
||||
voip.LossRate(xr_voip_metric_.lossRate);
|
||||
voip.DiscardRate(xr_voip_metric_.discardRate);
|
||||
voip.BurstDensity(xr_voip_metric_.burstDensity);
|
||||
voip.GapDensity(xr_voip_metric_.gapDensity);
|
||||
voip.BurstDuration(xr_voip_metric_.burstDuration);
|
||||
voip.GapDuration(xr_voip_metric_.gapDuration);
|
||||
voip.RoundTripDelay(xr_voip_metric_.roundTripDelay);
|
||||
voip.EndSystemDelay(xr_voip_metric_.endSystemDelay);
|
||||
voip.SignalLevel(xr_voip_metric_.signalLevel);
|
||||
voip.NoiseLevel(xr_voip_metric_.noiseLevel);
|
||||
voip.Rerl(xr_voip_metric_.RERL);
|
||||
voip.Gmin(xr_voip_metric_.Gmin);
|
||||
voip.Rfactor(xr_voip_metric_.Rfactor);
|
||||
voip.ExtRfactor(xr_voip_metric_.extRfactor);
|
||||
voip.MosLq(xr_voip_metric_.MOSLQ);
|
||||
voip.MosCq(xr_voip_metric_.MOSCQ);
|
||||
voip.RxConfig(xr_voip_metric_.RXconfig);
|
||||
voip.JbNominal(xr_voip_metric_.JBnominal);
|
||||
voip.JbMax(xr_voip_metric_.JBmax);
|
||||
voip.JbAbsMax(xr_voip_metric_.JBabsMax);
|
||||
|
||||
xr.WithVoipMetric(&voip);
|
||||
|
||||
PacketBuiltCallback callback(ctx);
|
||||
if (!callback.BuildPacket(xr))
|
||||
return BuildResult::kTruncated;
|
||||
|
||||
// Add XR header
|
||||
*ctx->AllocateData(1) = 0x80;
|
||||
*ctx->AllocateData(1) = 207;
|
||||
|
||||
uint32_t XRLengthPos = ctx->position;
|
||||
|
||||
// handle length later on
|
||||
ctx->AllocateData(2);
|
||||
|
||||
// Add our own SSRC
|
||||
ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), ssrc_);
|
||||
|
||||
// Add a VoIP metrics block
|
||||
*ctx->AllocateData(1) = 7;
|
||||
*ctx->AllocateData(1) = 0;
|
||||
ByteWriter<uint16_t>::WriteBigEndian(ctx->AllocateData(2), 8);
|
||||
|
||||
// Add the remote SSRC
|
||||
ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), remote_ssrc_);
|
||||
|
||||
*ctx->AllocateData(1) = xr_voip_metric_.lossRate;
|
||||
*ctx->AllocateData(1) = xr_voip_metric_.discardRate;
|
||||
*ctx->AllocateData(1) = xr_voip_metric_.burstDensity;
|
||||
*ctx->AllocateData(1) = xr_voip_metric_.gapDensity;
|
||||
|
||||
ByteWriter<uint16_t>::WriteBigEndian(ctx->AllocateData(2),
|
||||
xr_voip_metric_.burstDuration);
|
||||
ByteWriter<uint16_t>::WriteBigEndian(ctx->AllocateData(2),
|
||||
xr_voip_metric_.gapDuration);
|
||||
|
||||
ByteWriter<uint16_t>::WriteBigEndian(ctx->AllocateData(2),
|
||||
xr_voip_metric_.roundTripDelay);
|
||||
ByteWriter<uint16_t>::WriteBigEndian(ctx->AllocateData(2),
|
||||
xr_voip_metric_.endSystemDelay);
|
||||
|
||||
*ctx->AllocateData(1) = xr_voip_metric_.signalLevel;
|
||||
*ctx->AllocateData(1) = xr_voip_metric_.noiseLevel;
|
||||
*ctx->AllocateData(1) = xr_voip_metric_.RERL;
|
||||
*ctx->AllocateData(1) = xr_voip_metric_.Gmin;
|
||||
|
||||
*ctx->AllocateData(1) = xr_voip_metric_.Rfactor;
|
||||
*ctx->AllocateData(1) = xr_voip_metric_.extRfactor;
|
||||
*ctx->AllocateData(1) = xr_voip_metric_.MOSLQ;
|
||||
*ctx->AllocateData(1) = xr_voip_metric_.MOSCQ;
|
||||
|
||||
*ctx->AllocateData(1) = xr_voip_metric_.RXconfig;
|
||||
*ctx->AllocateData(1) = 0; // reserved
|
||||
|
||||
ByteWriter<uint16_t>::WriteBigEndian(ctx->AllocateData(2),
|
||||
xr_voip_metric_.JBnominal);
|
||||
ByteWriter<uint16_t>::WriteBigEndian(ctx->AllocateData(2),
|
||||
xr_voip_metric_.JBmax);
|
||||
ByteWriter<uint16_t>::WriteBigEndian(ctx->AllocateData(2),
|
||||
xr_voip_metric_.JBabsMax);
|
||||
|
||||
ByteWriter<uint16_t>::WriteBigEndian(&ctx->buffer[XRLengthPos], 10);
|
||||
|
||||
return BuildResult::kSuccess;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user