OLD | NEW |
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/audio_receiver/audio_receiver.h" | 5 #include "media/cast/audio_receiver/audio_receiver.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/message_loop/message_loop.h" | 11 #include "base/message_loop/message_loop.h" |
12 #include "media/cast/audio_receiver/audio_decoder.h" | 12 #include "media/cast/audio_receiver/audio_decoder.h" |
13 #include "media/cast/transport/cast_transport_defines.h" | 13 #include "media/cast/transport/cast_transport_defines.h" |
14 | 14 |
15 namespace { | 15 namespace { |
16 const int kMinSchedulingDelayMs = 1; | 16 const int kMinSchedulingDelayMs = 1; |
17 // TODO(miu): This should go in AudioReceiverConfig. | |
18 const int kTypicalAudioFrameDurationMs = 10; | |
19 } // namespace | 17 } // namespace |
20 | 18 |
21 namespace media { | 19 namespace media { |
22 namespace cast { | 20 namespace cast { |
23 | 21 |
24 AudioReceiver::AudioReceiver(scoped_refptr<CastEnvironment> cast_environment, | 22 AudioReceiver::AudioReceiver(scoped_refptr<CastEnvironment> cast_environment, |
25 const AudioReceiverConfig& audio_config, | 23 const FrameReceiverConfig& audio_config, |
26 transport::PacedPacketSender* const packet_sender) | 24 transport::PacedPacketSender* const packet_sender) |
27 : RtpReceiver(cast_environment->Clock(), &audio_config, NULL), | 25 : RtpReceiver(cast_environment->Clock(), &audio_config, NULL), |
28 cast_environment_(cast_environment), | 26 cast_environment_(cast_environment), |
29 event_subscriber_(kReceiverRtcpEventHistorySize, AUDIO_EVENT), | 27 event_subscriber_(kReceiverRtcpEventHistorySize, AUDIO_EVENT), |
30 codec_(audio_config.codec), | 28 codec_(audio_config.codec.audio), |
31 frequency_(audio_config.frequency), | 29 frequency_(audio_config.frequency), |
32 target_playout_delay_( | 30 target_playout_delay_( |
33 base::TimeDelta::FromMilliseconds(audio_config.rtp_max_delay_ms)), | 31 base::TimeDelta::FromMilliseconds(audio_config.rtp_max_delay_ms)), |
| 32 expected_frame_duration_( |
| 33 base::TimeDelta::FromSeconds(1) / audio_config.max_frame_rate), |
34 reports_are_scheduled_(false), | 34 reports_are_scheduled_(false), |
35 framer_(cast_environment->Clock(), | 35 framer_(cast_environment->Clock(), |
36 this, | 36 this, |
37 audio_config.incoming_ssrc, | 37 audio_config.incoming_ssrc, |
38 true, | 38 true, |
39 audio_config.rtp_max_delay_ms / kTypicalAudioFrameDurationMs), | 39 audio_config.rtp_max_delay_ms * audio_config.max_frame_rate / |
| 40 1000), |
40 rtcp_(cast_environment, | 41 rtcp_(cast_environment, |
41 NULL, | 42 NULL, |
42 NULL, | 43 NULL, |
43 packet_sender, | 44 packet_sender, |
44 GetStatistics(), | 45 GetStatistics(), |
45 audio_config.rtcp_mode, | 46 audio_config.rtcp_mode, |
46 base::TimeDelta::FromMilliseconds(audio_config.rtcp_interval), | 47 base::TimeDelta::FromMilliseconds(audio_config.rtcp_interval), |
47 audio_config.feedback_ssrc, | 48 audio_config.feedback_ssrc, |
48 audio_config.incoming_ssrc, | 49 audio_config.incoming_ssrc, |
49 audio_config.rtcp_c_name, | 50 audio_config.rtcp_c_name, |
50 true), | 51 true), |
51 is_waiting_for_consecutive_frame_(false), | 52 is_waiting_for_consecutive_frame_(false), |
52 lip_sync_drift_(ClockDriftSmoother::GetDefaultTimeConstant()), | 53 lip_sync_drift_(ClockDriftSmoother::GetDefaultTimeConstant()), |
53 weak_factory_(this) { | 54 weak_factory_(this) { |
54 if (!audio_config.use_external_decoder) | 55 DCHECK_GT(audio_config.rtp_max_delay_ms, 0); |
55 audio_decoder_.reset(new AudioDecoder(cast_environment, audio_config)); | 56 DCHECK_GT(audio_config.max_frame_rate, 0); |
| 57 audio_decoder_.reset(new AudioDecoder(cast_environment, audio_config)); |
56 decryptor_.Initialize(audio_config.aes_key, audio_config.aes_iv_mask); | 58 decryptor_.Initialize(audio_config.aes_key, audio_config.aes_iv_mask); |
57 rtcp_.SetTargetDelay(target_playout_delay_); | 59 rtcp_.SetTargetDelay(target_playout_delay_); |
58 cast_environment_->Logging()->AddRawEventSubscriber(&event_subscriber_); | 60 cast_environment_->Logging()->AddRawEventSubscriber(&event_subscriber_); |
59 memset(frame_id_to_rtp_timestamp_, 0, sizeof(frame_id_to_rtp_timestamp_)); | 61 memset(frame_id_to_rtp_timestamp_, 0, sizeof(frame_id_to_rtp_timestamp_)); |
60 } | 62 } |
61 | 63 |
62 AudioReceiver::~AudioReceiver() { | 64 AudioReceiver::~AudioReceiver() { |
63 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 65 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
64 cast_environment_->Logging()->RemoveRawEventSubscriber(&event_subscriber_); | 66 cast_environment_->Logging()->RemoveRawEventSubscriber(&event_subscriber_); |
65 } | 67 } |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 continue; | 214 continue; |
213 } | 215 } |
214 | 216 |
215 // If |framer_| has a frame ready that is out of sequence, examine the | 217 // If |framer_| has a frame ready that is out of sequence, examine the |
216 // playout time to determine whether it's acceptable to continue, thereby | 218 // playout time to determine whether it's acceptable to continue, thereby |
217 // skipping one or more frames. Skip if the missing frame wouldn't complete | 219 // skipping one or more frames. Skip if the missing frame wouldn't complete |
218 // playing before the start of playback of the available frame. | 220 // playing before the start of playback of the available frame. |
219 if (!is_consecutively_next_frame) { | 221 if (!is_consecutively_next_frame) { |
220 // TODO(miu): Also account for expected decode time here? | 222 // TODO(miu): Also account for expected decode time here? |
221 const base::TimeTicks earliest_possible_end_time_of_missing_frame = | 223 const base::TimeTicks earliest_possible_end_time_of_missing_frame = |
222 now + base::TimeDelta::FromMilliseconds(kTypicalAudioFrameDurationMs); | 224 now + expected_frame_duration_; |
223 if (earliest_possible_end_time_of_missing_frame < playout_time) { | 225 if (earliest_possible_end_time_of_missing_frame < playout_time) { |
224 VLOG(1) << "Wait for next consecutive frame instead of skipping."; | 226 VLOG(1) << "Wait for next consecutive frame instead of skipping."; |
225 if (!is_waiting_for_consecutive_frame_) { | 227 if (!is_waiting_for_consecutive_frame_) { |
226 is_waiting_for_consecutive_frame_ = true; | 228 is_waiting_for_consecutive_frame_ = true; |
227 cast_environment_->PostDelayedTask( | 229 cast_environment_->PostDelayedTask( |
228 CastEnvironment::MAIN, | 230 CastEnvironment::MAIN, |
229 FROM_HERE, | 231 FROM_HERE, |
230 base::Bind(&AudioReceiver::EmitAvailableEncodedFramesAfterWaiting, | 232 base::Bind(&AudioReceiver::EmitAvailableEncodedFramesAfterWaiting, |
231 weak_factory_.GetWeakPtr()), | 233 weak_factory_.GetWeakPtr()), |
232 playout_time - now); | 234 playout_time - now); |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
346 } | 348 } |
347 | 349 |
348 void AudioReceiver::SendNextCastMessage() { | 350 void AudioReceiver::SendNextCastMessage() { |
349 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 351 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
350 framer_.SendCastMessage(); // Will only send a message if it is time. | 352 framer_.SendCastMessage(); // Will only send a message if it is time. |
351 ScheduleNextCastMessage(); | 353 ScheduleNextCastMessage(); |
352 } | 354 } |
353 | 355 |
354 } // namespace cast | 356 } // namespace cast |
355 } // namespace media | 357 } // namespace media |
OLD | NEW |