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 "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 "crypto/encryptor.h" | 10 #include "base/strings/string_piece.h" |
11 #include "crypto/symmetric_key.h" | |
12 #include "media/cast/audio_receiver/audio_decoder.h" | 11 #include "media/cast/audio_receiver/audio_decoder.h" |
13 #include "media/cast/framer/framer.h" | 12 #include "media/cast/framer/framer.h" |
14 #include "media/cast/rtcp/rtcp.h" | 13 #include "media/cast/rtcp/rtcp.h" |
15 #include "media/cast/rtp_receiver/rtp_receiver.h" | 14 #include "media/cast/rtp_receiver/rtp_receiver.h" |
15 #include "media/cast/transport/cast_transport_defines.h" | |
16 | 16 |
17 // Max time we wait until an audio frame is due to be played out is released. | 17 // Max time we wait until an audio frame is due to be played out is released. |
18 static const int64 kMaxAudioFrameWaitMs = 20; | 18 static const int64 kMaxAudioFrameWaitMs = 20; |
19 static const int64 kMinSchedulingDelayMs = 1; | 19 static const int64 kMinSchedulingDelayMs = 1; |
20 | 20 |
21 namespace media { | 21 namespace media { |
22 namespace cast { | 22 namespace cast { |
23 | 23 |
24 DecodedAudioCallbackData::DecodedAudioCallbackData() | 24 DecodedAudioCallbackData::DecodedAudioCallbackData() |
25 : number_of_10ms_blocks(0), desired_frequency(0), callback() {} | 25 : number_of_10ms_blocks(0), desired_frequency(0), callback() {} |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
78 | 78 |
79 AudioReceiver::AudioReceiver(scoped_refptr<CastEnvironment> cast_environment, | 79 AudioReceiver::AudioReceiver(scoped_refptr<CastEnvironment> cast_environment, |
80 const AudioReceiverConfig& audio_config, | 80 const AudioReceiverConfig& audio_config, |
81 transport::PacedPacketSender* const packet_sender) | 81 transport::PacedPacketSender* const packet_sender) |
82 : cast_environment_(cast_environment), | 82 : cast_environment_(cast_environment), |
83 codec_(audio_config.codec), | 83 codec_(audio_config.codec), |
84 frequency_(audio_config.frequency), | 84 frequency_(audio_config.frequency), |
85 audio_buffer_(), | 85 audio_buffer_(), |
86 audio_decoder_(), | 86 audio_decoder_(), |
87 time_offset_(), | 87 time_offset_(), |
88 decryptor_(), | |
hubbe
2014/01/31 17:46:22
There is no need to call the default constructor,
mikhal1
2014/01/31 18:22:47
Done.
| |
88 weak_factory_(this) { | 89 weak_factory_(this) { |
89 target_delay_delta_ = | 90 target_delay_delta_ = |
90 base::TimeDelta::FromMilliseconds(audio_config.rtp_max_delay_ms); | 91 base::TimeDelta::FromMilliseconds(audio_config.rtp_max_delay_ms); |
91 incoming_payload_callback_.reset(new LocalRtpAudioData(this)); | 92 incoming_payload_callback_.reset(new LocalRtpAudioData(this)); |
92 incoming_payload_feedback_.reset(new LocalRtpAudioFeedback(this)); | 93 incoming_payload_feedback_.reset(new LocalRtpAudioFeedback(this)); |
93 if (audio_config.use_external_decoder) { | 94 if (audio_config.use_external_decoder) { |
94 audio_buffer_.reset(new Framer(cast_environment->Clock(), | 95 audio_buffer_.reset(new Framer(cast_environment->Clock(), |
95 incoming_payload_feedback_.get(), | 96 incoming_payload_feedback_.get(), |
96 audio_config.incoming_ssrc, | 97 audio_config.incoming_ssrc, |
97 true, | 98 true, |
98 0)); | 99 0)); |
99 } else { | 100 } else { |
100 audio_decoder_.reset(new AudioDecoder( | 101 audio_decoder_.reset(new AudioDecoder( |
101 cast_environment, audio_config, incoming_payload_feedback_.get())); | 102 cast_environment, audio_config, incoming_payload_feedback_.get())); |
102 } | 103 } |
103 if (audio_config.aes_iv_mask.size() == kAesKeySize && | 104 decryptor_.Initialize(audio_config.aes_key, audio_config.aes_iv_mask); |
104 audio_config.aes_key.size() == kAesKeySize) { | |
105 iv_mask_ = audio_config.aes_iv_mask; | |
106 decryption_key_.reset(crypto::SymmetricKey::Import( | |
107 crypto::SymmetricKey::AES, audio_config.aes_key)); | |
108 decryptor_.reset(new crypto::Encryptor()); | |
109 decryptor_->Init( | |
110 decryption_key_.get(), crypto::Encryptor::CTR, std::string()); | |
111 } else if (audio_config.aes_iv_mask.size() != 0 || | |
112 audio_config.aes_key.size() != 0) { | |
113 DCHECK(false) << "Invalid crypto configuration"; | |
114 } | |
115 | |
116 rtp_receiver_.reset(new RtpReceiver(cast_environment->Clock(), | 105 rtp_receiver_.reset(new RtpReceiver(cast_environment->Clock(), |
117 &audio_config, | 106 &audio_config, |
118 NULL, | 107 NULL, |
119 incoming_payload_callback_.get())); | 108 incoming_payload_callback_.get())); |
120 rtp_audio_receiver_statistics_.reset( | 109 rtp_audio_receiver_statistics_.reset( |
121 new LocalRtpReceiverStatistics(rtp_receiver_.get())); | 110 new LocalRtpReceiverStatistics(rtp_receiver_.get())); |
122 base::TimeDelta rtcp_interval_delta = | 111 base::TimeDelta rtcp_interval_delta = |
123 base::TimeDelta::FromMilliseconds(audio_config.rtcp_interval); | 112 base::TimeDelta::FromMilliseconds(audio_config.rtcp_interval); |
124 rtcp_.reset(new Rtcp(cast_environment, | 113 rtcp_.reset(new Rtcp(cast_environment, |
125 NULL, | 114 NULL, |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
160 // TODO(pwestin): update this as video to refresh over time. | 149 // TODO(pwestin): update this as video to refresh over time. |
161 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 150 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
162 if (time_first_incoming_packet_.is_null()) { | 151 if (time_first_incoming_packet_.is_null()) { |
163 InitializeTimers(); | 152 InitializeTimers(); |
164 first_incoming_rtp_timestamp_ = rtp_header.webrtc.header.timestamp; | 153 first_incoming_rtp_timestamp_ = rtp_header.webrtc.header.timestamp; |
165 time_first_incoming_packet_ = now; | 154 time_first_incoming_packet_ = now; |
166 } | 155 } |
167 | 156 |
168 if (audio_decoder_) { | 157 if (audio_decoder_) { |
169 DCHECK(!audio_buffer_) << "Invalid internal state"; | 158 DCHECK(!audio_buffer_) << "Invalid internal state"; |
170 std::string plaintext(reinterpret_cast<const char*>(payload_data), | 159 std::string plaintext(reinterpret_cast<const char*>(payload_data), |
hubbe
2014/01/31 17:46:22
Looks like we are copying the data into "plaintext
mikhal1
2014/01/31 18:22:47
Done.
| |
171 payload_size); | 160 payload_size); |
172 if (decryptor_) { | 161 if (decryptor_.initialized()) { |
173 plaintext.clear(); | 162 plaintext.clear(); |
174 if (!decryptor_->SetCounter(GetAesNonce(rtp_header.frame_id, iv_mask_))) { | 163 if (!decryptor_.Decrypt( |
175 NOTREACHED() << "Failed to set counter"; | 164 rtp_header.frame_id, |
176 return; | |
177 } | |
178 if (!decryptor_->Decrypt( | |
179 base::StringPiece(reinterpret_cast<const char*>(payload_data), | 165 base::StringPiece(reinterpret_cast<const char*>(payload_data), |
180 payload_size), | 166 payload_size), |
181 &plaintext)) { | 167 &plaintext)) |
182 VLOG(1) << "Decryption error"; | |
183 return; | 168 return; |
184 } | |
185 } | 169 } |
186 audio_decoder_->IncomingParsedRtpPacket( | 170 audio_decoder_->IncomingParsedRtpPacket( |
187 reinterpret_cast<const uint8*>(plaintext.data()), | 171 reinterpret_cast<const uint8*>(plaintext.data()), |
188 plaintext.size(), | 172 plaintext.size(), |
189 rtp_header); | 173 rtp_header); |
190 if (!queued_decoded_callbacks_.empty()) { | 174 if (!queued_decoded_callbacks_.empty()) { |
191 DecodedAudioCallbackData decoded_data = queued_decoded_callbacks_.front(); | 175 DecodedAudioCallbackData decoded_data = queued_decoded_callbacks_.front(); |
192 queued_decoded_callbacks_.pop_front(); | 176 queued_decoded_callbacks_.pop_front(); |
193 cast_environment_->PostTask( | 177 cast_environment_->PostTask( |
194 CastEnvironment::AUDIO_DECODER, | 178 CastEnvironment::AUDIO_DECODER, |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
320 if (!audio_buffer_->GetEncodedAudioFrame( | 304 if (!audio_buffer_->GetEncodedAudioFrame( |
321 encoded_frame.get(), &rtp_timestamp, &next_frame)) { | 305 encoded_frame.get(), &rtp_timestamp, &next_frame)) { |
322 // We have no audio frames. Wait for new packet(s). | 306 // We have no audio frames. Wait for new packet(s). |
323 // Since the application can post multiple AudioFrameEncodedCallback and | 307 // Since the application can post multiple AudioFrameEncodedCallback and |
324 // we only check the next frame to play out we might have multiple timeout | 308 // we only check the next frame to play out we might have multiple timeout |
325 // events firing after each other; however this should be a rare event. | 309 // events firing after each other; however this should be a rare event. |
326 VLOG(1) << "Failed to retrieved a complete frame at this point in time"; | 310 VLOG(1) << "Failed to retrieved a complete frame at this point in time"; |
327 return; | 311 return; |
328 } | 312 } |
329 | 313 |
330 if (decryptor_ && !DecryptAudioFrame(&encoded_frame)) { | 314 if (decryptor_.initialized() && !DecryptAudioFrame(&encoded_frame)) { |
331 // Logging already done. | 315 // Logging already done. |
332 return; | 316 return; |
333 } | 317 } |
334 | 318 |
335 if (PostEncodedAudioFrame(queued_encoded_callbacks_.front(), | 319 if (PostEncodedAudioFrame(queued_encoded_callbacks_.front(), |
336 rtp_timestamp, | 320 rtp_timestamp, |
337 next_frame, | 321 next_frame, |
338 &encoded_frame)) { | 322 &encoded_frame)) { |
339 // Call succeed remove callback from list. | 323 // Call succeed remove callback from list. |
340 queued_encoded_callbacks_.pop_front(); | 324 queued_encoded_callbacks_.pop_front(); |
(...skipping 10 matching lines...) Expand all Loading... | |
351 scoped_ptr<transport::EncodedAudioFrame> encoded_frame( | 335 scoped_ptr<transport::EncodedAudioFrame> encoded_frame( |
352 new transport::EncodedAudioFrame()); | 336 new transport::EncodedAudioFrame()); |
353 | 337 |
354 if (!audio_buffer_->GetEncodedAudioFrame( | 338 if (!audio_buffer_->GetEncodedAudioFrame( |
355 encoded_frame.get(), &rtp_timestamp, &next_frame)) { | 339 encoded_frame.get(), &rtp_timestamp, &next_frame)) { |
356 // We have no audio frames. Wait for new packet(s). | 340 // We have no audio frames. Wait for new packet(s). |
357 VLOG(1) << "Wait for more audio packets in frame"; | 341 VLOG(1) << "Wait for more audio packets in frame"; |
358 queued_encoded_callbacks_.push_back(callback); | 342 queued_encoded_callbacks_.push_back(callback); |
359 return; | 343 return; |
360 } | 344 } |
361 if (decryptor_ && !DecryptAudioFrame(&encoded_frame)) { | 345 if (decryptor_.initialized() && !DecryptAudioFrame(&encoded_frame)) { |
362 // Logging already done. | 346 // Logging already done. |
363 queued_encoded_callbacks_.push_back(callback); | 347 queued_encoded_callbacks_.push_back(callback); |
364 return; | 348 return; |
365 } | 349 } |
366 if (!PostEncodedAudioFrame( | 350 if (!PostEncodedAudioFrame( |
367 callback, rtp_timestamp, next_frame, &encoded_frame)) { | 351 callback, rtp_timestamp, next_frame, &encoded_frame)) { |
368 // We have an audio frame; however we are missing packets and we have time | 352 // We have an audio frame; however we are missing packets and we have time |
369 // to wait for new packet(s). | 353 // to wait for new packet(s). |
370 queued_encoded_callbacks_.push_back(callback); | 354 queued_encoded_callbacks_.push_back(callback); |
371 } | 355 } |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
487 } | 471 } |
488 // Don't allow the playout time to go backwards. | 472 // Don't allow the playout time to go backwards. |
489 if (last_playout_time_ > playout_time) | 473 if (last_playout_time_ > playout_time) |
490 playout_time = last_playout_time_; | 474 playout_time = last_playout_time_; |
491 last_playout_time_ = playout_time; | 475 last_playout_time_ = playout_time; |
492 return playout_time; | 476 return playout_time; |
493 } | 477 } |
494 | 478 |
495 bool AudioReceiver::DecryptAudioFrame( | 479 bool AudioReceiver::DecryptAudioFrame( |
496 scoped_ptr<transport::EncodedAudioFrame>* audio_frame) { | 480 scoped_ptr<transport::EncodedAudioFrame>* audio_frame) { |
497 DCHECK(decryptor_) << "Invalid state"; | 481 if (!decryptor_.initialized()) |
482 return false; | |
498 | 483 |
499 if (!decryptor_->SetCounter( | |
500 GetAesNonce((*audio_frame)->frame_id, iv_mask_))) { | |
501 NOTREACHED() << "Failed to set counter"; | |
502 return false; | |
503 } | |
504 std::string decrypted_audio_data; | 484 std::string decrypted_audio_data; |
505 if (!decryptor_->Decrypt((*audio_frame)->data, &decrypted_audio_data)) { | 485 if (!decryptor_.Decrypt((*audio_frame)->frame_id, |
506 VLOG(1) << "Decryption error"; | 486 (*audio_frame)->data, |
507 // Give up on this frame, release it from jitter buffer. | 487 &decrypted_audio_data)) { |
488 // Give up on this frame, release it from the jitter buffer. | |
508 audio_buffer_->ReleaseFrame((*audio_frame)->frame_id); | 489 audio_buffer_->ReleaseFrame((*audio_frame)->frame_id); |
509 return false; | 490 return false; |
510 } | 491 } |
511 (*audio_frame)->data.swap(decrypted_audio_data); | 492 (*audio_frame)->data.swap(decrypted_audio_data); |
512 return true; | 493 return true; |
513 } | 494 } |
514 | 495 |
515 void AudioReceiver::ScheduleNextRtcpReport() { | 496 void AudioReceiver::ScheduleNextRtcpReport() { |
516 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 497 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
517 base::TimeDelta time_to_send = rtcp_->TimeToSendNextRtcpReport() - | 498 base::TimeDelta time_to_send = rtcp_->TimeToSendNextRtcpReport() - |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
568 } | 549 } |
569 if (audio_decoder_) { | 550 if (audio_decoder_) { |
570 // Will only send a message if it is time. | 551 // Will only send a message if it is time. |
571 audio_decoder_->SendCastMessage(); | 552 audio_decoder_->SendCastMessage(); |
572 } | 553 } |
573 ScheduleNextCastMessage(); | 554 ScheduleNextCastMessage(); |
574 } | 555 } |
575 | 556 |
576 } // namespace cast | 557 } // namespace cast |
577 } // namespace media | 558 } // namespace media |
OLD | NEW |