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/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 Loading... |
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 Loading... |
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 decryptor_->SetCounter(GetAesNonce((*video_frame)->frame_id, iv_mask_)); |
| 225 |
| 226 if (!decryptor_->Decrypt((*video_frame)->data, |
| 227 &decrypted_video_frame->data)) { |
| 228 return false; |
| 229 } |
| 230 decrypted_video_frame->codec = (*video_frame)->codec; |
| 231 decrypted_video_frame->key_frame = (*video_frame)->key_frame; |
| 232 decrypted_video_frame->frame_id = (*video_frame)->frame_id; |
| 233 decrypted_video_frame->last_referenced_frame_id = |
| 234 (*video_frame)->last_referenced_frame_id; |
| 235 |
| 236 video_frame->swap(decrypted_video_frame); |
| 237 return true; |
| 238 } |
| 239 |
203 // Called from the main cast thread. | 240 // Called from the main cast thread. |
204 void VideoReceiver::GetEncodedVideoFrame( | 241 void VideoReceiver::GetEncodedVideoFrame( |
205 const VideoFrameEncodedCallback& callback) { | 242 const VideoFrameEncodedCallback& callback) { |
206 scoped_ptr<EncodedVideoFrame> encoded_frame(new EncodedVideoFrame()); | 243 scoped_ptr<EncodedVideoFrame> encoded_frame(new EncodedVideoFrame()); |
207 uint32 rtp_timestamp = 0; | 244 uint32 rtp_timestamp = 0; |
208 bool next_frame = false; | 245 bool next_frame = false; |
209 | 246 |
210 if (!framer_->GetEncodedVideoFrame(encoded_frame.get(), &rtp_timestamp, | 247 if (!framer_->GetEncodedVideoFrame(encoded_frame.get(), &rtp_timestamp, |
211 &next_frame)) { | 248 &next_frame)) { |
212 // We have no video frames. Wait for new packet(s). | 249 // We have no video frames. Wait for new packet(s). |
213 queued_encoded_callbacks_.push_back(callback); | 250 queued_encoded_callbacks_.push_back(callback); |
214 return; | 251 return; |
215 } | 252 } |
| 253 |
| 254 if (decryptor_) { |
| 255 if (!DecryptVideoFrame(&encoded_frame)) { |
| 256 DCHECK(false) << "Decryption error"; |
| 257 return; |
| 258 } |
| 259 } |
| 260 |
216 base::TimeTicks render_time; | 261 base::TimeTicks render_time; |
217 if (PullEncodedVideoFrame(rtp_timestamp, next_frame, &encoded_frame, | 262 if (PullEncodedVideoFrame(rtp_timestamp, next_frame, &encoded_frame, |
218 &render_time)) { | 263 &render_time)) { |
219 cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE, | 264 cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE, |
220 base::Bind(callback, base::Passed(&encoded_frame), render_time)); | 265 base::Bind(callback, base::Passed(&encoded_frame), render_time)); |
221 } else { | 266 } else { |
222 // We have a video frame; however we are missing packets and we have time | 267 // We have a video frame; however we are missing packets and we have time |
223 // to wait for new packet(s). | 268 // to wait for new packet(s). |
224 queued_encoded_callbacks_.push_back(callback); | 269 queued_encoded_callbacks_.push_back(callback); |
225 } | 270 } |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
286 // We have no video frames. Wait for new packet(s). | 331 // We have no video frames. Wait for new packet(s). |
287 // Since the application can post multiple VideoFrameEncodedCallback and | 332 // Since the application can post multiple VideoFrameEncodedCallback and |
288 // we only check the next frame to play out we might have multiple timeout | 333 // 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. | 334 // 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"; | 335 VLOG(1) << "Failed to retrieved a complete frame at this point in time"; |
291 return; | 336 return; |
292 } | 337 } |
293 VLOG(1) << "PlayoutTimeout retrieved frame " | 338 VLOG(1) << "PlayoutTimeout retrieved frame " |
294 << static_cast<int>(encoded_frame->frame_id); | 339 << static_cast<int>(encoded_frame->frame_id); |
295 | 340 |
| 341 if (decryptor_) { |
| 342 if (!DecryptVideoFrame(&encoded_frame)) { |
| 343 DCHECK(false) << "Decryption error"; |
| 344 return; |
| 345 } |
| 346 } |
| 347 |
296 base::TimeTicks render_time; | 348 base::TimeTicks render_time; |
297 if (PullEncodedVideoFrame(rtp_timestamp, next_frame, &encoded_frame, | 349 if (PullEncodedVideoFrame(rtp_timestamp, next_frame, &encoded_frame, |
298 &render_time)) { | 350 &render_time)) { |
299 if (!queued_encoded_callbacks_.empty()) { | 351 if (!queued_encoded_callbacks_.empty()) { |
300 VideoFrameEncodedCallback callback = queued_encoded_callbacks_.front(); | 352 VideoFrameEncodedCallback callback = queued_encoded_callbacks_.front(); |
301 queued_encoded_callbacks_.pop_front(); | 353 queued_encoded_callbacks_.pop_front(); |
302 cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE, | 354 cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE, |
303 base::Bind(callback, base::Passed(&encoded_frame), render_time)); | 355 base::Bind(callback, base::Passed(&encoded_frame), render_time)); |
304 } | 356 } |
305 } else { | 357 } else { |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
419 weak_factory_.GetWeakPtr()), time_to_next); | 471 weak_factory_.GetWeakPtr()), time_to_next); |
420 } | 472 } |
421 | 473 |
422 void VideoReceiver::SendNextRtcpReport() { | 474 void VideoReceiver::SendNextRtcpReport() { |
423 rtcp_->SendRtcpReport(incoming_ssrc_); | 475 rtcp_->SendRtcpReport(incoming_ssrc_); |
424 ScheduleNextRtcpReport(); | 476 ScheduleNextRtcpReport(); |
425 } | 477 } |
426 | 478 |
427 } // namespace cast | 479 } // namespace cast |
428 } // namespace media | 480 } // namespace media |
OLD | NEW |