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

Side by Side Diff: media/cast/sender/audio_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: Based on TimeDelta rather than RTP delta. 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/audio_sender.h ('k') | media/cast/sender/frame_sender.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/audio_sender.h" 5 #include "media/cast/sender/audio_sender.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/message_loop/message_loop.h" 9 #include "base/message_loop/message_loop.h"
10 #include "media/cast/cast_defines.h" 10 #include "media/cast/cast_defines.h"
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 83
84 void AudioSender::InsertAudio(scoped_ptr<AudioBus> audio_bus, 84 void AudioSender::InsertAudio(scoped_ptr<AudioBus> audio_bus,
85 const base::TimeTicks& recorded_time) { 85 const base::TimeTicks& recorded_time) {
86 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 86 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
87 if (cast_initialization_status_ != STATUS_AUDIO_INITIALIZED) { 87 if (cast_initialization_status_ != STATUS_AUDIO_INITIALIZED) {
88 NOTREACHED(); 88 NOTREACHED();
89 return; 89 return;
90 } 90 }
91 DCHECK(audio_encoder_.get()) << "Invalid internal state"; 91 DCHECK(audio_encoder_.get()) << "Invalid internal state";
92 92
93 if (AreTooManyFramesInFlight()) { 93 if (ShouldDropNextFrame(recorded_time)) {
94 VLOG(1) << "Dropping frame due to too many frames currently in-flight."; 94 VLOG(1) << "Dropping frame due to too many frames currently in-flight.";
95 return; 95 return;
96 } 96 }
97 97
98 audio_encoder_->InsertAudio(audio_bus.Pass(), recorded_time); 98 audio_encoder_->InsertAudio(audio_bus.Pass(), recorded_time);
99 } 99 }
100 100
101 void AudioSender::SendEncodedAudioFrame( 101 void AudioSender::SendEncodedAudioFrame(
102 scoped_ptr<EncodedFrame> encoded_frame) { 102 scoped_ptr<EncodedFrame> encoded_frame) {
103 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 103 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
104 104
105 const uint32 frame_id = encoded_frame->frame_id; 105 const uint32 frame_id = encoded_frame->frame_id;
106 106
107 const bool is_first_frame_to_be_sent = last_send_time_.is_null(); 107 const bool is_first_frame_to_be_sent = last_send_time_.is_null();
108 last_send_time_ = cast_environment_->Clock()->NowTicks(); 108 last_send_time_ = cast_environment_->Clock()->NowTicks();
109 last_sent_frame_id_ = frame_id; 109 last_sent_frame_id_ = frame_id;
110 // If this is the first frame about to be sent, fake the value of 110 // If this is the first frame about to be sent, fake the value of
111 // |latest_acked_frame_id_| to indicate the receiver starts out all caught up. 111 // |latest_acked_frame_id_| to indicate the receiver starts out all caught up.
112 // Also, schedule the periodic frame re-send checks. 112 // Also, schedule the periodic frame re-send checks.
113 if (is_first_frame_to_be_sent) { 113 if (is_first_frame_to_be_sent) {
114 latest_acked_frame_id_ = frame_id - 1; 114 latest_acked_frame_id_ = frame_id - 1;
115 frame_id_to_rtp_timestamp_[latest_acked_frame_id_ & 0xff] =
116 encoded_frame->rtp_timestamp;
hubbe 2014/08/28 17:34:45 why don't we save the reference time here instead?
miu 2014/08/28 18:57:58 We never save the reference time (see line 126 bel
hubbe 2014/08/28 19:03:10 I think another map would be better than translati
miu 2014/08/28 20:37:15 Done. This led me to move a few "common members"
115 ScheduleNextResendCheck(); 117 ScheduleNextResendCheck();
116 } 118 }
117 119
118 cast_environment_->Logging()->InsertEncodedFrameEvent( 120 cast_environment_->Logging()->InsertEncodedFrameEvent(
119 last_send_time_, FRAME_ENCODED, AUDIO_EVENT, encoded_frame->rtp_timestamp, 121 last_send_time_, FRAME_ENCODED, AUDIO_EVENT, encoded_frame->rtp_timestamp,
120 frame_id, static_cast<int>(encoded_frame->data.size()), 122 frame_id, static_cast<int>(encoded_frame->data.size()),
121 encoded_frame->dependency == EncodedFrame::KEY, 123 encoded_frame->dependency == EncodedFrame::KEY,
122 configured_encoder_bitrate_); 124 configured_encoder_bitrate_);
123 // Only use lowest 8 bits as key. 125 // Only use lowest 8 bits as key.
124 frame_id_to_rtp_timestamp_[frame_id & 0xff] = encoded_frame->rtp_timestamp; 126 frame_id_to_rtp_timestamp_[frame_id & 0xff] = encoded_frame->rtp_timestamp;
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 std::vector<uint32> cancel_sending_frames; 239 std::vector<uint32> cancel_sending_frames;
238 while (latest_acked_frame_id_ != cast_feedback.ack_frame_id) { 240 while (latest_acked_frame_id_ != cast_feedback.ack_frame_id) {
239 latest_acked_frame_id_++; 241 latest_acked_frame_id_++;
240 cancel_sending_frames.push_back(latest_acked_frame_id_); 242 cancel_sending_frames.push_back(latest_acked_frame_id_);
241 } 243 }
242 transport_sender_->CancelSendingFrames(ssrc_, cancel_sending_frames); 244 transport_sender_->CancelSendingFrames(ssrc_, cancel_sending_frames);
243 latest_acked_frame_id_ = cast_feedback.ack_frame_id; 245 latest_acked_frame_id_ = cast_feedback.ack_frame_id;
244 } 246 }
245 } 247 }
246 248
247 bool AudioSender::AreTooManyFramesInFlight() const { 249 bool AudioSender::ShouldDropNextFrame(base::TimeTicks capture_time) const {
248 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 250 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
249 int frames_in_flight = 0; 251 int frames_in_flight = 0;
252 base::TimeDelta duration_in_flight;
250 if (!last_send_time_.is_null()) { 253 if (!last_send_time_.is_null()) {
251 frames_in_flight += 254 frames_in_flight =
252 static_cast<int32>(last_sent_frame_id_ - latest_acked_frame_id_); 255 static_cast<int32>(last_sent_frame_id_ - latest_acked_frame_id_);
256 if (frames_in_flight > 0) {
257 const uint32 oldest_unacked_frame_id = latest_acked_frame_id_ + 1;
258 base::TimeTicks oldest_unacked_capture_time;
259 if (rtp_timestamp_helper_.EstimateTimeTicks(
260 frame_id_to_rtp_timestamp_[oldest_unacked_frame_id & 0xff],
261 &oldest_unacked_capture_time)) {
262 duration_in_flight = capture_time - oldest_unacked_capture_time;
263 }
264 }
253 } 265 }
254 VLOG(2) << frames_in_flight 266 VLOG(2) << frames_in_flight
255 << " frames in flight; last sent: " << last_sent_frame_id_ 267 << " frames in flight; last sent: " << last_sent_frame_id_
256 << " latest acked: " << latest_acked_frame_id_; 268 << "; latest acked: " << latest_acked_frame_id_
257 return frames_in_flight >= max_unacked_frames_; 269 << "; duration in flight: "
270 << duration_in_flight.InMicroseconds() << " usec ("
271 << (target_playout_delay_ > base::TimeDelta() ?
272 100 * duration_in_flight / target_playout_delay_ :
273 kint64max) << "%)";
274 return frames_in_flight >= max_unacked_frames_ ||
275 duration_in_flight >= target_playout_delay_;
258 } 276 }
259 277
260 void AudioSender::ResendForKickstart() { 278 void AudioSender::ResendForKickstart() {
261 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 279 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
262 DCHECK(!last_send_time_.is_null()); 280 DCHECK(!last_send_time_.is_null());
263 VLOG(1) << "Resending last packet of frame " << last_sent_frame_id_ 281 VLOG(1) << "Resending last packet of frame " << last_sent_frame_id_
264 << " to kick-start."; 282 << " to kick-start.";
265 last_send_time_ = cast_environment_->Clock()->NowTicks(); 283 last_send_time_ = cast_environment_->Clock()->NowTicks();
266 transport_sender_->ResendFrameForKickstart(ssrc_, last_sent_frame_id_); 284 transport_sender_->ResendFrameForKickstart(ssrc_, last_sent_frame_id_);
267 } 285 }
268 286
269 } // namespace cast 287 } // namespace cast
270 } // namespace media 288 } // namespace media
OLDNEW
« no previous file with comments | « media/cast/sender/audio_sender.h ('k') | media/cast/sender/frame_sender.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698