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

Side by Side Diff: media/cast/video_sender/video_sender.cc

Issue 295603004: [Cast] Aggressively send sender reports until first receiver report is received. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 7 months 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/cast/video_sender/video_sender.h" 5 #include "media/cast/video_sender/video_sender.h"
6 6
7 #include <cstring> 7 #include <cstring>
8 #include <list> 8 #include <list>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/debug/trace_event.h" 11 #include "base/debug/trace_event.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/message_loop/message_loop.h" 13 #include "base/message_loop/message_loop.h"
14 #include "media/cast/cast_defines.h" 14 #include "media/cast/cast_defines.h"
15 #include "media/cast/rtcp/rtcp_defines.h" 15 #include "media/cast/rtcp/rtcp_defines.h"
16 #include "media/cast/transport/cast_transport_config.h" 16 #include "media/cast/transport/cast_transport_config.h"
17 #include "media/cast/video_sender/external_video_encoder.h" 17 #include "media/cast/video_sender/external_video_encoder.h"
18 #include "media/cast/video_sender/video_encoder_impl.h" 18 #include "media/cast/video_sender/video_encoder_impl.h"
19 19
20 namespace media { 20 namespace media {
21 namespace cast { 21 namespace cast {
22 22
23 const int64 kMinSchedulingDelayMs = 1; 23 const int kNumAggressiveReportsSentAtStart = 100;
24 24 const int kMinSchedulingDelayMs = 1;
25 class LocalRtcpVideoSenderFeedback : public RtcpSenderFeedback {
26 public:
27 explicit LocalRtcpVideoSenderFeedback(VideoSender* video_sender)
28 : video_sender_(video_sender) {}
29
30 virtual void OnReceivedCastFeedback(const RtcpCastMessage& cast_feedback)
31 OVERRIDE {
32 video_sender_->OnReceivedCastFeedback(cast_feedback);
33 }
34
35 private:
36 VideoSender* video_sender_;
37
38 DISALLOW_IMPLICIT_CONSTRUCTORS(LocalRtcpVideoSenderFeedback);
39 };
40 25
41 VideoSender::VideoSender( 26 VideoSender::VideoSender(
42 scoped_refptr<CastEnvironment> cast_environment, 27 scoped_refptr<CastEnvironment> cast_environment,
43 const VideoSenderConfig& video_config, 28 const VideoSenderConfig& video_config,
44 const CreateVideoEncodeAcceleratorCallback& create_vea_cb, 29 const CreateVideoEncodeAcceleratorCallback& create_vea_cb,
45 const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb, 30 const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb,
46 const CastInitializationCallback& cast_initialization_cb, 31 const CastInitializationCallback& cast_initialization_cb,
47 transport::CastTransportSender* const transport_sender) 32 transport::CastTransportSender* const transport_sender)
48 : rtp_max_delay_(base::TimeDelta::FromMilliseconds( 33 : rtp_max_delay_(base::TimeDelta::FromMilliseconds(
49 video_config.rtp_config.max_delay_ms)), 34 video_config.rtp_config.max_delay_ms)),
50 max_frame_rate_(video_config.max_frame_rate), 35 max_frame_rate_(video_config.max_frame_rate),
51 cast_environment_(cast_environment), 36 cast_environment_(cast_environment),
52 transport_sender_(transport_sender), 37 transport_sender_(transport_sender),
53 rtp_timestamp_helper_(kVideoFrequency), 38 rtp_timestamp_helper_(kVideoFrequency),
54 rtcp_feedback_(new LocalRtcpVideoSenderFeedback(this)), 39 num_aggressive_rtcp_reports_sent_(0),
55 last_acked_frame_id_(-1), 40 last_acked_frame_id_(-1),
56 last_sent_frame_id_(-1), 41 last_sent_frame_id_(-1),
57 frames_in_encoder_(0), 42 frames_in_encoder_(0),
58 duplicate_ack_(0), 43 duplicate_ack_(0),
59 last_skip_count_(0), 44 last_skip_count_(0),
60 current_requested_bitrate_(video_config.start_bitrate), 45 current_requested_bitrate_(video_config.start_bitrate),
61 congestion_control_(cast_environment->Clock(), 46 congestion_control_(cast_environment->Clock(),
62 video_config.congestion_control_back_off, 47 video_config.congestion_control_back_off,
63 video_config.max_bitrate, 48 video_config.max_bitrate,
64 video_config.min_bitrate, 49 video_config.min_bitrate,
(...skipping 19 matching lines...) Expand all
84 69
85 70
86 media::cast::transport::CastTransportVideoConfig transport_config; 71 media::cast::transport::CastTransportVideoConfig transport_config;
87 transport_config.codec = video_config.codec; 72 transport_config.codec = video_config.codec;
88 transport_config.rtp.config = video_config.rtp_config; 73 transport_config.rtp.config = video_config.rtp_config;
89 transport_config.rtp.max_outstanding_frames = max_unacked_frames_ + 1; 74 transport_config.rtp.max_outstanding_frames = max_unacked_frames_ + 1;
90 transport_sender_->InitializeVideo(transport_config); 75 transport_sender_->InitializeVideo(transport_config);
91 76
92 rtcp_.reset( 77 rtcp_.reset(
93 new Rtcp(cast_environment_, 78 new Rtcp(cast_environment_,
94 rtcp_feedback_.get(), 79 this,
95 transport_sender_, 80 transport_sender_,
96 NULL, // paced sender. 81 NULL, // paced sender.
97 NULL, 82 NULL,
98 video_config.rtcp_mode, 83 video_config.rtcp_mode,
99 base::TimeDelta::FromMilliseconds(video_config.rtcp_interval), 84 base::TimeDelta::FromMilliseconds(video_config.rtcp_interval),
100 video_config.rtp_config.ssrc, 85 video_config.rtp_config.ssrc,
101 video_config.incoming_feedback_ssrc, 86 video_config.incoming_feedback_ssrc,
102 video_config.rtcp_c_name, 87 video_config.rtcp_c_name,
103 false)); 88 false));
104 rtcp_->SetCastReceiverEventHistorySize(kReceiverRtcpEventHistorySize); 89 rtcp_->SetCastReceiverEventHistorySize(kReceiverRtcpEventHistorySize);
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 TRACE_EVENT_SCOPE_THREAD, 167 TRACE_EVENT_SCOPE_THREAD,
183 "rtp_timestamp", encoded_frame->rtp_timestamp); 168 "rtp_timestamp", encoded_frame->rtp_timestamp);
184 169
185 // Only use lowest 8 bits as key. 170 // Only use lowest 8 bits as key.
186 frame_id_to_rtp_timestamp_[frame_id & 0xff] = encoded_frame->rtp_timestamp; 171 frame_id_to_rtp_timestamp_[frame_id & 0xff] = encoded_frame->rtp_timestamp;
187 172
188 last_sent_frame_id_ = static_cast<int>(encoded_frame->frame_id); 173 last_sent_frame_id_ = static_cast<int>(encoded_frame->frame_id);
189 DCHECK(!encoded_frame->reference_time.is_null()); 174 DCHECK(!encoded_frame->reference_time.is_null());
190 rtp_timestamp_helper_.StoreLatestTime(encoded_frame->reference_time, 175 rtp_timestamp_helper_.StoreLatestTime(encoded_frame->reference_time,
191 encoded_frame->rtp_timestamp); 176 encoded_frame->rtp_timestamp);
177
178 // At the start of the session, it's important to send reports before each
179 // frame so that the receiver can properly compute playout times. The reason
180 // more than one report is sent is because transmission is not guaranteed,
181 // only best effort, so send enough that one should almost certainly get
182 // through.
183 if (num_aggressive_rtcp_reports_sent_ < kNumAggressiveReportsSentAtStart) {
184 // SendRtcpReport() will schedule future reports to be made if this is the
185 // last "aggressive report."
186 ++num_aggressive_rtcp_reports_sent_;
187 const bool is_last_aggressive_report =
188 (num_aggressive_rtcp_reports_sent_ == kNumAggressiveReportsSentAtStart);
189 VLOG_IF(1, is_last_aggressive_report) << "Sending last aggressive report.";
190 SendRtcpReport(is_last_aggressive_report);
191 }
192
192 transport_sender_->InsertCodedVideoFrame(*encoded_frame); 193 transport_sender_->InsertCodedVideoFrame(*encoded_frame);
193 UpdateFramesInFlight(); 194 UpdateFramesInFlight();
194 InitializeTimers(); 195 InitializeTimers();
195 } 196 }
196 197
197 void VideoSender::IncomingRtcpPacket(scoped_ptr<Packet> packet) { 198 void VideoSender::IncomingRtcpPacket(scoped_ptr<Packet> packet) {
198 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 199 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
199 rtcp_->IncomingRtcpPacket(&packet->front(), packet->size()); 200 rtcp_->IncomingRtcpPacket(&packet->front(), packet->size());
200 } 201 }
201 202
202 void VideoSender::ScheduleNextRtcpReport() { 203 void VideoSender::ScheduleNextRtcpReport() {
203 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 204 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
204 base::TimeDelta time_to_next = rtcp_->TimeToSendNextRtcpReport() - 205 base::TimeDelta time_to_next = rtcp_->TimeToSendNextRtcpReport() -
205 cast_environment_->Clock()->NowTicks(); 206 cast_environment_->Clock()->NowTicks();
206 207
207 time_to_next = std::max( 208 time_to_next = std::max(
208 time_to_next, base::TimeDelta::FromMilliseconds(kMinSchedulingDelayMs)); 209 time_to_next, base::TimeDelta::FromMilliseconds(kMinSchedulingDelayMs));
209 210
210 cast_environment_->PostDelayedTask( 211 cast_environment_->PostDelayedTask(
211 CastEnvironment::MAIN, 212 CastEnvironment::MAIN,
212 FROM_HERE, 213 FROM_HERE,
213 base::Bind(&VideoSender::SendRtcpReport, weak_factory_.GetWeakPtr()), 214 base::Bind(&VideoSender::SendRtcpReport,
215 weak_factory_.GetWeakPtr(),
216 true),
214 time_to_next); 217 time_to_next);
215 } 218 }
216 219
217 void VideoSender::SendRtcpReport() { 220 void VideoSender::SendRtcpReport(bool schedule_future_reports) {
218 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 221 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
219 const base::TimeTicks now = cast_environment_->Clock()->NowTicks(); 222 const base::TimeTicks now = cast_environment_->Clock()->NowTicks();
220 uint32 now_as_rtp_timestamp = 0; 223 uint32 now_as_rtp_timestamp = 0;
221 if (rtp_timestamp_helper_.GetCurrentTimeAsRtpTimestamp( 224 if (rtp_timestamp_helper_.GetCurrentTimeAsRtpTimestamp(
222 now, &now_as_rtp_timestamp)) { 225 now, &now_as_rtp_timestamp)) {
223 rtcp_->SendRtcpFromRtpSender(now, now_as_rtp_timestamp); 226 rtcp_->SendRtcpFromRtpSender(now, now_as_rtp_timestamp);
227 } else {
228 // |rtp_timestamp_helper_| should have stored a mapping by this point.
229 NOTREACHED();
224 } 230 }
225 ScheduleNextRtcpReport(); 231 if (schedule_future_reports)
232 ScheduleNextRtcpReport();
226 } 233 }
227 234
228 void VideoSender::ScheduleNextResendCheck() { 235 void VideoSender::ScheduleNextResendCheck() {
229 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 236 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
230 base::TimeDelta time_to_next; 237 base::TimeDelta time_to_next;
231 if (last_send_time_.is_null()) { 238 if (last_send_time_.is_null()) {
232 time_to_next = rtp_max_delay_; 239 time_to_next = rtp_max_delay_;
233 } else { 240 } else {
234 time_to_next = last_send_time_ - cast_environment_->Clock()->NowTicks() + 241 time_to_next = last_send_time_ - cast_environment_->Clock()->NowTicks() +
235 rtp_max_delay_; 242 rtp_max_delay_;
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
306 void VideoSender::OnReceivedCastFeedback(const RtcpCastMessage& cast_feedback) { 313 void VideoSender::OnReceivedCastFeedback(const RtcpCastMessage& cast_feedback) {
307 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 314 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
308 base::TimeDelta rtt; 315 base::TimeDelta rtt;
309 base::TimeDelta avg_rtt; 316 base::TimeDelta avg_rtt;
310 base::TimeDelta min_rtt; 317 base::TimeDelta min_rtt;
311 base::TimeDelta max_rtt; 318 base::TimeDelta max_rtt;
312 319
313 if (rtcp_->Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt)) { 320 if (rtcp_->Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt)) {
314 // Don't use a RTT lower than our average. 321 // Don't use a RTT lower than our average.
315 rtt = std::max(rtt, avg_rtt); 322 rtt = std::max(rtt, avg_rtt);
323
324 // Having the RTT values implies the receiver sent back a receiver report
325 // based on it having received a report from here. Therefore, ensure this
326 // sender stops aggressively sending reports.
327 if (num_aggressive_rtcp_reports_sent_ < kNumAggressiveReportsSentAtStart) {
328 VLOG(1) << "No longer a need to send reports aggressively (sent "
329 << num_aggressive_rtcp_reports_sent_ << ").";
330 num_aggressive_rtcp_reports_sent_ = kNumAggressiveReportsSentAtStart;
331 ScheduleNextRtcpReport();
332 }
316 } else { 333 } else {
317 // We have no measured value use default. 334 // We have no measured value use default.
318 rtt = base::TimeDelta::FromMilliseconds(kStartRttMs); 335 rtt = base::TimeDelta::FromMilliseconds(kStartRttMs);
319 } 336 }
320 if (cast_feedback.missing_frames_and_packets_.empty()) { 337 if (cast_feedback.missing_frames_and_packets_.empty()) {
321 // No lost packets. 338 // No lost packets.
322 int resend_frame = -1; 339 int resend_frame = -1;
323 if (last_sent_frame_id_ == -1) 340 if (last_sent_frame_id_ == -1)
324 return; 341 return;
325 342
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
361 ReceivedAck(cast_feedback.ack_frame_id_); 378 ReceivedAck(cast_feedback.ack_frame_id_);
362 } 379 }
363 380
364 void VideoSender::ReceivedAck(uint32 acked_frame_id) { 381 void VideoSender::ReceivedAck(uint32 acked_frame_id) {
365 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 382 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
366 if (acked_frame_id == UINT32_C(0xFFFFFFFF)) { 383 if (acked_frame_id == UINT32_C(0xFFFFFFFF)) {
367 // Receiver is sending a status message before any frames are ready to 384 // Receiver is sending a status message before any frames are ready to
368 // be acked. Ignore. 385 // be acked. Ignore.
369 return; 386 return;
370 } 387 }
371 // Start sending RTCP packets only after receiving the first ACK, i.e. only
372 // after establishing that the receiver is active.
373 if (last_acked_frame_id_ == -1) {
374 ScheduleNextRtcpReport();
375 }
376 last_acked_frame_id_ = static_cast<int>(acked_frame_id); 388 last_acked_frame_id_ = static_cast<int>(acked_frame_id);
377 base::TimeTicks now = cast_environment_->Clock()->NowTicks(); 389 base::TimeTicks now = cast_environment_->Clock()->NowTicks();
378 390
379 RtpTimestamp rtp_timestamp = 391 RtpTimestamp rtp_timestamp =
380 frame_id_to_rtp_timestamp_[acked_frame_id & 0xff]; 392 frame_id_to_rtp_timestamp_[acked_frame_id & 0xff];
381 cast_environment_->Logging()->InsertFrameEvent( 393 cast_environment_->Logging()->InsertFrameEvent(
382 now, FRAME_ACK_RECEIVED, VIDEO_EVENT, rtp_timestamp, acked_frame_id); 394 now, FRAME_ACK_RECEIVED, VIDEO_EVENT, rtp_timestamp, acked_frame_id);
383 395
384 VLOG(2) << "ReceivedAck:" << static_cast<int>(acked_frame_id); 396 VLOG(2) << "ReceivedAck:" << static_cast<int>(acked_frame_id);
385 active_session_ = true; 397 active_session_ = true;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 435
424 void VideoSender::UpdateBitrate(int new_bitrate) { 436 void VideoSender::UpdateBitrate(int new_bitrate) {
425 // Make sure we don't set the bitrate too insanely low. 437 // Make sure we don't set the bitrate too insanely low.
426 DCHECK_GT(new_bitrate, 1000); 438 DCHECK_GT(new_bitrate, 1000);
427 video_encoder_->SetBitRate(new_bitrate); 439 video_encoder_->SetBitRate(new_bitrate);
428 current_requested_bitrate_ = new_bitrate; 440 current_requested_bitrate_ = new_bitrate;
429 } 441 }
430 442
431 } // namespace cast 443 } // namespace cast
432 } // namespace media 444 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698