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

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

Issue 502333002: [Cast] In Audio/VideoSender, drop frames when too-long a duration is in-flight. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix missing brace (rebase oops). Created 6 years, 3 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
« no previous file with comments | « media/cast/sender/video_sender.h ('k') | media/cast/sender/vp8_encoder.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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"
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 rtp_timestamp, 112 rtp_timestamp,
113 kFrameIdUnknown); 113 kFrameIdUnknown);
114 114
115 // Used by chrome/browser/extension/api/cast_streaming/performance_test.cc 115 // Used by chrome/browser/extension/api/cast_streaming/performance_test.cc
116 TRACE_EVENT_INSTANT2( 116 TRACE_EVENT_INSTANT2(
117 "cast_perf_test", "InsertRawVideoFrame", 117 "cast_perf_test", "InsertRawVideoFrame",
118 TRACE_EVENT_SCOPE_THREAD, 118 TRACE_EVENT_SCOPE_THREAD,
119 "timestamp", capture_time.ToInternalValue(), 119 "timestamp", capture_time.ToInternalValue(),
120 "rtp_timestamp", rtp_timestamp); 120 "rtp_timestamp", rtp_timestamp);
121 121
122 if (AreTooManyFramesInFlight()) { 122 if (ShouldDropNextFrame(capture_time)) {
123 VLOG(1) << "Dropping frame due to too many frames currently in-flight."; 123 VLOG(1) << "Dropping frame due to too many frames currently in-flight.";
124 return; 124 return;
125 } 125 }
126 126
127 uint32 bitrate = fixed_bitrate_; 127 uint32 bitrate = fixed_bitrate_;
128 if (!bitrate) { 128 if (!bitrate) {
129 bitrate = congestion_control_.GetBitrate( 129 bitrate = congestion_control_.GetBitrate(
130 capture_time + target_playout_delay_, target_playout_delay_); 130 capture_time + target_playout_delay_, target_playout_delay_);
131 DCHECK(bitrate); 131 DCHECK(bitrate);
132 video_encoder_->SetBitRate(bitrate); 132 video_encoder_->SetBitRate(bitrate);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
171 } 171 }
172 172
173 VLOG_IF(1, encoded_frame->dependency == EncodedFrame::KEY) 173 VLOG_IF(1, encoded_frame->dependency == EncodedFrame::KEY)
174 << "Send encoded key frame; frame_id: " << frame_id; 174 << "Send encoded key frame; frame_id: " << frame_id;
175 175
176 cast_environment_->Logging()->InsertEncodedFrameEvent( 176 cast_environment_->Logging()->InsertEncodedFrameEvent(
177 last_send_time_, FRAME_ENCODED, VIDEO_EVENT, encoded_frame->rtp_timestamp, 177 last_send_time_, FRAME_ENCODED, VIDEO_EVENT, encoded_frame->rtp_timestamp,
178 frame_id, static_cast<int>(encoded_frame->data.size()), 178 frame_id, static_cast<int>(encoded_frame->data.size()),
179 encoded_frame->dependency == EncodedFrame::KEY, 179 encoded_frame->dependency == EncodedFrame::KEY,
180 requested_bitrate_before_encode); 180 requested_bitrate_before_encode);
181 // Only use lowest 8 bits as key. 181
182 frame_id_to_rtp_timestamp_[frame_id & 0xff] = encoded_frame->rtp_timestamp; 182 RecordLatestFrameTimestamps(frame_id,
183 encoded_frame->reference_time,
184 encoded_frame->rtp_timestamp);
183 185
184 // Used by chrome/browser/extension/api/cast_streaming/performance_test.cc 186 // Used by chrome/browser/extension/api/cast_streaming/performance_test.cc
185 TRACE_EVENT_INSTANT1( 187 TRACE_EVENT_INSTANT1(
186 "cast_perf_test", "VideoFrameEncoded", 188 "cast_perf_test", "VideoFrameEncoded",
187 TRACE_EVENT_SCOPE_THREAD, 189 TRACE_EVENT_SCOPE_THREAD,
188 "rtp_timestamp", encoded_frame->rtp_timestamp); 190 "rtp_timestamp", encoded_frame->rtp_timestamp);
189 191
190 DCHECK(!encoded_frame->reference_time.is_null());
191 rtp_timestamp_helper_.StoreLatestTime(encoded_frame->reference_time,
192 encoded_frame->rtp_timestamp);
193
194 // At the start of the session, it's important to send reports before each 192 // At the start of the session, it's important to send reports before each
195 // frame so that the receiver can properly compute playout times. The reason 193 // frame so that the receiver can properly compute playout times. The reason
196 // more than one report is sent is because transmission is not guaranteed, 194 // more than one report is sent is because transmission is not guaranteed,
197 // only best effort, so send enough that one should almost certainly get 195 // only best effort, so send enough that one should almost certainly get
198 // through. 196 // through.
199 if (num_aggressive_rtcp_reports_sent_ < kNumAggressiveReportsSentAtStart) { 197 if (num_aggressive_rtcp_reports_sent_ < kNumAggressiveReportsSentAtStart) {
200 // SendRtcpReport() will schedule future reports to be made if this is the 198 // SendRtcpReport() will schedule future reports to be made if this is the
201 // last "aggressive report." 199 // last "aggressive report."
202 ++num_aggressive_rtcp_reports_sent_; 200 ++num_aggressive_rtcp_reports_sent_;
203 const bool is_last_aggressive_report = 201 const bool is_last_aggressive_report =
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 } 266 }
269 } else { 267 } else {
270 // Only count duplicated ACKs if there is no NACK request in between. 268 // Only count duplicated ACKs if there is no NACK request in between.
271 // This is to avoid aggresive resend. 269 // This is to avoid aggresive resend.
272 duplicate_ack_counter_ = 0; 270 duplicate_ack_counter_ = 0;
273 } 271 }
274 272
275 base::TimeTicks now = cast_environment_->Clock()->NowTicks(); 273 base::TimeTicks now = cast_environment_->Clock()->NowTicks();
276 congestion_control_.AckFrame(cast_feedback.ack_frame_id, now); 274 congestion_control_.AckFrame(cast_feedback.ack_frame_id, now);
277 275
278 RtpTimestamp rtp_timestamp = 276 cast_environment_->Logging()->InsertFrameEvent(
279 frame_id_to_rtp_timestamp_[cast_feedback.ack_frame_id & 0xff]; 277 now,
280 cast_environment_->Logging()->InsertFrameEvent(now, 278 FRAME_ACK_RECEIVED,
281 FRAME_ACK_RECEIVED, 279 VIDEO_EVENT,
282 VIDEO_EVENT, 280 GetRecordedRtpTimestamp(cast_feedback.ack_frame_id),
283 rtp_timestamp, 281 cast_feedback.ack_frame_id);
284 cast_feedback.ack_frame_id);
285 282
286 const bool is_acked_out_of_order = 283 const bool is_acked_out_of_order =
287 static_cast<int32>(cast_feedback.ack_frame_id - 284 static_cast<int32>(cast_feedback.ack_frame_id -
288 latest_acked_frame_id_) < 0; 285 latest_acked_frame_id_) < 0;
289 VLOG(2) << "Received ACK" << (is_acked_out_of_order ? " out-of-order" : "") 286 VLOG(2) << "Received ACK" << (is_acked_out_of_order ? " out-of-order" : "")
290 << " for frame " << cast_feedback.ack_frame_id; 287 << " for frame " << cast_feedback.ack_frame_id;
291 if (!is_acked_out_of_order) { 288 if (!is_acked_out_of_order) {
292 // Cancel resends of acked frames. 289 // Cancel resends of acked frames.
293 std::vector<uint32> cancel_sending_frames; 290 std::vector<uint32> cancel_sending_frames;
294 while (latest_acked_frame_id_ != cast_feedback.ack_frame_id) { 291 while (latest_acked_frame_id_ != cast_feedback.ack_frame_id) {
295 latest_acked_frame_id_++; 292 latest_acked_frame_id_++;
296 cancel_sending_frames.push_back(latest_acked_frame_id_); 293 cancel_sending_frames.push_back(latest_acked_frame_id_);
297 } 294 }
298 transport_sender_->CancelSendingFrames(ssrc_, cancel_sending_frames); 295 transport_sender_->CancelSendingFrames(ssrc_, cancel_sending_frames);
299 latest_acked_frame_id_ = cast_feedback.ack_frame_id; 296 latest_acked_frame_id_ = cast_feedback.ack_frame_id;
300 } 297 }
301 } 298 }
302 299
303 bool VideoSender::AreTooManyFramesInFlight() const { 300 bool VideoSender::ShouldDropNextFrame(base::TimeTicks capture_time) const {
304 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 301 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
305 int frames_in_flight = frames_in_encoder_; 302 int frames_in_flight = 0;
303 base::TimeDelta duration_in_flight;
306 if (!last_send_time_.is_null()) { 304 if (!last_send_time_.is_null()) {
307 frames_in_flight += 305 frames_in_flight =
308 static_cast<int32>(last_sent_frame_id_ - latest_acked_frame_id_); 306 static_cast<int32>(last_sent_frame_id_ - latest_acked_frame_id_);
307 if (frames_in_flight > 0) {
308 const uint32 oldest_unacked_frame_id = latest_acked_frame_id_ + 1;
309 duration_in_flight =
310 capture_time - GetRecordedReferenceTime(oldest_unacked_frame_id);
311 }
309 } 312 }
313 frames_in_flight += frames_in_encoder_;
310 VLOG(2) << frames_in_flight 314 VLOG(2) << frames_in_flight
311 << " frames in flight; last sent: " << last_sent_frame_id_ 315 << " frames in flight; last sent: " << last_sent_frame_id_
312 << " latest acked: " << latest_acked_frame_id_ 316 << "; latest acked: " << latest_acked_frame_id_
313 << " frames in encoder: " << frames_in_encoder_; 317 << "; frames in encoder: " << frames_in_encoder_
314 return frames_in_flight >= max_unacked_frames_; 318 << "; duration in flight: "
319 << duration_in_flight.InMicroseconds() << " usec ("
320 << (target_playout_delay_ > base::TimeDelta() ?
321 100 * duration_in_flight / target_playout_delay_ :
322 kint64max) << "%)";
323 return frames_in_flight >= max_unacked_frames_ ||
324 duration_in_flight >= target_playout_delay_;
315 } 325 }
316 326
317 } // namespace cast 327 } // namespace cast
318 } // namespace media 328 } // namespace media
OLDNEW
« no previous file with comments | « media/cast/sender/video_sender.h ('k') | media/cast/sender/vp8_encoder.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698