Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1223)

Side by Side Diff: media/cast/net/rtcp/receiver_rtcp_session.cc

Issue 1520613004: cast: Split Rtcp into two for sender and receiver (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@timestamp
Patch Set: Add missing rtcp_session.h and a few comments Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/big_endian.h"
6 #include "base/time/tick_clock.h"
7 #include "media/cast/net/pacing/paced_sender.h"
8 #include "media/cast/net/rtcp/receiver_rtcp_session.h"
9 #include "media/cast/net/rtcp/rtcp_builder.h"
10 #include "media/cast/net/rtcp/rtcp_defines.h"
11 #include "media/cast/net/rtcp/rtcp_utility.h"
12
13 namespace media {
14 namespace cast {
15
16 namespace {
17
18 // Create a NTP diff from seconds and fractions of seconds; delay_fraction is
19 // fractions of a second where 0x80000000 is half a second.
20 uint32_t ConvertToNtpDiff(uint32_t delay_seconds, uint32_t delay_fraction) {
21 return ((delay_seconds & 0x0000FFFF) << 16) +
22 ((delay_fraction & 0xFFFF0000) >> 16);
23 }
24
25 } // namespace
26
27 ReceiverRtcpSession::ReceiverRtcpSession(base::TickClock* clock,
28 PacedPacketSender* packet_sender,
29 uint32_t local_ssrc,
30 uint32_t remote_ssrc)
31 : clock_(clock),
32 packet_sender_(packet_sender),
33 local_ssrc_(local_ssrc),
34 remote_ssrc_(remote_ssrc),
35 last_report_truncated_ntp_(0),
36 local_clock_ahead_by_(ClockDriftSmoother::GetDefaultTimeConstant()),
37 lip_sync_ntp_timestamp_(0),
38 parser_(local_ssrc, remote_ssrc) {}
39
40 ReceiverRtcpSession::~ReceiverRtcpSession() {}
41
42 bool ReceiverRtcpSession::IncomingRtcpPacket(const uint8_t* data,
43 size_t length) {
44 // Check if this is a valid RTCP packet.
45 if (!IsRtcpPacket(data, length)) {
46 VLOG(1) << "Rtcp@" << this << "::IncomingRtcpPacket() -- "
47 << "Received an invalid (non-RTCP?) packet.";
48 return false;
49 }
50
51 // Check if this packet is to us.
52 uint32_t ssrc_of_sender = GetSsrcOfSender(data, length);
53 if (ssrc_of_sender != remote_ssrc_) {
54 return false;
55 }
56
57 // Parse this packet.
58 base::BigEndianReader reader(reinterpret_cast<const char*>(data), length);
59 if (parser_.Parse(&reader)) {
60 if (parser_.has_sender_report()) {
61 OnReceivedNtp(parser_.sender_report().ntp_seconds,
62 parser_.sender_report().ntp_fraction);
63 OnReceivedLipSyncInfo(parser_.sender_report().rtp_timestamp,
64 parser_.sender_report().ntp_seconds,
65 parser_.sender_report().ntp_fraction);
66 }
67 }
68 return true;
69 }
70
71 void ReceiverRtcpSession::OnReceivedNtp(uint32_t ntp_seconds,
72 uint32_t ntp_fraction) {
73 last_report_truncated_ntp_ = ConvertToNtpDiff(ntp_seconds, ntp_fraction);
74
75 const base::TimeTicks now = clock_->NowTicks();
76 time_last_report_received_ = now;
77
78 // TODO(miu): This clock offset calculation does not account for packet
79 // transit time over the network. End2EndTest.EvilNetwork confirms that this
80 // contributes a very significant source of error here. Determine whether
81 // RTT should be factored-in, and how that changes the rest of the
82 // calculation.
83 const base::TimeDelta measured_offset =
84 now - ConvertNtpToTimeTicks(ntp_seconds, ntp_fraction);
85 local_clock_ahead_by_.Update(now, measured_offset);
86 if (measured_offset < local_clock_ahead_by_.Current()) {
87 // Logically, the minimum offset between the clocks has to be the correct
88 // one. For example, the time it took to transmit the current report may
89 // have been lower than usual, and so some of the error introduced by the
90 // transmission time can be eliminated.
91 local_clock_ahead_by_.Reset(now, measured_offset);
92 }
93 VLOG(1) << "Local clock is ahead of the remote clock by: "
94 << "measured=" << measured_offset.InMicroseconds() << " usec, "
95 << "filtered=" << local_clock_ahead_by_.Current().InMicroseconds()
96 << " usec.";
97 }
98
99 void ReceiverRtcpSession::SendRtcpReport(
100 RtcpTimeData time_data,
101 const RtcpCastMessage* cast_message,
102 base::TimeDelta target_delay,
103 const ReceiverRtcpEventSubscriber::RtcpEvents* rtcp_events,
104 const RtpReceiverStatistics* rtp_receiver_statistics) const {
105 RtcpReportBlock report_block;
106 RtcpReceiverReferenceTimeReport rrtr;
107 rrtr.ntp_seconds = time_data.ntp_seconds;
108 rrtr.ntp_fraction = time_data.ntp_fraction;
109
110 if (rtp_receiver_statistics) {
111 report_block.remote_ssrc = 0; // Not needed to set send side.
112 report_block.media_ssrc = remote_ssrc_; // SSRC of the RTP packet sender.
113 report_block.fraction_lost = rtp_receiver_statistics->fraction_lost;
114 report_block.cumulative_lost = rtp_receiver_statistics->cumulative_lost;
115 report_block.extended_high_sequence_number =
116 rtp_receiver_statistics->extended_high_sequence_number;
117 report_block.jitter = rtp_receiver_statistics->jitter;
118 report_block.last_sr = last_report_truncated_ntp_;
119 if (!time_last_report_received_.is_null()) {
120 uint32_t delay_seconds = 0;
121 uint32_t delay_fraction = 0;
122 base::TimeDelta delta = time_data.timestamp - time_last_report_received_;
123 ConvertTimeToFractions(delta.InMicroseconds(), &delay_seconds,
124 &delay_fraction);
125 report_block.delay_since_last_sr =
126 ConvertToNtpDiff(delay_seconds, delay_fraction);
127 } else {
128 report_block.delay_since_last_sr = 0;
129 }
130 }
131 RtcpBuilder rtcp_builder(local_ssrc_);
132 packet_sender_->SendRtcpPacket(
133 local_ssrc_, rtcp_builder.BuildRtcpFromReceiver(
134 rtp_receiver_statistics ? &report_block : NULL, &rrtr,
135 cast_message, rtcp_events, target_delay));
136 }
137
138 void ReceiverRtcpSession::OnReceivedLipSyncInfo(RtpTimeTicks rtp_timestamp,
139 uint32_t ntp_seconds,
140 uint32_t ntp_fraction) {
141 if (ntp_seconds == 0) {
142 NOTREACHED();
143 return;
144 }
145 lip_sync_rtp_timestamp_ = rtp_timestamp;
146 lip_sync_ntp_timestamp_ =
147 (static_cast<uint64_t>(ntp_seconds) << 32) | ntp_fraction;
148 }
149
150 bool ReceiverRtcpSession::GetLatestLipSyncTimes(
151 RtpTimeTicks* rtp_timestamp,
152 base::TimeTicks* reference_time) const {
153 if (!lip_sync_ntp_timestamp_)
154 return false;
155
156 const base::TimeTicks local_reference_time =
157 ConvertNtpToTimeTicks(
158 static_cast<uint32_t>(lip_sync_ntp_timestamp_ >> 32),
159 static_cast<uint32_t>(lip_sync_ntp_timestamp_)) +
160 local_clock_ahead_by_.Current();
161
162 // Sanity-check: Getting regular lip sync updates?
163 DCHECK((clock_->NowTicks() - local_reference_time) <
164 base::TimeDelta::FromMinutes(1));
165
166 *rtp_timestamp = lip_sync_rtp_timestamp_;
167 *reference_time = local_reference_time;
168 return true;
169 }
170
171 } // namespace cast
172 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698