| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/sender/video_sender.h" | 5 #include "media/cast/sender/video_sender.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cstring> | 8 #include <cstring> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/debug/trace_event.h" | 11 #include "base/debug/trace_event.h" |
| 12 #include "base/logging.h" | 12 #include "base/logging.h" |
| 13 #include "base/message_loop/message_loop.h" | 13 #include "base/message_loop/message_loop.h" |
| 14 #include "media/cast/cast_defines.h" | 14 #include "media/cast/cast_defines.h" |
| 15 #include "media/cast/net/cast_transport_config.h" | 15 #include "media/cast/net/cast_transport_config.h" |
| 16 #include "media/cast/sender/external_video_encoder.h" | 16 #include "media/cast/sender/external_video_encoder.h" |
| 17 #include "media/cast/sender/video_encoder_impl.h" | 17 #include "media/cast/sender/video_encoder_impl.h" |
| 18 | 18 |
| 19 namespace media { | 19 namespace media { |
| 20 namespace cast { | 20 namespace cast { |
| 21 | 21 |
| 22 const int kNumAggressiveReportsSentAtStart = 100; | 22 const int kNumAggressiveReportsSentAtStart = 100; |
| 23 const int kMinSchedulingDelayMs = 1; | 23 const int kMinSchedulingDelayMs = 1; |
| 24 | 24 |
| 25 namespace { |
| 26 |
| 27 // Returns a fixed bitrate value when external video encoder is used. |
| 28 // Some hardware encoder shows bad behavior if we set the bitrate too |
| 29 // frequently, e.g. quality drop, not abiding by target bitrate, etc. |
| 30 // See details: crbug.com/392086. |
| 31 size_t GetFixedBitrate(const VideoSenderConfig& video_config) { |
| 32 if (!video_config.use_external_encoder) |
| 33 return 0; |
| 34 return (video_config.min_bitrate + video_config.max_bitrate) / 2; |
| 35 } |
| 36 |
| 37 } // namespace |
| 38 |
| 25 VideoSender::VideoSender( | 39 VideoSender::VideoSender( |
| 26 scoped_refptr<CastEnvironment> cast_environment, | 40 scoped_refptr<CastEnvironment> cast_environment, |
| 27 const VideoSenderConfig& video_config, | 41 const VideoSenderConfig& video_config, |
| 28 const CreateVideoEncodeAcceleratorCallback& create_vea_cb, | 42 const CreateVideoEncodeAcceleratorCallback& create_vea_cb, |
| 29 const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb, | 43 const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb, |
| 30 CastTransportSender* const transport_sender) | 44 CastTransportSender* const transport_sender) |
| 31 : FrameSender( | 45 : FrameSender( |
| 32 cast_environment, | 46 cast_environment, |
| 33 transport_sender, | 47 transport_sender, |
| 34 base::TimeDelta::FromMilliseconds(video_config.rtcp_interval), | 48 base::TimeDelta::FromMilliseconds(video_config.rtcp_interval), |
| 35 kVideoFrequency, | 49 kVideoFrequency, |
| 36 video_config.ssrc), | 50 video_config.ssrc), |
| 37 target_playout_delay_(video_config.target_playout_delay), | 51 target_playout_delay_(video_config.target_playout_delay), |
| 38 max_unacked_frames_( | 52 max_unacked_frames_( |
| 39 std::min(kMaxUnackedFrames, | 53 std::min(kMaxUnackedFrames, |
| 40 1 + static_cast<int>(target_playout_delay_ * | 54 1 + static_cast<int>(target_playout_delay_ * |
| 41 video_config.max_frame_rate / | 55 video_config.max_frame_rate / |
| 42 base::TimeDelta::FromSeconds(1)))), | 56 base::TimeDelta::FromSeconds(1)))), |
| 57 fixed_bitrate_(GetFixedBitrate(video_config)), |
| 43 num_aggressive_rtcp_reports_sent_(0), | 58 num_aggressive_rtcp_reports_sent_(0), |
| 44 frames_in_encoder_(0), | 59 frames_in_encoder_(0), |
| 45 last_sent_frame_id_(0), | 60 last_sent_frame_id_(0), |
| 46 latest_acked_frame_id_(0), | 61 latest_acked_frame_id_(0), |
| 47 duplicate_ack_counter_(0), | 62 duplicate_ack_counter_(0), |
| 48 congestion_control_(cast_environment->Clock(), | 63 congestion_control_(cast_environment->Clock(), |
| 49 video_config.max_bitrate, | 64 video_config.max_bitrate, |
| 50 video_config.min_bitrate, | 65 video_config.min_bitrate, |
| 51 max_unacked_frames_), | 66 max_unacked_frames_), |
| 52 cast_initialization_status_(STATUS_VIDEO_UNINITIALIZED), | 67 cast_initialization_status_(STATUS_VIDEO_UNINITIALIZED), |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 110 "cast_perf_test", "InsertRawVideoFrame", | 125 "cast_perf_test", "InsertRawVideoFrame", |
| 111 TRACE_EVENT_SCOPE_THREAD, | 126 TRACE_EVENT_SCOPE_THREAD, |
| 112 "timestamp", capture_time.ToInternalValue(), | 127 "timestamp", capture_time.ToInternalValue(), |
| 113 "rtp_timestamp", rtp_timestamp); | 128 "rtp_timestamp", rtp_timestamp); |
| 114 | 129 |
| 115 if (AreTooManyFramesInFlight()) { | 130 if (AreTooManyFramesInFlight()) { |
| 116 VLOG(1) << "Dropping frame due to too many frames currently in-flight."; | 131 VLOG(1) << "Dropping frame due to too many frames currently in-flight."; |
| 117 return; | 132 return; |
| 118 } | 133 } |
| 119 | 134 |
| 120 uint32 bitrate = congestion_control_.GetBitrate( | 135 uint32 bitrate = fixed_bitrate_; |
| 121 capture_time + target_playout_delay_, target_playout_delay_); | 136 if (!bitrate) { |
| 122 | 137 bitrate = congestion_control_.GetBitrate( |
| 123 video_encoder_->SetBitRate(bitrate); | 138 capture_time + target_playout_delay_, target_playout_delay_); |
| 139 DCHECK(bitrate); |
| 140 video_encoder_->SetBitRate(bitrate); |
| 141 } else if (last_send_time_.is_null()) { |
| 142 // Set the fixed bitrate value to codec until a frame is sent. We might |
| 143 // set this value a couple times at the very beginning of the stream but |
| 144 // it is not harmful. |
| 145 video_encoder_->SetBitRate(bitrate); |
| 146 } |
| 124 | 147 |
| 125 if (video_encoder_->EncodeVideoFrame( | 148 if (video_encoder_->EncodeVideoFrame( |
| 126 video_frame, | 149 video_frame, |
| 127 capture_time, | 150 capture_time, |
| 128 base::Bind(&VideoSender::SendEncodedVideoFrame, | 151 base::Bind(&VideoSender::SendEncodedVideoFrame, |
| 129 weak_factory_.GetWeakPtr(), | 152 weak_factory_.GetWeakPtr(), |
| 130 bitrate))) { | 153 bitrate))) { |
| 131 frames_in_encoder_++; | 154 frames_in_encoder_++; |
| 132 } else { | 155 } else { |
| 133 VLOG(1) << "Encoder rejected a frame. Skipping..."; | 156 VLOG(1) << "Encoder rejected a frame. Skipping..."; |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 348 last_send_time_ = cast_environment_->Clock()->NowTicks(); | 371 last_send_time_ = cast_environment_->Clock()->NowTicks(); |
| 349 | 372 |
| 350 // Sending this extra packet is to kick-start the session. There is | 373 // Sending this extra packet is to kick-start the session. There is |
| 351 // no need to optimize re-transmission for this case. | 374 // no need to optimize re-transmission for this case. |
| 352 transport_sender_->ResendPackets(false, missing_frames_and_packets, | 375 transport_sender_->ResendPackets(false, missing_frames_and_packets, |
| 353 false, rtt_); | 376 false, rtt_); |
| 354 } | 377 } |
| 355 | 378 |
| 356 } // namespace cast | 379 } // namespace cast |
| 357 } // namespace media | 380 } // namespace media |
| OLD | NEW |