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

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

Issue 62843002: Cast: Added support for AES-CTR crypto. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed nits Created 7 years, 1 month 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 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/video_receiver/video_receiver.h" 5 #include "media/cast/video_receiver/video_receiver.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8
8 #include "base/bind.h" 9 #include "base/bind.h"
9 #include "base/logging.h" 10 #include "base/logging.h"
10 #include "base/message_loop/message_loop.h" 11 #include "base/message_loop/message_loop.h"
12 #include "crypto/symmetric_key.h"
11 #include "media/cast/cast_defines.h" 13 #include "media/cast/cast_defines.h"
12 #include "media/cast/framer/framer.h" 14 #include "media/cast/framer/framer.h"
13 #include "media/cast/video_receiver/video_decoder.h" 15 #include "media/cast/video_receiver/video_decoder.h"
14 16
15 namespace media { 17 namespace media {
16 namespace cast { 18 namespace cast {
17 19
18 const int64 kMinSchedulingDelayMs = 1; 20 const int64 kMinSchedulingDelayMs = 1;
19 21
20 static const int64 kMinTimeBetweenOffsetUpdatesMs = 2000; 22 static const int64 kMinTimeBetweenOffsetUpdatesMs = 2000;
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 incoming_payload_feedback_(new LocalRtpVideoFeedback(this)), 120 incoming_payload_feedback_(new LocalRtpVideoFeedback(this)),
119 rtp_receiver_(cast_environment_->Clock(), NULL, &video_config, 121 rtp_receiver_(cast_environment_->Clock(), NULL, &video_config,
120 incoming_payload_callback_.get()), 122 incoming_payload_callback_.get()),
121 rtp_video_receiver_statistics_( 123 rtp_video_receiver_statistics_(
122 new LocalRtpReceiverStatistics(&rtp_receiver_)), 124 new LocalRtpReceiverStatistics(&rtp_receiver_)),
123 weak_factory_(this) { 125 weak_factory_(this) {
124 int max_unacked_frames = video_config.rtp_max_delay_ms * 126 int max_unacked_frames = video_config.rtp_max_delay_ms *
125 video_config.max_frame_rate / 1000; 127 video_config.max_frame_rate / 1000;
126 DCHECK(max_unacked_frames) << "Invalid argument"; 128 DCHECK(max_unacked_frames) << "Invalid argument";
127 129
130 if (video_config.aes_iv_mask.size() == kAesBlockSize * 2 &&
131 video_config.aes_key.size() == kAesBlockSize * 2) {
132 iv_mask_ = ConvertFromBase16String(video_config.aes_iv_mask);
133 crypto::SymmetricKey* key = crypto::SymmetricKey::Import(
134 crypto::SymmetricKey::AES,
135 ConvertFromBase16String(video_config.aes_key));
Alpha Left Google 2013/11/07 01:10:11 Again don't do the conversion in this low level st
pwestin 2013/11/07 17:16:04 Done.
136 encryptor_.reset(new crypto::Encryptor());
137 encryptor_->Init(key, crypto::Encryptor::CTR, std::string());
138 } else if (video_config.aes_iv_mask.size() != 0 ||
139 video_config.aes_iv_mask.size() != 0) {
140 DCHECK(false) << "Invalid crypto configuration";
141 }
142
128 framer_.reset(new Framer(cast_environment->Clock(), 143 framer_.reset(new Framer(cast_environment->Clock(),
129 incoming_payload_feedback_.get(), 144 incoming_payload_feedback_.get(),
130 video_config.incoming_ssrc, 145 video_config.incoming_ssrc,
131 video_config.decoder_faster_than_max_frame_rate, 146 video_config.decoder_faster_than_max_frame_rate,
132 max_unacked_frames)); 147 max_unacked_frames));
133 if (!video_config.use_external_decoder) { 148 if (!video_config.use_external_decoder) {
134 video_decoder_.reset(new VideoDecoder(video_config)); 149 video_decoder_.reset(new VideoDecoder(video_config));
135 } 150 }
136 151
137 rtcp_.reset( 152 rtcp_.reset(
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 base::Bind(frame_decoded_callback, 208 base::Bind(frame_decoded_callback,
194 base::Passed(&video_frame), render_time)); 209 base::Passed(&video_frame), render_time));
195 } else { 210 } else {
196 // This will happen if we decide to decode but not show a frame. 211 // This will happen if we decide to decode but not show a frame.
197 cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE, 212 cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE,
198 base::Bind(&VideoReceiver::GetRawVideoFrame, 213 base::Bind(&VideoReceiver::GetRawVideoFrame,
199 weak_factory_.GetWeakPtr(), frame_decoded_callback)); 214 weak_factory_.GetWeakPtr(), frame_decoded_callback));
200 } 215 }
201 } 216 }
202 217
218 bool VideoReceiver::DecryptVideoFrame(
219 const EncodedVideoFrame* encrypted_frame,
220 EncodedVideoFrame* video_frame) {
221 DCHECK(encryptor_) << "Invalid state";
222
223 // TODO(pwestin): the frame id must be a 32 bit number.
224 encryptor_->SetCounter(GetAesNounce(encrypted_frame->frame_id, iv_mask_));
225
226 video_frame->codec = encrypted_frame->codec;
227 video_frame->key_frame = encrypted_frame->key_frame;
228 video_frame->frame_id = encrypted_frame->frame_id;
229 video_frame->last_referenced_frame_id =
230 encrypted_frame->last_referenced_frame_id;
231
232 return encryptor_->Decrypt(encrypted_frame->data, &video_frame->data);
233 }
234
203 // Called from the main cast thread. 235 // Called from the main cast thread.
204 void VideoReceiver::GetEncodedVideoFrame( 236 void VideoReceiver::GetEncodedVideoFrame(
205 const VideoFrameEncodedCallback& callback) { 237 const VideoFrameEncodedCallback& callback) {
206 scoped_ptr<EncodedVideoFrame> encoded_frame(new EncodedVideoFrame()); 238 scoped_ptr<EncodedVideoFrame> encoded_frame(new EncodedVideoFrame());
207 uint32 rtp_timestamp = 0; 239 uint32 rtp_timestamp = 0;
208 bool next_frame = false; 240 bool next_frame = false;
209 241
210 if (!framer_->GetEncodedVideoFrame(encoded_frame.get(), &rtp_timestamp, 242 if (!framer_->GetEncodedVideoFrame(encoded_frame.get(), &rtp_timestamp,
211 &next_frame)) { 243 &next_frame)) {
212 // We have no video frames. Wait for new packet(s). 244 // We have no video frames. Wait for new packet(s).
213 queued_encoded_callbacks_.push_back(callback); 245 queued_encoded_callbacks_.push_back(callback);
214 return; 246 return;
215 } 247 }
248
249 if (encryptor_) {
250 EncodedVideoFrame* decrypted_video_frame = new EncodedVideoFrame();
Alpha Left Google 2013/11/07 01:10:11 This should be a scoped_ptr<T>.
pwestin 2013/11/07 17:16:04 Done.
251
252 if (DecryptVideoFrame(encoded_frame.get(), decrypted_video_frame)) {
253 encoded_frame.reset(decrypted_video_frame);
254 } else {
255 DCHECK(false) << "Decryption error";
256 return;
257 }
258 }
259
216 base::TimeTicks render_time; 260 base::TimeTicks render_time;
217 if (PullEncodedVideoFrame(rtp_timestamp, next_frame, &encoded_frame, 261 if (PullEncodedVideoFrame(rtp_timestamp, next_frame, &encoded_frame,
218 &render_time)) { 262 &render_time)) {
219 cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE, 263 cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE,
220 base::Bind(callback, base::Passed(&encoded_frame), render_time)); 264 base::Bind(callback, base::Passed(&encoded_frame), render_time));
221 } else { 265 } else {
222 // We have a video frame; however we are missing packets and we have time 266 // We have a video frame; however we are missing packets and we have time
223 // to wait for new packet(s). 267 // to wait for new packet(s).
224 queued_encoded_callbacks_.push_back(callback); 268 queued_encoded_callbacks_.push_back(callback);
225 } 269 }
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 // We have no video frames. Wait for new packet(s). 330 // We have no video frames. Wait for new packet(s).
287 // Since the application can post multiple VideoFrameEncodedCallback and 331 // Since the application can post multiple VideoFrameEncodedCallback and
288 // we only check the next frame to play out we might have multiple timeout 332 // we only check the next frame to play out we might have multiple timeout
289 // events firing after each other; however this should be a rare event. 333 // events firing after each other; however this should be a rare event.
290 VLOG(1) << "Failed to retrieved a complete frame at this point in time"; 334 VLOG(1) << "Failed to retrieved a complete frame at this point in time";
291 return; 335 return;
292 } 336 }
293 VLOG(1) << "PlayoutTimeout retrieved frame " 337 VLOG(1) << "PlayoutTimeout retrieved frame "
294 << static_cast<int>(encoded_frame->frame_id); 338 << static_cast<int>(encoded_frame->frame_id);
295 339
340 if (encryptor_) {
341 EncodedVideoFrame* decrypted_video_frame = new EncodedVideoFrame();
Alpha Left Google 2013/11/07 01:10:11 Same here, use scoped_ptr<T>.
pwestin 2013/11/07 17:16:04 Done.
342
343 if (DecryptVideoFrame(encoded_frame.get(), decrypted_video_frame)) {
344 encoded_frame.reset(decrypted_video_frame);
345 } else {
346 DCHECK(false) << "Decryption error";
347 delete decrypted_video_frame;
348 return;
349 }
350 }
351
296 base::TimeTicks render_time; 352 base::TimeTicks render_time;
297 if (PullEncodedVideoFrame(rtp_timestamp, next_frame, &encoded_frame, 353 if (PullEncodedVideoFrame(rtp_timestamp, next_frame, &encoded_frame,
298 &render_time)) { 354 &render_time)) {
299 if (!queued_encoded_callbacks_.empty()) { 355 if (!queued_encoded_callbacks_.empty()) {
300 VideoFrameEncodedCallback callback = queued_encoded_callbacks_.front(); 356 VideoFrameEncodedCallback callback = queued_encoded_callbacks_.front();
301 queued_encoded_callbacks_.pop_front(); 357 queued_encoded_callbacks_.pop_front();
302 cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE, 358 cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE,
303 base::Bind(callback, base::Passed(&encoded_frame), render_time)); 359 base::Bind(callback, base::Passed(&encoded_frame), render_time));
304 } 360 }
305 } else { 361 } else {
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
419 weak_factory_.GetWeakPtr()), time_to_next); 475 weak_factory_.GetWeakPtr()), time_to_next);
420 } 476 }
421 477
422 void VideoReceiver::SendNextRtcpReport() { 478 void VideoReceiver::SendNextRtcpReport() {
423 rtcp_->SendRtcpReport(incoming_ssrc_); 479 rtcp_->SendRtcpReport(incoming_ssrc_);
424 ScheduleNextRtcpReport(); 480 ScheduleNextRtcpReport();
425 } 481 }
426 482
427 } // namespace cast 483 } // namespace cast
428 } // namespace media 484 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698