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

Side by Side Diff: media/cast/audio_receiver/audio_receiver.cc

Issue 138843011: Cast: Adding helper crypto classes (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Responding to review Created 6 years, 10 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 | Annotate | Revision Log
OLDNEW
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 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 if (audio_config.use_external_decoder) { 93 if (audio_config.use_external_decoder) {
94 audio_buffer_.reset(new Framer(cast_environment->Clock(), 94 audio_buffer_.reset(new Framer(cast_environment->Clock(),
95 incoming_payload_feedback_.get(), 95 incoming_payload_feedback_.get(),
96 audio_config.incoming_ssrc, 96 audio_config.incoming_ssrc,
97 true, 97 true,
98 0)); 98 0));
99 } else { 99 } else {
100 audio_decoder_.reset(new AudioDecoder( 100 audio_decoder_.reset(new AudioDecoder(
101 cast_environment, audio_config, incoming_payload_feedback_.get())); 101 cast_environment, audio_config, incoming_payload_feedback_.get()));
102 } 102 }
103 if (audio_config.aes_iv_mask.size() == kAesKeySize && 103 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(), 104 rtp_receiver_.reset(new RtpReceiver(cast_environment->Clock(),
117 &audio_config, 105 &audio_config,
118 NULL, 106 NULL,
119 incoming_payload_callback_.get())); 107 incoming_payload_callback_.get()));
120 rtp_audio_receiver_statistics_.reset( 108 rtp_audio_receiver_statistics_.reset(
121 new LocalRtpReceiverStatistics(rtp_receiver_.get())); 109 new LocalRtpReceiverStatistics(rtp_receiver_.get()));
122 base::TimeDelta rtcp_interval_delta = 110 base::TimeDelta rtcp_interval_delta =
123 base::TimeDelta::FromMilliseconds(audio_config.rtcp_interval); 111 base::TimeDelta::FromMilliseconds(audio_config.rtcp_interval);
124 rtcp_.reset(new Rtcp(cast_environment, 112 rtcp_.reset(new Rtcp(cast_environment,
125 NULL, 113 NULL,
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 // TODO(pwestin): update this as video to refresh over time. 148 // TODO(pwestin): update this as video to refresh over time.
161 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 149 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
162 if (time_first_incoming_packet_.is_null()) { 150 if (time_first_incoming_packet_.is_null()) {
163 InitializeTimers(); 151 InitializeTimers();
164 first_incoming_rtp_timestamp_ = rtp_header.webrtc.header.timestamp; 152 first_incoming_rtp_timestamp_ = rtp_header.webrtc.header.timestamp;
165 time_first_incoming_packet_ = now; 153 time_first_incoming_packet_ = now;
166 } 154 }
167 155
168 if (audio_decoder_) { 156 if (audio_decoder_) {
169 DCHECK(!audio_buffer_) << "Invalid internal state"; 157 DCHECK(!audio_buffer_) << "Invalid internal state";
170 std::string plaintext(reinterpret_cast<const char*>(payload_data), 158 std::string plaintext;
171 payload_size); 159 if (decryptor_.initialized()) {
172 if (decryptor_) { 160 if (!decryptor_.Decrypt(
173 plaintext.clear(); 161 rtp_header.frame_id,
174 if (!decryptor_->SetCounter(GetAesNonce(rtp_header.frame_id, iv_mask_))) {
175 NOTREACHED() << "Failed to set counter";
176 return;
177 }
178 if (!decryptor_->Decrypt(
179 base::StringPiece(reinterpret_cast<const char*>(payload_data), 162 base::StringPiece(reinterpret_cast<const char*>(payload_data),
180 payload_size), 163 payload_size),
181 &plaintext)) { 164 &plaintext))
182 VLOG(1) << "Decryption error";
183 return; 165 return;
184 } 166 } else {
167 plaintext = std::string(reinterpret_cast<const char*>(payload_data),
hubbe 2014/01/31 18:30:39 Won't this copy the data twice? Perhaps use append
168 payload_size);
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
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
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
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
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
OLDNEW
« no previous file with comments | « media/cast/audio_receiver/audio_receiver.h ('k') | media/cast/audio_receiver/audio_receiver.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698