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

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

Issue 387933005: Cast: Refactor RTCP handling (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: smaller diff Created 6 years, 5 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/sender/video_sender.h" 5 #include "media/cast/sender/video_sender.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cstring> 8 #include <cstring>
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/net/cast_transport_config.h" 15 #include "media/cast/net/cast_transport_config.h"
16 #include "media/cast/net/rtcp/rtcp_defines.h" 16 #include "media/cast/net/rtcp/rtcp_defines.h"
miu 2014/07/16 19:58:03 Remove this include.
Alpha Left Google 2014/07/17 01:01:46 Done.
17 #include "media/cast/sender/external_video_encoder.h" 17 #include "media/cast/sender/external_video_encoder.h"
18 #include "media/cast/sender/video_encoder_impl.h" 18 #include "media/cast/sender/video_encoder_impl.h"
19 19
20 namespace media { 20 namespace media {
21 namespace cast { 21 namespace cast {
22 22
23 const int kNumAggressiveReportsSentAtStart = 100; 23 const int kNumAggressiveReportsSentAtStart = 100;
24 const int kMinSchedulingDelayMs = 1; 24 const int kMinSchedulingDelayMs = 1;
25 25
26 VideoSender::VideoSender( 26 VideoSender::VideoSender(
27 scoped_refptr<CastEnvironment> cast_environment, 27 scoped_refptr<CastEnvironment> cast_environment,
28 const VideoSenderConfig& video_config, 28 const VideoSenderConfig& video_config,
29 const CreateVideoEncodeAcceleratorCallback& create_vea_cb, 29 const CreateVideoEncodeAcceleratorCallback& create_vea_cb,
30 const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb, 30 const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb,
31 CastTransportSender* const transport_sender) 31 CastTransportSender* const transport_sender)
32 : cast_environment_(cast_environment), 32 : FrameSender(
33 cast_environment,
34 transport_sender,
35 base::TimeDelta::FromMilliseconds(video_config.rtcp_interval),
36 kVideoFrequency,
37 false),
33 target_playout_delay_(video_config.target_playout_delay), 38 target_playout_delay_(video_config.target_playout_delay),
34 transport_sender_(transport_sender),
35 max_unacked_frames_( 39 max_unacked_frames_(
36 std::min(kMaxUnackedFrames, 40 std::min(kMaxUnackedFrames,
37 1 + static_cast<int>(target_playout_delay_ * 41 1 + static_cast<int>(target_playout_delay_ *
38 video_config.max_frame_rate / 42 video_config.max_frame_rate /
39 base::TimeDelta::FromSeconds(1)))), 43 base::TimeDelta::FromSeconds(1)))),
40 rtcp_(cast_environment_,
41 this,
42 transport_sender_,
43 NULL, // paced sender.
44 NULL,
45 video_config.rtcp_mode,
46 base::TimeDelta::FromMilliseconds(video_config.rtcp_interval),
47 video_config.ssrc,
48 video_config.incoming_feedback_ssrc,
49 video_config.rtcp_c_name,
50 VIDEO_EVENT),
51 rtp_timestamp_helper_(kVideoFrequency),
52 num_aggressive_rtcp_reports_sent_(0), 44 num_aggressive_rtcp_reports_sent_(0),
53 frames_in_encoder_(0), 45 frames_in_encoder_(0),
54 last_sent_frame_id_(0), 46 last_sent_frame_id_(0),
55 latest_acked_frame_id_(0), 47 latest_acked_frame_id_(0),
56 duplicate_ack_counter_(0), 48 duplicate_ack_counter_(0),
57 congestion_control_(cast_environment->Clock(), 49 congestion_control_(cast_environment->Clock(),
58 video_config.max_bitrate, 50 video_config.max_bitrate,
59 video_config.min_bitrate, 51 video_config.min_bitrate,
60 max_unacked_frames_), 52 max_unacked_frames_),
61 cast_initialization_status_(STATUS_VIDEO_UNINITIALIZED), 53 cast_initialization_status_(STATUS_VIDEO_UNINITIALIZED),
62 weak_factory_(this) { 54 weak_factory_(this) {
63 VLOG(1) << "max_unacked_frames " << max_unacked_frames_; 55 VLOG(1) << "max_unacked_frames " << max_unacked_frames_;
64 DCHECK_GT(max_unacked_frames_, 0); 56 DCHECK_GT(max_unacked_frames_, 0);
65 57
66 if (video_config.use_external_encoder) { 58 if (video_config.use_external_encoder) {
67 video_encoder_.reset(new ExternalVideoEncoder(cast_environment, 59 video_encoder_.reset(new ExternalVideoEncoder(cast_environment,
68 video_config, 60 video_config,
69 create_vea_cb, 61 create_vea_cb,
70 create_video_encode_mem_cb)); 62 create_video_encode_mem_cb));
71 } else { 63 } else {
72 video_encoder_.reset(new VideoEncoderImpl( 64 video_encoder_.reset(new VideoEncoderImpl(
73 cast_environment, video_config, max_unacked_frames_)); 65 cast_environment, video_config, max_unacked_frames_));
74 } 66 }
75 cast_initialization_status_ = STATUS_VIDEO_INITIALIZED; 67 cast_initialization_status_ = STATUS_VIDEO_INITIALIZED;
76 68
77 media::cast::CastTransportRtpConfig transport_config; 69 media::cast::CastTransportRtpConfig transport_config;
78 transport_config.ssrc = video_config.ssrc; 70 transport_config.ssrc = video_config.ssrc;
71 transport_config.feedback_ssrc = video_config.incoming_feedback_ssrc;
72 transport_config.c_name = video_config.rtcp_c_name;
79 transport_config.rtp_payload_type = video_config.rtp_payload_type; 73 transport_config.rtp_payload_type = video_config.rtp_payload_type;
80 transport_config.stored_frames = max_unacked_frames_; 74 transport_config.stored_frames = max_unacked_frames_;
81 transport_config.aes_key = video_config.aes_key; 75 transport_config.aes_key = video_config.aes_key;
82 transport_config.aes_iv_mask = video_config.aes_iv_mask; 76 transport_config.aes_iv_mask = video_config.aes_iv_mask;
83 transport_sender_->InitializeVideo(transport_config);
84 77
85 rtcp_.SetCastReceiverEventHistorySize(kReceiverRtcpEventHistorySize); 78 transport_sender->InitializeVideo(
79 transport_config,
80 base::Bind(&VideoSender::OnReceivedCastFeedback,
81 weak_factory_.GetWeakPtr()),
82 base::Bind(&VideoSender::OnReceivedRtt, weak_factory_.GetWeakPtr()));
86 83
87 memset(frame_id_to_rtp_timestamp_, 0, sizeof(frame_id_to_rtp_timestamp_)); 84 memset(frame_id_to_rtp_timestamp_, 0, sizeof(frame_id_to_rtp_timestamp_));
88 } 85 }
89 86
90 VideoSender::~VideoSender() { 87 VideoSender::~VideoSender() {
91 } 88 }
92 89
93 void VideoSender::InsertRawVideoFrame( 90 void VideoSender::InsertRawVideoFrame(
94 const scoped_refptr<media::VideoFrame>& video_frame, 91 const scoped_refptr<media::VideoFrame>& video_frame,
95 const base::TimeTicks& capture_time) { 92 const base::TimeTicks& capture_time) {
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
195 VLOG_IF(1, is_last_aggressive_report) << "Sending last aggressive report."; 192 VLOG_IF(1, is_last_aggressive_report) << "Sending last aggressive report.";
196 SendRtcpReport(is_last_aggressive_report); 193 SendRtcpReport(is_last_aggressive_report);
197 } 194 }
198 195
199 congestion_control_.SendFrameToTransport( 196 congestion_control_.SendFrameToTransport(
200 frame_id, encoded_frame->data.size() * 8, last_send_time_); 197 frame_id, encoded_frame->data.size() * 8, last_send_time_);
201 198
202 transport_sender_->InsertCodedVideoFrame(*encoded_frame); 199 transport_sender_->InsertCodedVideoFrame(*encoded_frame);
203 } 200 }
204 201
205 void VideoSender::IncomingRtcpPacket(scoped_ptr<Packet> packet) { 202 void VideoSender::ResendCheck() {
206 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 203 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
207 rtcp_.IncomingRtcpPacket(&packet->front(), packet->size()); 204 DCHECK(!last_send_time_.is_null());
208 } 205 const base::TimeDelta time_since_last_send =
209 206 cast_environment_->Clock()->NowTicks() - last_send_time_;
210 void VideoSender::ScheduleNextRtcpReport() { 207 if (time_since_last_send > target_playout_delay_) {
211 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 208 if (latest_acked_frame_id_ == last_sent_frame_id_) {
212 base::TimeDelta time_to_next = rtcp_.TimeToSendNextRtcpReport() - 209 // Last frame acked, no point in doing anything
213 cast_environment_->Clock()->NowTicks(); 210 } else {
214 211 VLOG(1) << "ACK timeout; last acked frame: " << latest_acked_frame_id_;
215 time_to_next = std::max( 212 ResendForKickstart();
216 time_to_next, base::TimeDelta::FromMilliseconds(kMinSchedulingDelayMs)); 213 }
217
218 cast_environment_->PostDelayedTask(
219 CastEnvironment::MAIN,
220 FROM_HERE,
221 base::Bind(&VideoSender::SendRtcpReport,
222 weak_factory_.GetWeakPtr(),
223 true),
224 time_to_next);
225 }
226
227 void VideoSender::SendRtcpReport(bool schedule_future_reports) {
228 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
229 const base::TimeTicks now = cast_environment_->Clock()->NowTicks();
230 uint32 now_as_rtp_timestamp = 0;
231 if (rtp_timestamp_helper_.GetCurrentTimeAsRtpTimestamp(
232 now, &now_as_rtp_timestamp)) {
233 rtcp_.SendRtcpFromRtpSender(now, now_as_rtp_timestamp);
234 } else {
235 // |rtp_timestamp_helper_| should have stored a mapping by this point.
236 NOTREACHED();
237 } 214 }
238 if (schedule_future_reports) 215 ScheduleNextResendCheck();
239 ScheduleNextRtcpReport();
240 } 216 }
241 217
242 void VideoSender::ScheduleNextResendCheck() { 218 void VideoSender::ScheduleNextResendCheck() {
243 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 219 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
244 DCHECK(!last_send_time_.is_null()); 220 DCHECK(!last_send_time_.is_null());
245 base::TimeDelta time_to_next = 221 base::TimeDelta time_to_next =
246 last_send_time_ - cast_environment_->Clock()->NowTicks() + 222 last_send_time_ - cast_environment_->Clock()->NowTicks() +
247 target_playout_delay_; 223 target_playout_delay_;
248 time_to_next = std::max( 224 time_to_next = std::max(
249 time_to_next, base::TimeDelta::FromMilliseconds(kMinSchedulingDelayMs)); 225 time_to_next, base::TimeDelta::FromMilliseconds(kMinSchedulingDelayMs));
250 cast_environment_->PostDelayedTask( 226 cast_environment_->PostDelayedTask(
251 CastEnvironment::MAIN, 227 CastEnvironment::MAIN,
252 FROM_HERE, 228 FROM_HERE,
253 base::Bind(&VideoSender::ResendCheck, weak_factory_.GetWeakPtr()), 229 base::Bind(&VideoSender::ResendCheck, weak_factory_.GetWeakPtr()),
254 time_to_next); 230 time_to_next);
255 } 231 }
256 232
257 void VideoSender::ResendCheck() {
258 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
259 DCHECK(!last_send_time_.is_null());
260 const base::TimeDelta time_since_last_send =
261 cast_environment_->Clock()->NowTicks() - last_send_time_;
262 if (time_since_last_send > target_playout_delay_) {
263 if (latest_acked_frame_id_ == last_sent_frame_id_) {
264 // Last frame acked, no point in doing anything
265 } else {
266 VLOG(1) << "ACK timeout; last acked frame: " << latest_acked_frame_id_;
267 ResendForKickstart();
268 }
269 }
270 ScheduleNextResendCheck();
271 }
272
273 void VideoSender::OnReceivedCastFeedback(const RtcpCastMessage& cast_feedback) { 233 void VideoSender::OnReceivedCastFeedback(const RtcpCastMessage& cast_feedback) {
274 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 234 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
275 235
276 base::TimeDelta rtt; 236 base::TimeDelta rtt;
277 base::TimeDelta avg_rtt; 237 base::TimeDelta avg_rtt;
278 base::TimeDelta min_rtt; 238 base::TimeDelta min_rtt;
279 base::TimeDelta max_rtt; 239 base::TimeDelta max_rtt;
280 if (rtcp_.Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt)) { 240 if (is_rtt_available()) {
241 rtt = rtt_;
242 avg_rtt = avg_rtt_;
243 min_rtt = min_rtt_;
244 max_rtt = max_rtt_;
245
281 congestion_control_.UpdateRtt(rtt); 246 congestion_control_.UpdateRtt(rtt);
282 247
283 // Don't use a RTT lower than our average. 248 // Don't use a RTT lower than our average.
284 rtt = std::max(rtt, avg_rtt); 249 rtt = std::max(rtt, avg_rtt);
285 250
286 // Having the RTT values implies the receiver sent back a receiver report 251 // Having the RTT values implies the receiver sent back a receiver report
287 // based on it having received a report from here. Therefore, ensure this 252 // based on it having received a report from here. Therefore, ensure this
288 // sender stops aggressively sending reports. 253 // sender stops aggressively sending reports.
289 if (num_aggressive_rtcp_reports_sent_ < kNumAggressiveReportsSentAtStart) { 254 if (num_aggressive_rtcp_reports_sent_ < kNumAggressiveReportsSentAtStart) {
290 VLOG(1) << "No longer a need to send reports aggressively (sent " 255 VLOG(1) << "No longer a need to send reports aggressively (sent "
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
377 // Send the first packet of the last encoded frame to kick start 342 // Send the first packet of the last encoded frame to kick start
378 // retransmission. This gives enough information to the receiver what 343 // retransmission. This gives enough information to the receiver what
379 // packets and frames are missing. 344 // packets and frames are missing.
380 MissingFramesAndPacketsMap missing_frames_and_packets; 345 MissingFramesAndPacketsMap missing_frames_and_packets;
381 PacketIdSet missing; 346 PacketIdSet missing;
382 missing.insert(kRtcpCastLastPacket); 347 missing.insert(kRtcpCastLastPacket);
383 missing_frames_and_packets.insert( 348 missing_frames_and_packets.insert(
384 std::make_pair(last_sent_frame_id_, missing)); 349 std::make_pair(last_sent_frame_id_, missing));
385 last_send_time_ = cast_environment_->Clock()->NowTicks(); 350 last_send_time_ = cast_environment_->Clock()->NowTicks();
386 351
387 base::TimeDelta rtt;
388 base::TimeDelta avg_rtt;
389 base::TimeDelta min_rtt;
390 base::TimeDelta max_rtt;
391 rtcp_.Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt);
392
393 // Sending this extra packet is to kick-start the session. There is 352 // Sending this extra packet is to kick-start the session. There is
394 // no need to optimize re-transmission for this case. 353 // no need to optimize re-transmission for this case.
395 transport_sender_->ResendPackets(false, missing_frames_and_packets, 354 transport_sender_->ResendPackets(false, missing_frames_and_packets,
396 false, rtt); 355 false, rtt_);
397 } 356 }
398 357
399 } // namespace cast 358 } // namespace cast
400 } // namespace media 359 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698