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

Side by Side Diff: media/cast/video_sender/video_sender.cc

Issue 116623002: Cast: Adding support for GPU accelerated encode (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed merge nits Created 6 years, 11 months 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
« no previous file with comments | « media/cast/video_sender/video_sender.h ('k') | media/cast/video_sender/video_sender.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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_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" 12 #include "crypto/encryptor.h"
13 #include "crypto/symmetric_key.h" 13 #include "crypto/symmetric_key.h"
14 #include "media/cast/cast_defines.h" 14 #include "media/cast/cast_defines.h"
15 #include "media/cast/transport/pacing/paced_sender.h" 15 #include "media/cast/transport/pacing/paced_sender.h"
16 #include "media/cast/video_sender/video_encoder.h" 16 #include "media/cast/video_sender/external_video_encoder.h"
17 #include "media/cast/video_sender/video_encoder_impl.h"
17 18
18 namespace media { 19 namespace media {
19 namespace cast { 20 namespace cast {
20 21
21 const int64 kMinSchedulingDelayMs = 1; 22 const int64 kMinSchedulingDelayMs = 1;
22 23
23 class LocalRtcpVideoSenderFeedback : public RtcpSenderFeedback { 24 class LocalRtcpVideoSenderFeedback : public RtcpSenderFeedback {
24 public: 25 public:
25 explicit LocalRtcpVideoSenderFeedback(VideoSender* video_sender) 26 explicit LocalRtcpVideoSenderFeedback(VideoSender* video_sender)
26 : video_sender_(video_sender) { 27 : video_sender_(video_sender) {
(...skipping 19 matching lines...) Expand all
46 rtp_sender_->RtpStatistics(now, sender_info); 47 rtp_sender_->RtpStatistics(now, sender_info);
47 } 48 }
48 49
49 private: 50 private:
50 transport::RtpSender* rtp_sender_; 51 transport::RtpSender* rtp_sender_;
51 }; 52 };
52 53
53 VideoSender::VideoSender( 54 VideoSender::VideoSender(
54 scoped_refptr<CastEnvironment> cast_environment, 55 scoped_refptr<CastEnvironment> cast_environment,
55 const VideoSenderConfig& video_config, 56 const VideoSenderConfig& video_config,
56 VideoEncoderController* const video_encoder_controller, 57 const scoped_refptr<GpuVideoAcceleratorFactories>& gpu_factories,
57 transport::PacedPacketSender* const paced_packet_sender) 58 transport::PacedPacketSender* const paced_packet_sender)
58 : rtp_max_delay_( 59 : rtp_max_delay_(
59 base::TimeDelta::FromMilliseconds(video_config.rtp_max_delay_ms)), 60 base::TimeDelta::FromMilliseconds(video_config.rtp_max_delay_ms)),
60 max_frame_rate_(video_config.max_frame_rate), 61 max_frame_rate_(video_config.max_frame_rate),
61 cast_environment_(cast_environment), 62 cast_environment_(cast_environment),
62 rtcp_feedback_(new LocalRtcpVideoSenderFeedback(this)), 63 rtcp_feedback_(new LocalRtcpVideoSenderFeedback(this)),
63 rtp_sender_(new transport::RtpSender(cast_environment, 64 rtp_sender_(new transport::RtpSender(cast_environment,
64 NULL, 65 NULL,
65 &video_config, 66 &video_config,
66 paced_packet_sender)), 67 paced_packet_sender)),
(...skipping 10 matching lines...) Expand all
77 weak_factory_(this) { 78 weak_factory_(this) {
78 max_unacked_frames_ = static_cast<uint8>(video_config.rtp_max_delay_ms * 79 max_unacked_frames_ = static_cast<uint8>(video_config.rtp_max_delay_ms *
79 video_config.max_frame_rate / 1000) + 1; 80 video_config.max_frame_rate / 1000) + 1;
80 VLOG(1) << "max_unacked_frames " << static_cast<int>(max_unacked_frames_); 81 VLOG(1) << "max_unacked_frames " << static_cast<int>(max_unacked_frames_);
81 DCHECK_GT(max_unacked_frames_, 0) << "Invalid argument"; 82 DCHECK_GT(max_unacked_frames_, 0) << "Invalid argument";
82 83
83 rtp_video_sender_statistics_.reset( 84 rtp_video_sender_statistics_.reset(
84 new LocalRtpVideoSenderStatistics(rtp_sender_.get())); 85 new LocalRtpVideoSenderStatistics(rtp_sender_.get()));
85 86
86 if (video_config.use_external_encoder) { 87 if (video_config.use_external_encoder) {
87 DCHECK(video_encoder_controller) << "Invalid argument"; 88 video_encoder_.reset(new ExternalVideoEncoder(cast_environment,
88 video_encoder_controller_ = video_encoder_controller; 89 video_config, gpu_factories));
89 } else { 90 } else {
90 video_encoder_.reset(new VideoEncoder(cast_environment, video_config, 91 video_encoder_.reset(new VideoEncoderImpl(cast_environment, video_config,
91 max_unacked_frames_)); 92 max_unacked_frames_));
92 video_encoder_controller_ = video_encoder_.get();
93 } 93 }
94 94
95 if (video_config.aes_iv_mask.size() == kAesKeySize && 95 if (video_config.aes_iv_mask.size() == kAesKeySize &&
96 video_config.aes_key.size() == kAesKeySize) { 96 video_config.aes_key.size() == kAesKeySize) {
97 iv_mask_ = video_config.aes_iv_mask; 97 iv_mask_ = video_config.aes_iv_mask;
98 encryption_key_.reset(crypto::SymmetricKey::Import( 98 encryption_key_.reset(crypto::SymmetricKey::Import(
99 crypto::SymmetricKey::AES, video_config.aes_key)); 99 crypto::SymmetricKey::AES, video_config.aes_key));
100 encryptor_.reset(new crypto::Encryptor()); 100 encryptor_.reset(new crypto::Encryptor());
101 encryptor_->Init(encryption_key_.get(), 101 encryptor_->Init(encryption_key_.get(),
102 crypto::Encryptor::CTR, 102 crypto::Encryptor::CTR,
103 std::string()); 103 std::string());
104 } else if (video_config.aes_iv_mask.size() != 0 || 104 } else if (video_config.aes_iv_mask.size() != 0 ||
105 video_config.aes_key.size() != 0) { 105 video_config.aes_key.size() != 0) {
106 DCHECK(false) << "Invalid crypto configuration"; 106 NOTREACHED() << "Invalid crypto configuration";
107 } 107 }
108 108
109 rtcp_.reset(new Rtcp( 109 rtcp_.reset(new Rtcp(
110 cast_environment_, 110 cast_environment_,
111 rtcp_feedback_.get(), 111 rtcp_feedback_.get(),
112 paced_packet_sender, 112 paced_packet_sender,
113 rtp_video_sender_statistics_.get(), 113 rtp_video_sender_statistics_.get(),
114 NULL, 114 NULL,
115 video_config.rtcp_mode, 115 video_config.rtcp_mode,
116 base::TimeDelta::FromMilliseconds(video_config.rtcp_interval), 116 base::TimeDelta::FromMilliseconds(video_config.rtcp_interval),
(...skipping 23 matching lines...) Expand all
140 base::TimeTicks now = cast_environment_->Clock()->NowTicks(); 140 base::TimeTicks now = cast_environment_->Clock()->NowTicks();
141 cast_environment_->Logging()->InsertFrameEvent(now, kVideoFrameReceived, 141 cast_environment_->Logging()->InsertFrameEvent(now, kVideoFrameReceived,
142 GetVideoRtpTimestamp(capture_time), kFrameIdUnknown); 142 GetVideoRtpTimestamp(capture_time), kFrameIdUnknown);
143 143
144 if (!video_encoder_->EncodeVideoFrame(video_frame, capture_time, 144 if (!video_encoder_->EncodeVideoFrame(video_frame, capture_time,
145 base::Bind(&VideoSender::SendEncodedVideoFrameMainThread, 145 base::Bind(&VideoSender::SendEncodedVideoFrameMainThread,
146 weak_factory_.GetWeakPtr()))) { 146 weak_factory_.GetWeakPtr()))) {
147 } 147 }
148 } 148 }
149 149
150 void VideoSender::InsertCodedVideoFrame(const EncodedVideoFrame* encoded_frame,
151 const base::TimeTicks& capture_time,
152 const base::Closure callback) {
153 DCHECK(!video_encoder_.get()) << "Invalid state";
154 DCHECK(encoded_frame) << "Invalid argument";
155 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
156
157 SendEncodedVideoFrame(encoded_frame, capture_time);
158 cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE, callback);
159 }
160
161 void VideoSender::SendEncodedVideoFrameMainThread( 150 void VideoSender::SendEncodedVideoFrameMainThread(
162 scoped_ptr<EncodedVideoFrame> video_frame, 151 scoped_ptr<EncodedVideoFrame> video_frame,
163 const base::TimeTicks& capture_time) { 152 const base::TimeTicks& capture_time) {
164 SendEncodedVideoFrame(video_frame.get(), capture_time); 153 SendEncodedVideoFrame(video_frame.get(), capture_time);
165 } 154 }
166 155
167 bool VideoSender::EncryptVideoFrame(const EncodedVideoFrame& video_frame, 156 bool VideoSender::EncryptVideoFrame(const EncodedVideoFrame& video_frame,
168 EncodedVideoFrame* encrypted_frame) { 157 EncodedVideoFrame* encrypted_frame) {
169 DCHECK(encryptor_) << "Invalid state"; 158 DCHECK(encryptor_) << "Invalid state";
170 159
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 } 294 }
306 295
307 void VideoSender::ResendCheck() { 296 void VideoSender::ResendCheck() {
308 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 297 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
309 if (!last_send_time_.is_null() && last_sent_frame_id_ != -1) { 298 if (!last_send_time_.is_null() && last_sent_frame_id_ != -1) {
310 base::TimeDelta time_since_last_send = 299 base::TimeDelta time_since_last_send =
311 cast_environment_->Clock()->NowTicks() - last_send_time_; 300 cast_environment_->Clock()->NowTicks() - last_send_time_;
312 if (time_since_last_send > rtp_max_delay_) { 301 if (time_since_last_send > rtp_max_delay_) {
313 if (last_acked_frame_id_ == -1) { 302 if (last_acked_frame_id_ == -1) {
314 // We have not received any ack, send a key frame. 303 // We have not received any ack, send a key frame.
315 video_encoder_controller_->GenerateKeyFrame(); 304 video_encoder_->GenerateKeyFrame();
316 last_acked_frame_id_ = -1; 305 last_acked_frame_id_ = -1;
317 last_sent_frame_id_ = -1; 306 last_sent_frame_id_ = -1;
318 UpdateFramesInFlight(); 307 UpdateFramesInFlight();
319 } else { 308 } else {
320 DCHECK_LE(0, last_acked_frame_id_); 309 DCHECK_LE(0, last_acked_frame_id_);
321 310
322 uint32 frame_id = static_cast<uint32>(last_acked_frame_id_ + 1); 311 uint32 frame_id = static_cast<uint32>(last_acked_frame_id_ + 1);
323 VLOG(1) << "ACK timeout resend frame:" << static_cast<int>(frame_id); 312 VLOG(1) << "ACK timeout resend frame:" << static_cast<int>(frame_id);
324 ResendFrame(frame_id); 313 ResendFrame(frame_id);
325 } 314 }
(...skipping 16 matching lines...) Expand all
342 time_to_next = std::max(time_to_next, 331 time_to_next = std::max(time_to_next,
343 base::TimeDelta::FromMilliseconds(kMinSchedulingDelayMs)); 332 base::TimeDelta::FromMilliseconds(kMinSchedulingDelayMs));
344 333
345 cast_environment_->PostDelayedTask(CastEnvironment::MAIN, FROM_HERE, 334 cast_environment_->PostDelayedTask(CastEnvironment::MAIN, FROM_HERE,
346 base::Bind(&VideoSender::SkippedFramesCheck, weak_factory_.GetWeakPtr()), 335 base::Bind(&VideoSender::SkippedFramesCheck, weak_factory_.GetWeakPtr()),
347 time_to_next); 336 time_to_next);
348 } 337 }
349 338
350 void VideoSender::SkippedFramesCheck() { 339 void VideoSender::SkippedFramesCheck() {
351 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 340 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
352 int skip_count = video_encoder_controller_->NumberOfSkippedFrames(); 341 int skip_count = video_encoder_->NumberOfSkippedFrames();
353 if (skip_count - last_skip_count_ > 342 if (skip_count - last_skip_count_ >
354 kSkippedFramesThreshold * max_frame_rate_) { 343 kSkippedFramesThreshold * max_frame_rate_) {
355 // TODO(pwestin): Propagate this up to the application. 344 // TODO(pwestin): Propagate this up to the application.
356 } 345 }
357 last_skip_count_ = skip_count; 346 last_skip_count_ = skip_count;
358 last_checked_skip_count_time_ = cast_environment_->Clock()->NowTicks(); 347 last_checked_skip_count_time_ = cast_environment_->Clock()->NowTicks();
359 ScheduleNextSkippedFramesCheck(); 348 ScheduleNextSkippedFramesCheck();
360 } 349 }
361 350
362 void VideoSender::OnReceivedCastFeedback(const RtcpCastMessage& cast_feedback) { 351 void VideoSender::OnReceivedCastFeedback(const RtcpCastMessage& cast_feedback) {
(...skipping 11 matching lines...) Expand all
374 rtt = std::max(rtt, avg_rtt); 363 rtt = std::max(rtt, avg_rtt);
375 } else { 364 } else {
376 // We have no measured value use default. 365 // We have no measured value use default.
377 rtt = base::TimeDelta::FromMilliseconds(kStartRttMs); 366 rtt = base::TimeDelta::FromMilliseconds(kStartRttMs);
378 } 367 }
379 if (cast_feedback.missing_frames_and_packets_.empty()) { 368 if (cast_feedback.missing_frames_and_packets_.empty()) {
380 // No lost packets. 369 // No lost packets.
381 int resend_frame = -1; 370 int resend_frame = -1;
382 if (last_sent_frame_id_ == -1) return; 371 if (last_sent_frame_id_ == -1) return;
383 372
384 video_encoder_controller_->LatestFrameIdToReference( 373 video_encoder_->LatestFrameIdToReference(
385 cast_feedback.ack_frame_id_); 374 cast_feedback.ack_frame_id_);
386 375
387 if (static_cast<uint32>(last_acked_frame_id_ + 1) == 376 if (static_cast<uint32>(last_acked_frame_id_ + 1) ==
388 cast_feedback.ack_frame_id_) { 377 cast_feedback.ack_frame_id_) {
389 uint32 new_bitrate = 0; 378 uint32 new_bitrate = 0;
390 if (congestion_control_.OnAck(rtt, &new_bitrate)) { 379 if (congestion_control_.OnAck(rtt, &new_bitrate)) {
391 video_encoder_controller_->SetBitRate(new_bitrate); 380 video_encoder_->SetBitRate(new_bitrate);
392 } 381 }
393 } 382 }
394 if (static_cast<uint32>(last_acked_frame_id_) == cast_feedback.ack_frame_id_ 383 if (static_cast<uint32>(last_acked_frame_id_) == cast_feedback.ack_frame_id_
395 // We only count duplicate ACKs when we have sent newer frames. 384 // We only count duplicate ACKs when we have sent newer frames.
396 && IsNewerFrameId(last_sent_frame_id_, last_acked_frame_id_)) { 385 && IsNewerFrameId(last_sent_frame_id_, last_acked_frame_id_)) {
397 duplicate_ack_++; 386 duplicate_ack_++;
398 } else { 387 } else {
399 duplicate_ack_ = 0; 388 duplicate_ack_ = 0;
400 } 389 }
401 if (duplicate_ack_ >= 2 && duplicate_ack_ % 3 == 2) { 390 if (duplicate_ack_ >= 2 && duplicate_ack_ % 3 == 2) {
402 // Resend last ACK + 1 frame. 391 // Resend last ACK + 1 frame.
403 resend_frame = static_cast<uint32>(last_acked_frame_id_ + 1); 392 resend_frame = static_cast<uint32>(last_acked_frame_id_ + 1);
404 } 393 }
405 if (resend_frame != -1) { 394 if (resend_frame != -1) {
406 DCHECK_LE(0, resend_frame); 395 DCHECK_LE(0, resend_frame);
407 VLOG(1) << "Received duplicate ACK for frame:" 396 VLOG(1) << "Received duplicate ACK for frame:"
408 << static_cast<int>(resend_frame); 397 << static_cast<int>(resend_frame);
409 ResendFrame(static_cast<uint32>(resend_frame)); 398 ResendFrame(static_cast<uint32>(resend_frame));
410 } 399 }
411 } else { 400 } else {
412 rtp_sender_->ResendPackets(cast_feedback.missing_frames_and_packets_); 401 rtp_sender_->ResendPackets(cast_feedback.missing_frames_and_packets_);
413 last_send_time_ = now; 402 last_send_time_ = now;
414 403
415 uint32 new_bitrate = 0; 404 uint32 new_bitrate = 0;
416 if (congestion_control_.OnNack(rtt, &new_bitrate)) { 405 if (congestion_control_.OnNack(rtt, &new_bitrate)) {
417 video_encoder_controller_->SetBitRate(new_bitrate); 406 video_encoder_->SetBitRate(new_bitrate);
418 } 407 }
419 } 408 }
420 ReceivedAck(cast_feedback.ack_frame_id_); 409 ReceivedAck(cast_feedback.ack_frame_id_);
421 } 410 }
422 411
423 void VideoSender::ReceivedAck(uint32 acked_frame_id) { 412 void VideoSender::ReceivedAck(uint32 acked_frame_id) {
424 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 413 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
425 last_acked_frame_id_ = static_cast<int>(acked_frame_id); 414 last_acked_frame_id_ = static_cast<int>(acked_frame_id);
426 base::TimeTicks now = cast_environment_->Clock()->NowTicks(); 415 base::TimeTicks now = cast_environment_->Clock()->NowTicks();
427 cast_environment_->Logging()->InsertGenericEvent(now, kAckReceived, 416 cast_environment_->Logging()->InsertGenericEvent(now, kAckReceived,
(...skipping 11 matching lines...) Expand all
439 if (last_acked_frame_id_ != -1) { 428 if (last_acked_frame_id_ != -1) {
440 DCHECK_LE(0, last_acked_frame_id_); 429 DCHECK_LE(0, last_acked_frame_id_);
441 frames_in_flight = static_cast<uint32>(last_sent_frame_id_) - 430 frames_in_flight = static_cast<uint32>(last_sent_frame_id_) -
442 static_cast<uint32>(last_acked_frame_id_); 431 static_cast<uint32>(last_acked_frame_id_);
443 } else { 432 } else {
444 frames_in_flight = static_cast<uint32>(last_sent_frame_id_) + 1; 433 frames_in_flight = static_cast<uint32>(last_sent_frame_id_) + 1;
445 } 434 }
446 VLOG(1) << "Frames in flight; last sent: " << last_sent_frame_id_ 435 VLOG(1) << "Frames in flight; last sent: " << last_sent_frame_id_
447 << " last acked:" << last_acked_frame_id_; 436 << " last acked:" << last_acked_frame_id_;
448 if (frames_in_flight >= max_unacked_frames_) { 437 if (frames_in_flight >= max_unacked_frames_) {
449 video_encoder_controller_->SkipNextFrame(true); 438 video_encoder_->SkipNextFrame(true);
450 return; 439 return;
451 } 440 }
452 } 441 }
453 video_encoder_controller_->SkipNextFrame(false); 442 video_encoder_->SkipNextFrame(false);
454 } 443 }
455 444
456 void VideoSender::ResendFrame(uint32 resend_frame_id) { 445 void VideoSender::ResendFrame(uint32 resend_frame_id) {
457 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 446 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
458 MissingFramesAndPacketsMap missing_frames_and_packets; 447 MissingFramesAndPacketsMap missing_frames_and_packets;
459 PacketIdSet missing; 448 PacketIdSet missing;
460 missing_frames_and_packets.insert(std::make_pair(resend_frame_id, missing)); 449 missing_frames_and_packets.insert(std::make_pair(resend_frame_id, missing));
461 rtp_sender_->ResendPackets(missing_frames_and_packets); 450 rtp_sender_->ResendPackets(missing_frames_and_packets);
462 last_send_time_ = cast_environment_->Clock()->NowTicks(); 451 last_send_time_ = cast_environment_->Clock()->NowTicks();
463 } 452 }
464 453
465 } // namespace cast 454 } // namespace cast
466 } // namespace media 455 } // namespace media
OLDNEW
« no previous file with comments | « media/cast/video_sender/video_sender.h ('k') | media/cast/video_sender/video_sender.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698