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 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #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" | |
14 #include "media/cast/cast_defines.h" | 12 #include "media/cast/cast_defines.h" |
15 #include "media/cast/framer/framer.h" | 13 #include "media/cast/framer/framer.h" |
16 #include "media/cast/rtcp/rtcp_sender.h" | 14 #include "media/cast/rtcp/rtcp_sender.h" |
17 #include "media/cast/video_receiver/video_decoder.h" | 15 #include "media/cast/video_receiver/video_decoder.h" |
18 | 16 |
19 namespace media { | 17 namespace media { |
20 namespace cast { | 18 namespace cast { |
21 | 19 |
22 const int64 kMinSchedulingDelayMs = 1; | 20 const int64 kMinSchedulingDelayMs = 1; |
23 | 21 |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
93 target_delay_delta_( | 91 target_delay_delta_( |
94 base::TimeDelta::FromMilliseconds(video_config.rtp_max_delay_ms)), | 92 base::TimeDelta::FromMilliseconds(video_config.rtp_max_delay_ms)), |
95 frame_delay_(base::TimeDelta::FromMilliseconds( | 93 frame_delay_(base::TimeDelta::FromMilliseconds( |
96 1000 / video_config.max_frame_rate)), | 94 1000 / video_config.max_frame_rate)), |
97 incoming_payload_callback_(new LocalRtpVideoData(this)), | 95 incoming_payload_callback_(new LocalRtpVideoData(this)), |
98 incoming_payload_feedback_(new LocalRtpVideoFeedback(this)), | 96 incoming_payload_feedback_(new LocalRtpVideoFeedback(this)), |
99 rtp_receiver_(cast_environment_->Clock(), NULL, &video_config, | 97 rtp_receiver_(cast_environment_->Clock(), NULL, &video_config, |
100 incoming_payload_callback_.get()), | 98 incoming_payload_callback_.get()), |
101 rtp_video_receiver_statistics_( | 99 rtp_video_receiver_statistics_( |
102 new LocalRtpReceiverStatistics(&rtp_receiver_)), | 100 new LocalRtpReceiverStatistics(&rtp_receiver_)), |
| 101 decryptor_(), |
103 time_incoming_packet_updated_(false), | 102 time_incoming_packet_updated_(false), |
104 incoming_rtp_timestamp_(0), | 103 incoming_rtp_timestamp_(0), |
105 weak_factory_(this) { | 104 weak_factory_(this) { |
106 int max_unacked_frames = video_config.rtp_max_delay_ms * | 105 int max_unacked_frames = video_config.rtp_max_delay_ms * |
107 video_config.max_frame_rate / 1000; | 106 video_config.max_frame_rate / 1000; |
108 DCHECK(max_unacked_frames) << "Invalid argument"; | 107 DCHECK(max_unacked_frames) << "Invalid argument"; |
109 | 108 |
110 if (video_config.aes_iv_mask.size() == kAesKeySize && | 109 decryptor_.Initialize(video_config.aes_key, video_config.aes_iv_mask); |
111 video_config.aes_key.size() == kAesKeySize) { | |
112 iv_mask_ = video_config.aes_iv_mask; | |
113 decryption_key_.reset(crypto::SymmetricKey::Import( | |
114 crypto::SymmetricKey::AES, video_config.aes_key)); | |
115 decryptor_.reset(new crypto::Encryptor()); | |
116 decryptor_->Init(decryption_key_.get(), | |
117 crypto::Encryptor::CTR, | |
118 std::string()); | |
119 } else if (video_config.aes_iv_mask.size() != 0 || | |
120 video_config.aes_key.size() != 0) { | |
121 DCHECK(false) << "Invalid crypto configuration"; | |
122 } | |
123 | |
124 framer_.reset(new Framer(cast_environment->Clock(), | 110 framer_.reset(new Framer(cast_environment->Clock(), |
125 incoming_payload_feedback_.get(), | 111 incoming_payload_feedback_.get(), |
126 video_config.incoming_ssrc, | 112 video_config.incoming_ssrc, |
127 video_config.decoder_faster_than_max_frame_rate, | 113 video_config.decoder_faster_than_max_frame_rate, |
128 max_unacked_frames)); | 114 max_unacked_frames)); |
129 if (!video_config.use_external_decoder) { | 115 if (!video_config.use_external_decoder) { |
130 video_decoder_.reset(new VideoDecoder(video_config, cast_environment)); | 116 video_decoder_.reset(new VideoDecoder(video_config, cast_environment)); |
131 } | 117 } |
132 | 118 |
133 rtcp_.reset(new Rtcp( | 119 rtcp_.reset(new Rtcp( |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
184 // This will happen if we decide to decode but not show a frame. | 170 // This will happen if we decide to decode but not show a frame. |
185 cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE, | 171 cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE, |
186 base::Bind(&VideoReceiver::GetRawVideoFrame, base::Unretained(this), | 172 base::Bind(&VideoReceiver::GetRawVideoFrame, base::Unretained(this), |
187 frame_decoded_callback)); | 173 frame_decoded_callback)); |
188 } | 174 } |
189 } | 175 } |
190 | 176 |
191 bool VideoReceiver::DecryptVideoFrame( | 177 bool VideoReceiver::DecryptVideoFrame( |
192 scoped_ptr<transport::EncodedVideoFrame>* video_frame) { | 178 scoped_ptr<transport::EncodedVideoFrame>* video_frame) { |
193 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 179 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
194 DCHECK(decryptor_) << "Invalid state"; | |
195 | 180 |
196 if (!decryptor_->SetCounter(GetAesNonce((*video_frame)->frame_id, | 181 if (decryptor_.initialized()) { |
197 iv_mask_))) { | 182 std::string decrypted_video_data; |
198 NOTREACHED() << "Failed to set counter"; | 183 if (!decryptor_.Decrypt((*video_frame)->frame_id, |
199 return false; | 184 (*video_frame)->data, |
| 185 &decrypted_video_data)) { |
| 186 // Give up on this frame, release it from jitter buffer. |
| 187 framer_->ReleaseFrame((*video_frame)->frame_id); |
| 188 return false; |
| 189 } |
| 190 (*video_frame)->data.swap(decrypted_video_data); |
| 191 return true; |
200 } | 192 } |
201 std::string decrypted_video_data; | |
202 if (!decryptor_->Decrypt((*video_frame)->data, &decrypted_video_data)) { | |
203 VLOG(1) << "Decryption error"; | |
204 // Give up on this frame, release it from jitter buffer. | |
205 framer_->ReleaseFrame((*video_frame)->frame_id); | |
206 return false; | |
207 } | |
208 (*video_frame)->data.swap(decrypted_video_data); | |
209 return true; | |
210 } | 193 } |
211 | 194 |
212 // Called from the main cast thread. | 195 // Called from the main cast thread. |
213 void VideoReceiver::GetEncodedVideoFrame( | 196 void VideoReceiver::GetEncodedVideoFrame( |
214 const VideoFrameEncodedCallback& callback) { | 197 const VideoFrameEncodedCallback& callback) { |
215 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 198 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
216 scoped_ptr<transport::EncodedVideoFrame> encoded_frame( | 199 scoped_ptr<transport::EncodedVideoFrame> encoded_frame( |
217 new transport::EncodedVideoFrame()); | 200 new transport::EncodedVideoFrame()); |
218 uint32 rtp_timestamp = 0; | 201 uint32 rtp_timestamp = 0; |
219 bool next_frame = false; | 202 bool next_frame = false; |
220 | 203 |
221 if (!framer_->GetEncodedVideoFrame(encoded_frame.get(), &rtp_timestamp, | 204 if (!framer_->GetEncodedVideoFrame(encoded_frame.get(), &rtp_timestamp, |
222 &next_frame)) { | 205 &next_frame)) { |
223 // We have no video frames. Wait for new packet(s). | 206 // We have no video frames. Wait for new packet(s). |
224 queued_encoded_callbacks_.push_back(callback); | 207 queued_encoded_callbacks_.push_back(callback); |
225 return; | 208 return; |
226 } | 209 } |
227 | 210 |
228 if (decryptor_ && !DecryptVideoFrame(&encoded_frame)) { | 211 if (decryptor_.initialized() && !DecryptVideoFrame(&encoded_frame)) { |
229 // Logging already done. | 212 // Logging already done. |
230 queued_encoded_callbacks_.push_back(callback); | 213 queued_encoded_callbacks_.push_back(callback); |
231 return; | 214 return; |
232 } | 215 } |
233 | 216 |
234 base::TimeTicks render_time; | 217 base::TimeTicks render_time; |
235 if (PullEncodedVideoFrame(rtp_timestamp, next_frame, &encoded_frame, | 218 if (PullEncodedVideoFrame(rtp_timestamp, next_frame, &encoded_frame, |
236 &render_time)) { | 219 &render_time)) { |
237 cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE, | 220 cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE, |
238 base::Bind(callback, base::Passed(&encoded_frame), render_time)); | 221 base::Bind(callback, base::Passed(&encoded_frame), render_time)); |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
313 // We have no video frames. Wait for new packet(s). | 296 // We have no video frames. Wait for new packet(s). |
314 // Since the application can post multiple VideoFrameEncodedCallback and | 297 // Since the application can post multiple VideoFrameEncodedCallback and |
315 // we only check the next frame to play out we might have multiple timeout | 298 // we only check the next frame to play out we might have multiple timeout |
316 // events firing after each other; however this should be a rare event. | 299 // events firing after each other; however this should be a rare event. |
317 VLOG(1) << "Failed to retrieved a complete frame at this point in time"; | 300 VLOG(1) << "Failed to retrieved a complete frame at this point in time"; |
318 return; | 301 return; |
319 } | 302 } |
320 VLOG(1) << "PlayoutTimeout retrieved frame " | 303 VLOG(1) << "PlayoutTimeout retrieved frame " |
321 << static_cast<int>(encoded_frame->frame_id); | 304 << static_cast<int>(encoded_frame->frame_id); |
322 | 305 |
323 if (decryptor_ && !DecryptVideoFrame(&encoded_frame)) { | 306 if (decryptor_.initialized() && !DecryptVideoFrame(&encoded_frame)) { |
324 // Logging already done. | 307 // Logging already done. |
325 return; | 308 return; |
326 } | 309 } |
327 | 310 |
328 base::TimeTicks render_time; | 311 base::TimeTicks render_time; |
329 if (PullEncodedVideoFrame(rtp_timestamp, next_frame, &encoded_frame, | 312 if (PullEncodedVideoFrame(rtp_timestamp, next_frame, &encoded_frame, |
330 &render_time)) { | 313 &render_time)) { |
331 if (!queued_encoded_callbacks_.empty()) { | 314 if (!queued_encoded_callbacks_.empty()) { |
332 VideoFrameEncodedCallback callback = queued_encoded_callbacks_.front(); | 315 VideoFrameEncodedCallback callback = queued_encoded_callbacks_.front(); |
333 queued_encoded_callbacks_.pop_front(); | 316 queued_encoded_callbacks_.pop_front(); |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
509 } | 492 } |
510 | 493 |
511 void VideoReceiver::SendNextRtcpReport() { | 494 void VideoReceiver::SendNextRtcpReport() { |
512 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 495 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
513 rtcp_->SendRtcpFromRtpReceiver(NULL, NULL); | 496 rtcp_->SendRtcpFromRtpReceiver(NULL, NULL); |
514 ScheduleNextRtcpReport(); | 497 ScheduleNextRtcpReport(); |
515 } | 498 } |
516 | 499 |
517 } // namespace cast | 500 } // namespace cast |
518 } // namespace media | 501 } // namespace media |
OLD | NEW |