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 3 // found in the LICENSE file. 4 5 #include "media/cast/video_receiver/video_receiver.h" 6 7 #include <algorithm> 8 9 #include "base/bind.h" 10 #include "base/logging.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" 15 #include "media/cast/framer/framer.h" 16 #include "media/cast/video_receiver/video_decoder.h" 17 18 namespace media { 19 namespace cast { 20 21 const int64 kMinSchedulingDelayMs = 1; 22 23 static const int64 kMinTimeBetweenOffsetUpdatesMs = 2000; 24 static const int kTimeOffsetFilter = 8; 25 static const int64_t kMinProcessIntervalMs = 5; 26 27 // Local implementation of RtpData (defined in rtp_rtcp_defines.h). 28 // Used to pass payload data into the video receiver. 29 class LocalRtpVideoData : public RtpData { 30 public: 31 explicit LocalRtpVideoData(VideoReceiver* video_receiver) 32 : video_receiver_(video_receiver) {} 33 34 virtual ~LocalRtpVideoData() {} 35 36 virtual void OnReceivedPayloadData(const uint8* payload_data, 37 size_t payload_size, 38 const RtpCastHeader* rtp_header) OVERRIDE { 39 video_receiver_->IncomingParsedRtpPacket(payload_data, payload_size, 40 *rtp_header); 41 } 42 43 private: 44 VideoReceiver* video_receiver_; 45 }; 46 47 // Local implementation of RtpPayloadFeedback (defined in rtp_defines.h) 48 // Used to convey cast-specific feedback from receiver to sender. 49 // Callback triggered by the Framer (cast message builder). 50 class LocalRtpVideoFeedback : public RtpPayloadFeedback { 51 public: 52 explicit LocalRtpVideoFeedback(VideoReceiver* video_receiver) 53 : video_receiver_(video_receiver) { 54 } 55 56 virtual void CastFeedback(const RtcpCastMessage& cast_message) OVERRIDE { 57 video_receiver_->CastFeedback(cast_message); 58 } 59 60 private: 61 VideoReceiver* video_receiver_; 62 }; 63 64 // Local implementation of RtpReceiverStatistics (defined by rtcp.h). 65 // Used to pass statistics data from the RTP module to the RTCP module. 66 class LocalRtpReceiverStatistics : public RtpReceiverStatistics { 67 public: 68 explicit LocalRtpReceiverStatistics(RtpReceiver* rtp_receiver) 69 : rtp_receiver_(rtp_receiver) { 70 } 71 72 virtual void GetStatistics(uint8* fraction_lost, 73 uint32* cumulative_lost, // 24 bits valid. 74 uint32* extended_high_sequence_number, 75 uint32* jitter) OVERRIDE { 76 rtp_receiver_->GetStatistics(fraction_lost, 77 cumulative_lost, 78 extended_high_sequence_number, 79 jitter); 80 } 81 82 private: 83 RtpReceiver* rtp_receiver_; 84 }; 85 86 VideoReceiver::VideoReceiver(scoped_refptr<CastEnvironment> cast_environment, 87 const VideoReceiverConfig& video_config, 88 PacedPacketSender* const packet_sender) 89 : cast_environment_(cast_environment), 90 codec_(video_config.codec), 91 target_delay_delta_( 92 base::TimeDelta::FromMilliseconds(video_config.rtp_max_delay_ms)), 93 frame_delay_(base::TimeDelta::FromMilliseconds( 94 1000 / video_config.max_frame_rate)), 95 incoming_payload_callback_(new LocalRtpVideoData(this)), 96 incoming_payload_feedback_(new LocalRtpVideoFeedback(this)), 97 rtp_receiver_(cast_environment_->Clock(), NULL, &video_config, 98 incoming_payload_callback_.get()), 99 rtp_video_receiver_statistics_( 100 new LocalRtpReceiverStatistics(&rtp_receiver_)), 101 time_incoming_packet_updated_(false), 102 incoming_rtp_timestamp_(0), 103 weak_factory_(this) { 104 int max_unacked_frames = video_config.rtp_max_delay_ms * 105 video_config.max_frame_rate / 1000; 106 DCHECK(max_unacked_frames) << "Invalid argument"; 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 120 framer_.reset(new Framer(cast_environment->Clock(), 121 incoming_payload_feedback_.get(), 122 video_config.incoming_ssrc, 123 video_config.decoder_faster_than_max_frame_rate, 124 max_unacked_frames)); 125 if (!video_config.use_external_decoder) { 126 video_decoder_.reset(new VideoDecoder(video_config, cast_environment)); 127 } 128 129 rtcp_.reset( 130 new Rtcp(cast_environment_, 131 NULL, 132 packet_sender, 133 NULL, 134 rtp_video_receiver_statistics_.get(), 135 video_config.rtcp_mode, 136 base::TimeDelta::FromMilliseconds(video_config.rtcp_interval), 137 video_config.feedback_ssrc, 138 video_config.incoming_ssrc, 139 video_config.rtcp_c_name)); 140 } 141 142 VideoReceiver::~VideoReceiver() {} 143 144 void VideoReceiver::InitializeTimers() { 145 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 146 ScheduleNextRtcpReport(); 147 ScheduleNextCastMessage(); 148 } 149 150 void VideoReceiver::GetRawVideoFrame( 151 const VideoFrameDecodedCallback& callback) { 152 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 153 GetEncodedVideoFrame(base::Bind(&VideoReceiver::DecodeVideoFrame, 154 base::Unretained(this), callback)); 155 } 156 157 // Called when we have a frame to decode. 158 void VideoReceiver::DecodeVideoFrame( 159 const VideoFrameDecodedCallback& callback, 160 scoped_ptr<EncodedVideoFrame> encoded_frame, 161 const base::TimeTicks& render_time) { 162 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 163 // Hand the ownership of the encoded frame to the decode thread. 164 cast_environment_->PostTask(CastEnvironment::VIDEO_DECODER, FROM_HERE, 165 base::Bind(&VideoReceiver::DecodeVideoFrameThread, base::Unretained(this), 166 base::Passed(&encoded_frame), render_time, callback)); 167 } 168 169 // Utility function to run the decoder on a designated decoding thread. 170 void VideoReceiver::DecodeVideoFrameThread( 171 scoped_ptr<EncodedVideoFrame> encoded_frame, 172 const base::TimeTicks render_time, 173 const VideoFrameDecodedCallback& frame_decoded_callback) { 174 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::VIDEO_DECODER)); 175 DCHECK(video_decoder_); 176 177 if (!(video_decoder_->DecodeVideoFrame(encoded_frame.get(), render_time, 178 frame_decoded_callback))) { 179 // This will happen if we decide to decode but not show a frame. 180 cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE, 181 base::Bind(&VideoReceiver::GetRawVideoFrame, base::Unretained(this), 182 frame_decoded_callback)); 183 } 184 } 185 186 bool VideoReceiver::DecryptVideoFrame( 187 scoped_ptr<EncodedVideoFrame>* video_frame) { 188 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 189 DCHECK(decryptor_) << "Invalid state"; 190 191 if (!decryptor_->SetCounter(GetAesNonce((*video_frame)->frame_id, 192 iv_mask_))) { 193 NOTREACHED() << "Failed to set counter"; 194 return false; 195 } 196 std::string decrypted_video_data; 197 if (!decryptor_->Decrypt((*video_frame)->data, &decrypted_video_data)) { 198 VLOG(1) << "Decryption error"; 199 // Give up on this frame, release it from jitter buffer. 200 framer_->ReleaseFrame((*video_frame)->frame_id); 201 return false; 202 } 203 (*video_frame)->data.swap(decrypted_video_data); 204 return true; 205 } 206 207 // Called from the main cast thread. 208 void VideoReceiver::GetEncodedVideoFrame( 209 const VideoFrameEncodedCallback& callback) { 210 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 211 scoped_ptr<EncodedVideoFrame> encoded_frame(new EncodedVideoFrame()); 212 uint32 rtp_timestamp = 0; 213 bool next_frame = false; 214 215 if (!framer_->GetEncodedVideoFrame(encoded_frame.get(), &rtp_timestamp, 216 &next_frame)) { 217 // We have no video frames. Wait for new packet(s). 218 queued_encoded_callbacks_.push_back(callback); 219 return; 220 } 221 222 if (decryptor_ && !DecryptVideoFrame(&encoded_frame)) { 223 // Logging already done. 224 queued_encoded_callbacks_.push_back(callback); 225 return; 226 } 227 228 base::TimeTicks render_time; 229 if (PullEncodedVideoFrame(rtp_timestamp, next_frame, &encoded_frame, 230 &render_time)) { 231 cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE, 232 base::Bind(callback, base::Passed(&encoded_frame), render_time)); 233 } else { 234 // We have a video frame; however we are missing packets and we have time 235 // to wait for new packet(s). 236 queued_encoded_callbacks_.push_back(callback); 237 } 238 } 239 240 // Should we pull the encoded video frame from the framer? decided by if this is 241 // the next frame or we are running out of time and have to pull the following 242 // frame. 243 // If the frame is too old to be rendered we set the don't show flag in the 244 // video bitstream where possible. 245 bool VideoReceiver::PullEncodedVideoFrame(uint32 rtp_timestamp, 246 bool next_frame, scoped_ptr<EncodedVideoFrame>* encoded_frame, 247 base::TimeTicks* render_time) { 248 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 249 base::TimeTicks now = cast_environment_->Clock()->NowTicks(); 250 *render_time = GetRenderTime(now, rtp_timestamp); 251 252 // TODO(mikhal): Store actual render time and not diff. 253 cast_environment_->Logging()->InsertFrameEventWithDelay(kVideoRenderDelay, 254 rtp_timestamp, (*encoded_frame)->frame_id, now - *render_time); 255 256 // Minimum time before a frame is due to be rendered before we pull it for 257 // decode. 258 base::TimeDelta min_wait_delta = frame_delay_; 259 base::TimeDelta time_until_render = *render_time - now; 260 if (!next_frame && (time_until_render > min_wait_delta)) { 261 // Example: 262 // We have decoded frame 1 and we have received the complete frame 3, but 263 // not frame 2. If we still have time before frame 3 should be rendered we 264 // will wait for 2 to arrive, however if 2 never show up this timer will hit 265 // and we will pull out frame 3 for decoding and rendering. 266 base::TimeDelta time_until_release = time_until_render - min_wait_delta; 267 cast_environment_->PostDelayedTask(CastEnvironment::MAIN, FROM_HERE, 268 base::Bind(&VideoReceiver::PlayoutTimeout, weak_factory_.GetWeakPtr()), 269 time_until_release); 270 VLOG(1) << "Wait before releasing frame " 271 << static_cast<int>((*encoded_frame)->frame_id) 272 << " time " << time_until_release.InMilliseconds(); 273 return false; 274 } 275 276 base::TimeDelta dont_show_timeout_delta = 277 base::TimeDelta::FromMilliseconds(-kDontShowTimeoutMs); 278 if (codec_ == kVp8 && time_until_render < dont_show_timeout_delta) { 279 (*encoded_frame)->data[0] &= 0xef; 280 VLOG(1) << "Don't show frame " 281 << static_cast<int>((*encoded_frame)->frame_id) 282 << " time_until_render:" << time_until_render.InMilliseconds(); 283 } else { 284 VLOG(1) << "Show frame " 285 << static_cast<int>((*encoded_frame)->frame_id) 286 << " time_until_render:" << time_until_render.InMilliseconds(); 287 } 288 // We have a copy of the frame, release this one. 289 framer_->ReleaseFrame((*encoded_frame)->frame_id); 290 (*encoded_frame)->codec = codec_; 291 return true; 292 } 293 294 void VideoReceiver::PlayoutTimeout() { 295 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 296 if (queued_encoded_callbacks_.empty()) return; 297 298 uint32 rtp_timestamp = 0; 299 bool next_frame = false; 300 scoped_ptr<EncodedVideoFrame> encoded_frame(new EncodedVideoFrame()); 301 302 if (!framer_->GetEncodedVideoFrame(encoded_frame.get(), &rtp_timestamp, 303 &next_frame)) { 304 // We have no video frames. Wait for new packet(s). 305 // Since the application can post multiple VideoFrameEncodedCallback and 306 // we only check the next frame to play out we might have multiple timeout 307 // events firing after each other; however this should be a rare event. 308 VLOG(1) << "Failed to retrieved a complete frame at this point in time"; 309 return; 310 } 311 VLOG(1) << "PlayoutTimeout retrieved frame " 312 << static_cast<int>(encoded_frame->frame_id); 313 314 if (decryptor_ && !DecryptVideoFrame(&encoded_frame)) { 315 // Logging already done. 316 return; 317 } 318 319 base::TimeTicks render_time; 320 if (PullEncodedVideoFrame(rtp_timestamp, next_frame, &encoded_frame, 321 &render_time)) { 322 if (!queued_encoded_callbacks_.empty()) { 323 VideoFrameEncodedCallback callback = queued_encoded_callbacks_.front(); 324 queued_encoded_callbacks_.pop_front(); 325 cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE, 326 base::Bind(callback, base::Passed(&encoded_frame), render_time)); 327 } 328 } else { 329 // We have a video frame; however we are missing packets and we have time 330 // to wait for new packet(s). 331 } 332 } 333 334 base::TimeTicks VideoReceiver::GetRenderTime(base::TimeTicks now, 335 uint32 rtp_timestamp) { 336 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 337 // Senders time in ms when this frame was captured. 338 // Note: the senders clock and our local clock might not be synced. 339 base::TimeTicks rtp_timestamp_in_ticks; 340 341 if (time_offset_.InMilliseconds() == 0) { 342 if (!rtcp_->RtpTimestampInSenderTime(kVideoFrequency, 343 incoming_rtp_timestamp_, 344 &rtp_timestamp_in_ticks)) { 345 // We have not received any RTCP to sync the stream play it out as soon as 346 // possible. 347 return now; 348 } 349 time_offset_ = time_incoming_packet_ - rtp_timestamp_in_ticks; 350 } else if (time_incoming_packet_updated_) { 351 if (rtcp_->RtpTimestampInSenderTime(kVideoFrequency, 352 incoming_rtp_timestamp_, 353 &rtp_timestamp_in_ticks)) { 354 // Time to update the time_offset. 355 base::TimeDelta time_offset = 356 time_incoming_packet_ - rtp_timestamp_in_ticks; 357 time_offset_ = ((kTimeOffsetFilter - 1) * time_offset_ + time_offset) 358 / kTimeOffsetFilter; 359 } 360 } 361 // Reset |time_incoming_packet_updated_| to enable a future measurement. 362 time_incoming_packet_updated_ = false; 363 if (!rtcp_->RtpTimestampInSenderTime(kVideoFrequency, 364 rtp_timestamp, 365 &rtp_timestamp_in_ticks)) { 366 // This can fail if we have not received any RTCP packets in a long time. 367 return now; 368 } 369 return (rtp_timestamp_in_ticks + time_offset_ + target_delay_delta_); 370 } 371 372 void VideoReceiver::IncomingPacket(const uint8* packet, size_t length, 373 const base::Closure callback) { 374 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 375 if (Rtcp::IsRtcpPacket(packet, length)) { 376 rtcp_->IncomingRtcpPacket(packet, length); 377 } else { 378 rtp_receiver_.ReceivedPacket(packet, length); 379 } 380 cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE, callback); 381 } 382 383 void VideoReceiver::IncomingParsedRtpPacket(const uint8* payload_data, 384 size_t payload_size, 385 const RtpCastHeader& rtp_header) { 386 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 387 388 base::TimeTicks now = cast_environment_->Clock()->NowTicks(); 389 if (time_incoming_packet_.is_null() || now - time_incoming_packet_ > 390 base::TimeDelta::FromMilliseconds(kMinTimeBetweenOffsetUpdatesMs)) { 391 if (time_incoming_packet_.is_null()) InitializeTimers(); 392 incoming_rtp_timestamp_ = rtp_header.webrtc.header.timestamp; 393 time_incoming_packet_ = now; 394 time_incoming_packet_updated_ = true; 395 } 396 397 cast_environment_->Logging()->InsertPacketEvent(kPacketReceived, 398 rtp_header.webrtc.header.timestamp, rtp_header.frame_id, 399 rtp_header.packet_id, rtp_header.max_packet_id, payload_size); 400 401 bool complete = framer_->InsertPacket(payload_data, payload_size, rtp_header); 402 403 if (!complete) return; // Video frame not complete; wait for more packets. 404 if (queued_encoded_callbacks_.empty()) return; // No pending callback. 405 406 VideoFrameEncodedCallback callback = queued_encoded_callbacks_.front(); 407 queued_encoded_callbacks_.pop_front(); 408 cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE, 409 base::Bind(&VideoReceiver::GetEncodedVideoFrame, 410 weak_factory_.GetWeakPtr(), callback)); 411 } 412 413 // Send a cast feedback message. Actual message created in the framer (cast 414 // message builder). 415 void VideoReceiver::CastFeedback(const RtcpCastMessage& cast_message) { 416 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 417 // TODO(pwestin): wire up log messages. 418 rtcp_->SendRtcpFromRtpReceiver(&cast_message, NULL); 419 time_last_sent_cast_message_= cast_environment_->Clock()->NowTicks(); 420 } 421 422 // Cast messages should be sent within a maximum interval. Schedule a call 423 // if not triggered elsewhere, e.g. by the cast message_builder. 424 void VideoReceiver::ScheduleNextCastMessage() { 425 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 426 base::TimeTicks send_time; 427 framer_->TimeToSendNextCastMessage(&send_time); 428 429 base::TimeDelta time_to_send = send_time - 430 cast_environment_->Clock()->NowTicks(); 431 time_to_send = std::max(time_to_send, 432 base::TimeDelta::FromMilliseconds(kMinSchedulingDelayMs)); 433 cast_environment_->PostDelayedTask(CastEnvironment::MAIN, FROM_HERE, 434 base::Bind(&VideoReceiver::SendNextCastMessage, 435 weak_factory_.GetWeakPtr()), time_to_send); 436 } 437 438 void VideoReceiver::SendNextCastMessage() { 439 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 440 framer_->SendCastMessage(); // Will only send a message if it is time. 441 ScheduleNextCastMessage(); 442 } 443 444 // Schedule the next RTCP report to be sent back to the sender. 445 void VideoReceiver::ScheduleNextRtcpReport() { 446 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 447 base::TimeDelta time_to_next = rtcp_->TimeToSendNextRtcpReport() - 448 cast_environment_->Clock()->NowTicks(); 449 450 time_to_next = std::max(time_to_next, 451 base::TimeDelta::FromMilliseconds(kMinSchedulingDelayMs)); 452 453 cast_environment_->PostDelayedTask(CastEnvironment::MAIN, FROM_HERE, 454 base::Bind(&VideoReceiver::SendNextRtcpReport, 455 weak_factory_.GetWeakPtr()), time_to_next); 456 } 457 458 void VideoReceiver::SendNextRtcpReport() { 459 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 460 rtcp_->SendRtcpFromRtpReceiver(NULL, NULL); 461 ScheduleNextRtcpReport(); 462 } 463 464 } // namespace cast 465 } // namespace media 466