OLD | NEW |
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" |
11 #include "media/cast/net/cast_transport_config.h" | 11 #include "media/cast/net/cast_transport_config.h" |
12 #include "media/cast/sender/audio_encoder.h" | 12 #include "media/cast/sender/audio_encoder.h" |
13 | 13 |
14 namespace media { | 14 namespace media { |
15 namespace cast { | 15 namespace cast { |
16 namespace { | 16 namespace { |
17 | 17 |
18 const int kNumAggressiveReportsSentAtStart = 100; | 18 const int kNumAggressiveReportsSentAtStart = 100; |
19 const int kMinSchedulingDelayMs = 1; | 19 const int kMinSchedulingDelayMs = 1; |
20 | 20 |
21 // TODO(miu): This should be specified in AudioSenderConfig, but currently it is | 21 // TODO(miu): This should be specified in AudioSenderConfig, but currently it is |
22 // fixed to 100 FPS (i.e., 10 ms per frame), and AudioEncoder assumes this as | 22 // fixed to 100 FPS (i.e., 10 ms per frame), and AudioEncoder assumes this as |
23 // well. | 23 // well. |
24 const int kAudioFrameRate = 100; | 24 const int kAudioFrameRate = 100; |
25 | 25 |
26 // Helper function to compute the maximum unacked audio frames that is sent. | |
27 int GetMaxUnackedFrames(base::TimeDelta target_delay) { | |
28 // As long as it doesn't go over |kMaxUnackedFrames|, it is okay to send more | |
29 // audio data than the target delay would suggest. Audio packets are tiny and | |
30 // receiver has the ability to drop any one of the packets. | |
31 // We send up to three times of the target delay of audio frames. | |
32 int frames = | |
33 1 + 2 * target_delay * kAudioFrameRate / base::TimeDelta::FromSeconds(1); | |
34 return std::min(kMaxUnackedFrames, frames); | |
35 } | |
36 } // namespace | 26 } // namespace |
37 | 27 |
38 AudioSender::AudioSender(scoped_refptr<CastEnvironment> cast_environment, | 28 AudioSender::AudioSender(scoped_refptr<CastEnvironment> cast_environment, |
39 const AudioSenderConfig& audio_config, | 29 const AudioSenderConfig& audio_config, |
40 CastTransportSender* const transport_sender) | 30 CastTransportSender* const transport_sender) |
41 : FrameSender( | 31 : FrameSender( |
42 cast_environment, | 32 cast_environment, |
43 transport_sender, | 33 transport_sender, |
44 base::TimeDelta::FromMilliseconds(audio_config.rtcp_interval), | 34 base::TimeDelta::FromMilliseconds(audio_config.rtcp_interval), |
45 audio_config.frequency, | 35 audio_config.frequency, |
46 audio_config.ssrc), | 36 audio_config.ssrc, |
47 target_playout_delay_(audio_config.target_playout_delay), | 37 kAudioFrameRate * 2.0, // We lie to increase max outstanding frames. |
48 max_unacked_frames_(GetMaxUnackedFrames(target_playout_delay_)), | 38 audio_config.target_playout_delay), |
49 configured_encoder_bitrate_(audio_config.bitrate), | 39 configured_encoder_bitrate_(audio_config.bitrate), |
50 num_aggressive_rtcp_reports_sent_(0), | 40 num_aggressive_rtcp_reports_sent_(0), |
51 last_sent_frame_id_(0), | 41 last_sent_frame_id_(0), |
52 latest_acked_frame_id_(0), | 42 latest_acked_frame_id_(0), |
53 duplicate_ack_counter_(0), | 43 duplicate_ack_counter_(0), |
54 cast_initialization_status_(STATUS_AUDIO_UNINITIALIZED), | 44 cast_initialization_status_(STATUS_AUDIO_UNINITIALIZED), |
55 weak_factory_(this) { | 45 weak_factory_(this) { |
56 VLOG(1) << "max_unacked_frames " << max_unacked_frames_; | 46 VLOG(1) << "max_unacked_frames " << max_unacked_frames_; |
57 DCHECK_GT(max_unacked_frames_, 0); | 47 DCHECK_GT(max_unacked_frames_, 0); |
58 | 48 |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 if (num_aggressive_rtcp_reports_sent_ < kNumAggressiveReportsSentAtStart) { | 135 if (num_aggressive_rtcp_reports_sent_ < kNumAggressiveReportsSentAtStart) { |
146 // SendRtcpReport() will schedule future reports to be made if this is the | 136 // SendRtcpReport() will schedule future reports to be made if this is the |
147 // last "aggressive report." | 137 // last "aggressive report." |
148 ++num_aggressive_rtcp_reports_sent_; | 138 ++num_aggressive_rtcp_reports_sent_; |
149 const bool is_last_aggressive_report = | 139 const bool is_last_aggressive_report = |
150 (num_aggressive_rtcp_reports_sent_ == kNumAggressiveReportsSentAtStart); | 140 (num_aggressive_rtcp_reports_sent_ == kNumAggressiveReportsSentAtStart); |
151 VLOG_IF(1, is_last_aggressive_report) << "Sending last aggressive report."; | 141 VLOG_IF(1, is_last_aggressive_report) << "Sending last aggressive report."; |
152 SendRtcpReport(is_last_aggressive_report); | 142 SendRtcpReport(is_last_aggressive_report); |
153 } | 143 } |
154 | 144 |
| 145 if (send_target_playout_delay_) { |
| 146 encoded_frame->new_playout_delay_ms = |
| 147 target_playout_delay_.InMilliseconds(); |
| 148 } |
155 transport_sender_->InsertCodedAudioFrame(*encoded_frame); | 149 transport_sender_->InsertCodedAudioFrame(*encoded_frame); |
156 } | 150 } |
157 | 151 |
158 void AudioSender::ScheduleNextResendCheck() { | 152 void AudioSender::ScheduleNextResendCheck() { |
159 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 153 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
160 DCHECK(!last_send_time_.is_null()); | 154 DCHECK(!last_send_time_.is_null()); |
161 base::TimeDelta time_to_next = | 155 base::TimeDelta time_to_next = |
162 last_send_time_ - cast_environment_->Clock()->NowTicks() + | 156 last_send_time_ - cast_environment_->Clock()->NowTicks() + |
163 target_playout_delay_; | 157 target_playout_delay_; |
164 time_to_next = std::max( | 158 time_to_next = std::max( |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
267 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 261 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
268 DCHECK(!last_send_time_.is_null()); | 262 DCHECK(!last_send_time_.is_null()); |
269 VLOG(1) << "Resending last packet of frame " << last_sent_frame_id_ | 263 VLOG(1) << "Resending last packet of frame " << last_sent_frame_id_ |
270 << " to kick-start."; | 264 << " to kick-start."; |
271 last_send_time_ = cast_environment_->Clock()->NowTicks(); | 265 last_send_time_ = cast_environment_->Clock()->NowTicks(); |
272 transport_sender_->ResendFrameForKickstart(ssrc_, last_sent_frame_id_); | 266 transport_sender_->ResendFrameForKickstart(ssrc_, last_sent_frame_id_); |
273 } | 267 } |
274 | 268 |
275 } // namespace cast | 269 } // namespace cast |
276 } // namespace media | 270 } // namespace media |
OLD | NEW |