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

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

Issue 545593002: [Cast] Track audio queued in encoder; account for it in ShouldDropNextFrame(). (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: 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
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 18 matching lines...) Expand all
29 CastTransportSender* const transport_sender) 29 CastTransportSender* const transport_sender)
30 : FrameSender( 30 : FrameSender(
31 cast_environment, 31 cast_environment,
32 transport_sender, 32 transport_sender,
33 base::TimeDelta::FromMilliseconds(audio_config.rtcp_interval), 33 base::TimeDelta::FromMilliseconds(audio_config.rtcp_interval),
34 audio_config.frequency, 34 audio_config.frequency,
35 audio_config.ssrc, 35 audio_config.ssrc,
36 kAudioFrameRate * 2.0, // We lie to increase max outstanding frames. 36 kAudioFrameRate * 2.0, // We lie to increase max outstanding frames.
37 audio_config.target_playout_delay), 37 audio_config.target_playout_delay),
38 configured_encoder_bitrate_(audio_config.bitrate), 38 configured_encoder_bitrate_(audio_config.bitrate),
39 samples_in_encoder_(0),
39 weak_factory_(this) { 40 weak_factory_(this) {
40 cast_initialization_status_ = STATUS_AUDIO_UNINITIALIZED; 41 cast_initialization_status_ = STATUS_AUDIO_UNINITIALIZED;
41 VLOG(1) << "max_unacked_frames " << max_unacked_frames_; 42 VLOG(1) << "max_unacked_frames " << max_unacked_frames_;
42 DCHECK_GT(max_unacked_frames_, 0); 43 DCHECK_GT(max_unacked_frames_, 0);
43 44
44 if (!audio_config.use_external_encoder) { 45 if (!audio_config.use_external_encoder) {
45 audio_encoder_.reset( 46 audio_encoder_.reset(
46 new AudioEncoder(cast_environment, 47 new AudioEncoder(cast_environment,
47 audio_config.channels, 48 audio_config.channels,
48 audio_config.frequency, 49 audio_config.frequency,
(...skipping 28 matching lines...) Expand all
77 78
78 void AudioSender::InsertAudio(scoped_ptr<AudioBus> audio_bus, 79 void AudioSender::InsertAudio(scoped_ptr<AudioBus> audio_bus,
79 const base::TimeTicks& recorded_time) { 80 const base::TimeTicks& recorded_time) {
80 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 81 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
81 if (cast_initialization_status_ != STATUS_AUDIO_INITIALIZED) { 82 if (cast_initialization_status_ != STATUS_AUDIO_INITIALIZED) {
82 NOTREACHED(); 83 NOTREACHED();
83 return; 84 return;
84 } 85 }
85 DCHECK(audio_encoder_.get()) << "Invalid internal state"; 86 DCHECK(audio_encoder_.get()) << "Invalid internal state";
86 87
88 // TODO(miu): An |audio_bus| that represents more duration than a single
89 // frame's duration can defeat our logic here, causing too much data to become
90 // enqueued. This will be addressed in a soon-upcoming change.
87 if (ShouldDropNextFrame(recorded_time)) { 91 if (ShouldDropNextFrame(recorded_time)) {
88 VLOG(1) << "Dropping frame due to too many frames currently in-flight."; 92 VLOG(1) << "Dropping frame due to too many frames currently in-flight.";
89 return; 93 return;
90 } 94 }
91 95
96 UpdateEncoderBacklogStats(+audio_bus->frames());
Alpha Left Google 2014/09/05 20:02:06 What's with the '+'?
miu 2014/09/05 20:40:27 Readability thing. Just a helper to see that this
97
92 audio_encoder_->InsertAudio(audio_bus.Pass(), recorded_time); 98 audio_encoder_->InsertAudio(audio_bus.Pass(), recorded_time);
93 } 99 }
94 100
101 void AudioSender::UpdateEncoderBacklogStats(int samples_added) {
102 samples_in_encoder_ += samples_added;
103 DCHECK_GE(samples_in_encoder_, 0);
104 frames_in_encoder_ =
105 samples_in_encoder_ / audio_encoder_->GetSamplesPerFrame();
106 }
107
95 void AudioSender::SendEncodedAudioFrame( 108 void AudioSender::SendEncodedAudioFrame(
96 scoped_ptr<EncodedFrame> encoded_frame) { 109 scoped_ptr<EncodedFrame> encoded_frame,
110 int samples_skipped) {
97 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 111 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
98 112
113 UpdateEncoderBacklogStats(
114 -(audio_encoder_->GetSamplesPerFrame() + samples_skipped));
115
99 const uint32 frame_id = encoded_frame->frame_id; 116 const uint32 frame_id = encoded_frame->frame_id;
100 117
101 const bool is_first_frame_to_be_sent = last_send_time_.is_null(); 118 const bool is_first_frame_to_be_sent = last_send_time_.is_null();
102 last_send_time_ = cast_environment_->Clock()->NowTicks(); 119 last_send_time_ = cast_environment_->Clock()->NowTicks();
103 last_sent_frame_id_ = frame_id; 120 last_sent_frame_id_ = frame_id;
104 // If this is the first frame about to be sent, fake the value of 121 // If this is the first frame about to be sent, fake the value of
105 // |latest_acked_frame_id_| to indicate the receiver starts out all caught up. 122 // |latest_acked_frame_id_| to indicate the receiver starts out all caught up.
106 // Also, schedule the periodic frame re-send checks. 123 // Also, schedule the periodic frame re-send checks.
107 if (is_first_frame_to_be_sent) { 124 if (is_first_frame_to_be_sent) {
108 latest_acked_frame_id_ = frame_id - 1; 125 latest_acked_frame_id_ = frame_id - 1;
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
195 std::vector<uint32> cancel_sending_frames; 212 std::vector<uint32> cancel_sending_frames;
196 while (latest_acked_frame_id_ != cast_feedback.ack_frame_id) { 213 while (latest_acked_frame_id_ != cast_feedback.ack_frame_id) {
197 latest_acked_frame_id_++; 214 latest_acked_frame_id_++;
198 cancel_sending_frames.push_back(latest_acked_frame_id_); 215 cancel_sending_frames.push_back(latest_acked_frame_id_);
199 } 216 }
200 transport_sender_->CancelSendingFrames(ssrc_, cancel_sending_frames); 217 transport_sender_->CancelSendingFrames(ssrc_, cancel_sending_frames);
201 latest_acked_frame_id_ = cast_feedback.ack_frame_id; 218 latest_acked_frame_id_ = cast_feedback.ack_frame_id;
202 } 219 }
203 } 220 }
204 221
205 bool AudioSender::ShouldDropNextFrame(base::TimeTicks capture_time) const {
206 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
207 int frames_in_flight = 0;
208 base::TimeDelta duration_in_flight;
209 if (!last_send_time_.is_null()) {
210 frames_in_flight =
211 static_cast<int32>(last_sent_frame_id_ - latest_acked_frame_id_);
212 if (frames_in_flight > 0) {
213 const uint32 oldest_unacked_frame_id = latest_acked_frame_id_ + 1;
214 duration_in_flight =
215 capture_time - GetRecordedReferenceTime(oldest_unacked_frame_id);
216 }
217 }
218 VLOG(2) << frames_in_flight
219 << " frames in flight; last sent: " << last_sent_frame_id_
220 << "; latest acked: " << latest_acked_frame_id_
221 << "; duration in flight: "
222 << duration_in_flight.InMicroseconds() << " usec ("
223 << (target_playout_delay_ > base::TimeDelta() ?
224 100 * duration_in_flight / target_playout_delay_ :
225 kint64max) << "%)";
226 return frames_in_flight >= max_unacked_frames_ ||
227 duration_in_flight >= target_playout_delay_;
228 }
229
230 } // namespace cast 222 } // namespace cast
231 } // namespace media 223 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698