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

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: Sync TOT 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/encryptor.h"
13 #include "crypto/symmetric_key.h"
11 #include "media/cast/cast_defines.h" 14 #include "media/cast/cast_defines.h"
12 #include "media/cast/framer/framer.h" 15 #include "media/cast/framer/framer.h"
13 #include "media/cast/video_receiver/video_decoder.h" 16 #include "media/cast/video_receiver/video_decoder.h"
14 17
15 namespace media { 18 namespace media {
16 namespace cast { 19 namespace cast {
17 20
18 const int64 kMinSchedulingDelayMs = 1; 21 const int64 kMinSchedulingDelayMs = 1;
19 22
20 static const int64 kMinTimeBetweenOffsetUpdatesMs = 2000; 23 static const int64 kMinTimeBetweenOffsetUpdatesMs = 2000;
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 incoming_payload_callback_.get()), 98 incoming_payload_callback_.get()),
96 rtp_video_receiver_statistics_( 99 rtp_video_receiver_statistics_(
97 new LocalRtpReceiverStatistics(&rtp_receiver_)), 100 new LocalRtpReceiverStatistics(&rtp_receiver_)),
98 time_incoming_packet_updated_(false), 101 time_incoming_packet_updated_(false),
99 incoming_rtp_timestamp_(0), 102 incoming_rtp_timestamp_(0),
100 weak_factory_(this) { 103 weak_factory_(this) {
101 int max_unacked_frames = video_config.rtp_max_delay_ms * 104 int max_unacked_frames = video_config.rtp_max_delay_ms *
102 video_config.max_frame_rate / 1000; 105 video_config.max_frame_rate / 1000;
103 DCHECK(max_unacked_frames) << "Invalid argument"; 106 DCHECK(max_unacked_frames) << "Invalid argument";
104 107
108 if (video_config.aes_iv_mask.size() == kAesKeySize &&
109 video_config.aes_key.size() == kAesKeySize) {
110 iv_mask_ = video_config.aes_iv_mask;
111 crypto::SymmetricKey* key = crypto::SymmetricKey::Import(
112 crypto::SymmetricKey::AES, video_config.aes_key);
113 decryptor_.reset(new crypto::Encryptor());
114 decryptor_->Init(key, crypto::Encryptor::CTR, std::string());
115 } else if (video_config.aes_iv_mask.size() != 0 ||
116 video_config.aes_key.size() != 0) {
117 DCHECK(false) << "Invalid crypto configuration";
118 }
119
105 framer_.reset(new Framer(cast_environment->Clock(), 120 framer_.reset(new Framer(cast_environment->Clock(),
106 incoming_payload_feedback_.get(), 121 incoming_payload_feedback_.get(),
107 video_config.incoming_ssrc, 122 video_config.incoming_ssrc,
108 video_config.decoder_faster_than_max_frame_rate, 123 video_config.decoder_faster_than_max_frame_rate,
109 max_unacked_frames)); 124 max_unacked_frames));
110 if (!video_config.use_external_decoder) { 125 if (!video_config.use_external_decoder) {
111 video_decoder_.reset(new VideoDecoder(video_config, cast_environment)); 126 video_decoder_.reset(new VideoDecoder(video_config, cast_environment));
112 } 127 }
113 128
114 rtcp_.reset( 129 rtcp_.reset(
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 178
164 if (!(video_decoder_->DecodeVideoFrame(encoded_frame.get(), render_time, 179 if (!(video_decoder_->DecodeVideoFrame(encoded_frame.get(), render_time,
165 frame_decoded_callback))) { 180 frame_decoded_callback))) {
166 // This will happen if we decide to decode but not show a frame. 181 // This will happen if we decide to decode but not show a frame.
167 cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE, 182 cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE,
168 base::Bind(&VideoReceiver::GetRawVideoFrame, 183 base::Bind(&VideoReceiver::GetRawVideoFrame,
169 weak_factory_.GetWeakPtr(), frame_decoded_callback)); 184 weak_factory_.GetWeakPtr(), frame_decoded_callback));
170 } 185 }
171 } 186 }
172 187
188 bool VideoReceiver::DecryptVideoFrame(
189 scoped_ptr<EncodedVideoFrame>* video_frame) {
190 DCHECK(decryptor_) << "Invalid state";
191
192 if (!decryptor_->SetCounter(GetAesNonce((*video_frame)->frame_id,
193 iv_mask_))) {
194 NOTREACHED() << "Failed to set counter";
195 return false;
196 }
197 std::string decrypted_video_data;
198 if (!decryptor_->Decrypt((*video_frame)->data, &decrypted_video_data)) {
199 VLOG(0) << "Decryption error";
200 // Give up on this frame, release it from jitter buffer.
201 framer_->ReleaseFrame((*video_frame)->frame_id);
202 return false;
203 }
204 (*video_frame)->data.swap(decrypted_video_data);
205 return true;
206 }
207
173 // Called from the main cast thread. 208 // Called from the main cast thread.
174 void VideoReceiver::GetEncodedVideoFrame( 209 void VideoReceiver::GetEncodedVideoFrame(
175 const VideoFrameEncodedCallback& callback) { 210 const VideoFrameEncodedCallback& callback) {
176 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 211 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
177 scoped_ptr<EncodedVideoFrame> encoded_frame(new EncodedVideoFrame()); 212 scoped_ptr<EncodedVideoFrame> encoded_frame(new EncodedVideoFrame());
178 uint32 rtp_timestamp = 0; 213 uint32 rtp_timestamp = 0;
179 bool next_frame = false; 214 bool next_frame = false;
180 215
181 if (!framer_->GetEncodedVideoFrame(encoded_frame.get(), &rtp_timestamp, 216 if (!framer_->GetEncodedVideoFrame(encoded_frame.get(), &rtp_timestamp,
182 &next_frame)) { 217 &next_frame)) {
183 // We have no video frames. Wait for new packet(s). 218 // We have no video frames. Wait for new packet(s).
184 queued_encoded_callbacks_.push_back(callback); 219 queued_encoded_callbacks_.push_back(callback);
185 return; 220 return;
186 } 221 }
222
223 if (decryptor_ && !DecryptVideoFrame(&encoded_frame)) {
224 // Logging already done.
225 queued_encoded_callbacks_.push_back(callback);
226 return;
227 }
228
187 base::TimeTicks render_time; 229 base::TimeTicks render_time;
188 if (PullEncodedVideoFrame(rtp_timestamp, next_frame, &encoded_frame, 230 if (PullEncodedVideoFrame(rtp_timestamp, next_frame, &encoded_frame,
189 &render_time)) { 231 &render_time)) {
190 cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE, 232 cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE,
191 base::Bind(callback, base::Passed(&encoded_frame), render_time)); 233 base::Bind(callback, base::Passed(&encoded_frame), render_time));
192 } else { 234 } else {
193 // We have a video frame; however we are missing packets and we have time 235 // We have a video frame; however we are missing packets and we have time
194 // to wait for new packet(s). 236 // to wait for new packet(s).
195 queued_encoded_callbacks_.push_back(callback); 237 queued_encoded_callbacks_.push_back(callback);
196 } 238 }
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 // We have no video frames. Wait for new packet(s). 301 // We have no video frames. Wait for new packet(s).
260 // Since the application can post multiple VideoFrameEncodedCallback and 302 // Since the application can post multiple VideoFrameEncodedCallback and
261 // we only check the next frame to play out we might have multiple timeout 303 // we only check the next frame to play out we might have multiple timeout
262 // events firing after each other; however this should be a rare event. 304 // events firing after each other; however this should be a rare event.
263 VLOG(1) << "Failed to retrieved a complete frame at this point in time"; 305 VLOG(1) << "Failed to retrieved a complete frame at this point in time";
264 return; 306 return;
265 } 307 }
266 VLOG(1) << "PlayoutTimeout retrieved frame " 308 VLOG(1) << "PlayoutTimeout retrieved frame "
267 << static_cast<int>(encoded_frame->frame_id); 309 << static_cast<int>(encoded_frame->frame_id);
268 310
311 if (decryptor_ && !DecryptVideoFrame(&encoded_frame)) {
312 // Logging already done.
313 return;
314 }
315
269 base::TimeTicks render_time; 316 base::TimeTicks render_time;
270 if (PullEncodedVideoFrame(rtp_timestamp, next_frame, &encoded_frame, 317 if (PullEncodedVideoFrame(rtp_timestamp, next_frame, &encoded_frame,
271 &render_time)) { 318 &render_time)) {
272 if (!queued_encoded_callbacks_.empty()) { 319 if (!queued_encoded_callbacks_.empty()) {
273 VideoFrameEncodedCallback callback = queued_encoded_callbacks_.front(); 320 VideoFrameEncodedCallback callback = queued_encoded_callbacks_.front();
274 queued_encoded_callbacks_.pop_front(); 321 queued_encoded_callbacks_.pop_front();
275 cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE, 322 cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE,
276 base::Bind(callback, base::Passed(&encoded_frame), render_time)); 323 base::Bind(callback, base::Passed(&encoded_frame), render_time));
277 } 324 }
278 } else { 325 } else {
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 } 449 }
403 450
404 void VideoReceiver::SendNextRtcpReport() { 451 void VideoReceiver::SendNextRtcpReport() {
405 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 452 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
406 rtcp_->SendRtcpFromRtpReceiver(NULL, NULL); 453 rtcp_->SendRtcpFromRtpReceiver(NULL, NULL);
407 ScheduleNextRtcpReport(); 454 ScheduleNextRtcpReport();
408 } 455 }
409 456
410 } // namespace cast 457 } // namespace cast
411 } // namespace media 458 } // namespace media
OLDNEW
« no previous file with comments | « media/cast/video_receiver/video_receiver.h ('k') | media/cast/video_receiver/video_receiver.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698