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

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: Addressed comments 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() == kAesKeySize &&
131 video_config.aes_key.size() == kAesKeySize) {
132 iv_mask_ = video_config.aes_iv_mask;
133 crypto::SymmetricKey* key = crypto::SymmetricKey::Import(
134 crypto::SymmetricKey::AES, video_config.aes_key);
135 decryptor_.reset(new crypto::Encryptor());
136 decryptor_->Init(key, crypto::Encryptor::CTR, std::string());
137 } else if (video_config.aes_iv_mask.size() != 0 ||
138 video_config.aes_key.size() != 0) {
139 DCHECK(false) << "Invalid crypto configuration";
140 }
141
128 framer_.reset(new Framer(cast_environment->Clock(), 142 framer_.reset(new Framer(cast_environment->Clock(),
129 incoming_payload_feedback_.get(), 143 incoming_payload_feedback_.get(),
130 video_config.incoming_ssrc, 144 video_config.incoming_ssrc,
131 video_config.decoder_faster_than_max_frame_rate, 145 video_config.decoder_faster_than_max_frame_rate,
132 max_unacked_frames)); 146 max_unacked_frames));
133 if (!video_config.use_external_decoder) { 147 if (!video_config.use_external_decoder) {
134 video_decoder_.reset(new VideoDecoder(video_config)); 148 video_decoder_.reset(new VideoDecoder(video_config));
135 } 149 }
136 150
137 rtcp_.reset( 151 rtcp_.reset(
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 base::Bind(frame_decoded_callback, 207 base::Bind(frame_decoded_callback,
194 base::Passed(&video_frame), render_time)); 208 base::Passed(&video_frame), render_time));
195 } else { 209 } else {
196 // This will happen if we decide to decode but not show a frame. 210 // This will happen if we decide to decode but not show a frame.
197 cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE, 211 cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE,
198 base::Bind(&VideoReceiver::GetRawVideoFrame, 212 base::Bind(&VideoReceiver::GetRawVideoFrame,
199 weak_factory_.GetWeakPtr(), frame_decoded_callback)); 213 weak_factory_.GetWeakPtr(), frame_decoded_callback));
200 } 214 }
201 } 215 }
202 216
217 bool VideoReceiver::DecryptVideoFrame(
218 scoped_ptr<EncodedVideoFrame>* video_frame) {
219 DCHECK(decryptor_) << "Invalid state";
220
221 scoped_ptr<EncodedVideoFrame> decrypted_video_frame(
222 new EncodedVideoFrame());
223
224 // TODO(pwestin): the frame id must be a 32 bit number.
225 decryptor_->SetCounter(GetAesNounce((*video_frame)->frame_id, iv_mask_));
226
227 if (!decryptor_->Decrypt((*video_frame)->data,
228 &decrypted_video_frame->data)) {
229 return false;
230 }
231 decrypted_video_frame->codec = (*video_frame)->codec;
232 decrypted_video_frame->key_frame = (*video_frame)->key_frame;
233 decrypted_video_frame->frame_id = (*video_frame)->frame_id;
234 decrypted_video_frame->last_referenced_frame_id =
235 (*video_frame)->last_referenced_frame_id;
236
237 video_frame->swap(decrypted_video_frame);
238 return true;
239 }
240
203 // Called from the main cast thread. 241 // Called from the main cast thread.
204 void VideoReceiver::GetEncodedVideoFrame( 242 void VideoReceiver::GetEncodedVideoFrame(
205 const VideoFrameEncodedCallback& callback) { 243 const VideoFrameEncodedCallback& callback) {
206 scoped_ptr<EncodedVideoFrame> encoded_frame(new EncodedVideoFrame()); 244 scoped_ptr<EncodedVideoFrame> encoded_frame(new EncodedVideoFrame());
207 uint32 rtp_timestamp = 0; 245 uint32 rtp_timestamp = 0;
208 bool next_frame = false; 246 bool next_frame = false;
209 247
210 if (!framer_->GetEncodedVideoFrame(encoded_frame.get(), &rtp_timestamp, 248 if (!framer_->GetEncodedVideoFrame(encoded_frame.get(), &rtp_timestamp,
211 &next_frame)) { 249 &next_frame)) {
212 // We have no video frames. Wait for new packet(s). 250 // We have no video frames. Wait for new packet(s).
213 queued_encoded_callbacks_.push_back(callback); 251 queued_encoded_callbacks_.push_back(callback);
214 return; 252 return;
215 } 253 }
254
255 if (decryptor_) {
256 if (!DecryptVideoFrame(&encoded_frame)) {
257 DCHECK(false) << "Decryption error";
258 return;
259 }
260 }
261
216 base::TimeTicks render_time; 262 base::TimeTicks render_time;
217 if (PullEncodedVideoFrame(rtp_timestamp, next_frame, &encoded_frame, 263 if (PullEncodedVideoFrame(rtp_timestamp, next_frame, &encoded_frame,
218 &render_time)) { 264 &render_time)) {
219 cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE, 265 cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE,
220 base::Bind(callback, base::Passed(&encoded_frame), render_time)); 266 base::Bind(callback, base::Passed(&encoded_frame), render_time));
221 } else { 267 } else {
222 // We have a video frame; however we are missing packets and we have time 268 // We have a video frame; however we are missing packets and we have time
223 // to wait for new packet(s). 269 // to wait for new packet(s).
224 queued_encoded_callbacks_.push_back(callback); 270 queued_encoded_callbacks_.push_back(callback);
225 } 271 }
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 // We have no video frames. Wait for new packet(s). 332 // We have no video frames. Wait for new packet(s).
287 // Since the application can post multiple VideoFrameEncodedCallback and 333 // Since the application can post multiple VideoFrameEncodedCallback and
288 // we only check the next frame to play out we might have multiple timeout 334 // 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. 335 // 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"; 336 VLOG(1) << "Failed to retrieved a complete frame at this point in time";
291 return; 337 return;
292 } 338 }
293 VLOG(1) << "PlayoutTimeout retrieved frame " 339 VLOG(1) << "PlayoutTimeout retrieved frame "
294 << static_cast<int>(encoded_frame->frame_id); 340 << static_cast<int>(encoded_frame->frame_id);
295 341
342 if (decryptor_) {
343 if (!DecryptVideoFrame(&encoded_frame)) {
344 DCHECK(false) << "Decryption error";
345 return;
346 }
347 }
348
296 base::TimeTicks render_time; 349 base::TimeTicks render_time;
297 if (PullEncodedVideoFrame(rtp_timestamp, next_frame, &encoded_frame, 350 if (PullEncodedVideoFrame(rtp_timestamp, next_frame, &encoded_frame,
298 &render_time)) { 351 &render_time)) {
299 if (!queued_encoded_callbacks_.empty()) { 352 if (!queued_encoded_callbacks_.empty()) {
300 VideoFrameEncodedCallback callback = queued_encoded_callbacks_.front(); 353 VideoFrameEncodedCallback callback = queued_encoded_callbacks_.front();
301 queued_encoded_callbacks_.pop_front(); 354 queued_encoded_callbacks_.pop_front();
302 cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE, 355 cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE,
303 base::Bind(callback, base::Passed(&encoded_frame), render_time)); 356 base::Bind(callback, base::Passed(&encoded_frame), render_time));
304 } 357 }
305 } else { 358 } else {
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
419 weak_factory_.GetWeakPtr()), time_to_next); 472 weak_factory_.GetWeakPtr()), time_to_next);
420 } 473 }
421 474
422 void VideoReceiver::SendNextRtcpReport() { 475 void VideoReceiver::SendNextRtcpReport() {
423 rtcp_->SendRtcpReport(incoming_ssrc_); 476 rtcp_->SendRtcpReport(incoming_ssrc_);
424 ScheduleNextRtcpReport(); 477 ScheduleNextRtcpReport();
425 } 478 }
426 479
427 } // namespace cast 480 } // namespace cast
428 } // namespace media 481 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698