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_sender/video_sender.h" | 5 #include "media/cast/video_sender/video_sender.h" |
6 | 6 |
7 #include <list> | 7 #include <list> |
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" |
12 #include "media/cast/cast_defines.h" | 14 #include "media/cast/cast_defines.h" |
13 #include "media/cast/pacing/paced_sender.h" | 15 #include "media/cast/pacing/paced_sender.h" |
14 #include "media/cast/video_sender/video_encoder.h" | 16 #include "media/cast/video_sender/video_encoder.h" |
15 | 17 |
16 namespace media { | 18 namespace media { |
17 namespace cast { | 19 namespace cast { |
18 | 20 |
19 const int64 kMinSchedulingDelayMs = 1; | 21 const int64 kMinSchedulingDelayMs = 1; |
20 | 22 |
21 class LocalRtcpVideoSenderFeedback : public RtcpSenderFeedback { | 23 class LocalRtcpVideoSenderFeedback : public RtcpSenderFeedback { |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
80 new LocalRtpVideoSenderStatistics(rtp_sender_.get())); | 82 new LocalRtpVideoSenderStatistics(rtp_sender_.get())); |
81 | 83 |
82 if (video_config.use_external_encoder) { | 84 if (video_config.use_external_encoder) { |
83 DCHECK(video_encoder_controller) << "Invalid argument"; | 85 DCHECK(video_encoder_controller) << "Invalid argument"; |
84 video_encoder_controller_ = video_encoder_controller; | 86 video_encoder_controller_ = video_encoder_controller; |
85 } else { | 87 } else { |
86 video_encoder_ = new VideoEncoder(cast_environment, video_config, | 88 video_encoder_ = new VideoEncoder(cast_environment, video_config, |
87 max_unacked_frames_); | 89 max_unacked_frames_); |
88 video_encoder_controller_ = video_encoder_.get(); | 90 video_encoder_controller_ = video_encoder_.get(); |
89 } | 91 } |
| 92 |
| 93 if (video_config.aes_iv_mask.size() == kAesKeySize && |
| 94 video_config.aes_key.size() == kAesKeySize) { |
| 95 iv_mask_ = video_config.aes_iv_mask; |
| 96 crypto::SymmetricKey* key = crypto::SymmetricKey::Import( |
| 97 crypto::SymmetricKey::AES, video_config.aes_key); |
| 98 encryptor_.reset(new crypto::Encryptor()); |
| 99 encryptor_->Init(key, crypto::Encryptor::CTR, std::string()); |
| 100 } else if (video_config.aes_iv_mask.size() != 0 || |
| 101 video_config.aes_key.size() != 0) { |
| 102 DCHECK(false) << "Invalid crypto configuration"; |
| 103 } |
| 104 |
90 rtcp_.reset(new Rtcp( | 105 rtcp_.reset(new Rtcp( |
91 cast_environment_->Clock(), | 106 cast_environment_->Clock(), |
92 rtcp_feedback_.get(), | 107 rtcp_feedback_.get(), |
93 paced_packet_sender, | 108 paced_packet_sender, |
94 rtp_video_sender_statistics_.get(), | 109 rtp_video_sender_statistics_.get(), |
95 NULL, | 110 NULL, |
96 video_config.rtcp_mode, | 111 video_config.rtcp_mode, |
97 base::TimeDelta::FromMilliseconds(video_config.rtcp_interval), | 112 base::TimeDelta::FromMilliseconds(video_config.rtcp_interval), |
98 video_config.sender_ssrc, | 113 video_config.sender_ssrc, |
99 video_config.incoming_feedback_ssrc, | 114 video_config.incoming_feedback_ssrc, |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
136 SendEncodedVideoFrame(encoded_frame, capture_time); | 151 SendEncodedVideoFrame(encoded_frame, capture_time); |
137 cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE, callback); | 152 cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE, callback); |
138 } | 153 } |
139 | 154 |
140 void VideoSender::SendEncodedVideoFrameMainThread( | 155 void VideoSender::SendEncodedVideoFrameMainThread( |
141 scoped_ptr<EncodedVideoFrame> video_frame, | 156 scoped_ptr<EncodedVideoFrame> video_frame, |
142 const base::TimeTicks& capture_time) { | 157 const base::TimeTicks& capture_time) { |
143 SendEncodedVideoFrame(video_frame.get(), capture_time); | 158 SendEncodedVideoFrame(video_frame.get(), capture_time); |
144 } | 159 } |
145 | 160 |
| 161 bool VideoSender::EncryptVideoFrame(const EncodedVideoFrame& video_frame, |
| 162 EncodedVideoFrame* encrypted_frame) { |
| 163 DCHECK(encryptor_) << "Invalid state"; |
| 164 |
| 165 if (!encryptor_->SetCounter(GetAesNonce(video_frame.frame_id, iv_mask_))) { |
| 166 NOTREACHED() << "Failed to set counter"; |
| 167 return false; |
| 168 } |
| 169 |
| 170 if (!encryptor_->Encrypt(video_frame.data, &encrypted_frame->data)) { |
| 171 NOTREACHED() << "Encrypt error"; |
| 172 return false; |
| 173 } |
| 174 encrypted_frame->codec = video_frame.codec; |
| 175 encrypted_frame->key_frame = video_frame.key_frame; |
| 176 encrypted_frame->frame_id = video_frame.frame_id; |
| 177 encrypted_frame->last_referenced_frame_id = |
| 178 video_frame.last_referenced_frame_id; |
| 179 return true; |
| 180 } |
| 181 |
146 void VideoSender::SendEncodedVideoFrame(const EncodedVideoFrame* encoded_frame, | 182 void VideoSender::SendEncodedVideoFrame(const EncodedVideoFrame* encoded_frame, |
147 const base::TimeTicks& capture_time) { | 183 const base::TimeTicks& capture_time) { |
148 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 184 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
149 last_send_time_ = cast_environment_->Clock()->NowTicks(); | 185 last_send_time_ = cast_environment_->Clock()->NowTicks(); |
150 rtp_sender_->IncomingEncodedVideoFrame(encoded_frame, capture_time); | 186 |
| 187 if (encryptor_) { |
| 188 EncodedVideoFrame encrypted_video_frame; |
| 189 |
| 190 if (!EncryptVideoFrame(*encoded_frame, &encrypted_video_frame)) { |
| 191 // Logging already done. |
| 192 return; |
| 193 } |
| 194 rtp_sender_->IncomingEncodedVideoFrame(&encrypted_video_frame, |
| 195 capture_time); |
| 196 } else { |
| 197 rtp_sender_->IncomingEncodedVideoFrame(encoded_frame, capture_time); |
| 198 } |
151 if (encoded_frame->key_frame) { | 199 if (encoded_frame->key_frame) { |
152 VLOG(1) << "Send encoded key frame; frame_id:" | 200 VLOG(1) << "Send encoded key frame; frame_id:" |
153 << static_cast<int>(encoded_frame->frame_id); | 201 << static_cast<int>(encoded_frame->frame_id); |
154 } | 202 } |
155 last_sent_frame_id_ = static_cast<int>(encoded_frame->frame_id); | 203 last_sent_frame_id_ = static_cast<int>(encoded_frame->frame_id); |
156 UpdateFramesInFlight(); | 204 UpdateFramesInFlight(); |
157 InitializeTimers(); | 205 InitializeTimers(); |
158 } | 206 } |
159 | 207 |
160 void VideoSender::IncomingRtcpPacket(const uint8* packet, size_t length, | 208 void VideoSender::IncomingRtcpPacket(const uint8* packet, size_t length, |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
346 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 394 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
347 MissingFramesAndPacketsMap missing_frames_and_packets; | 395 MissingFramesAndPacketsMap missing_frames_and_packets; |
348 PacketIdSet missing; | 396 PacketIdSet missing; |
349 missing_frames_and_packets.insert(std::make_pair(resend_frame_id, missing)); | 397 missing_frames_and_packets.insert(std::make_pair(resend_frame_id, missing)); |
350 rtp_sender_->ResendPackets(missing_frames_and_packets); | 398 rtp_sender_->ResendPackets(missing_frames_and_packets); |
351 last_send_time_ = cast_environment_->Clock()->NowTicks(); | 399 last_send_time_ = cast_environment_->Clock()->NowTicks(); |
352 } | 400 } |
353 | 401 |
354 } // namespace cast | 402 } // namespace cast |
355 } // namespace media | 403 } // namespace media |
OLD | NEW |