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_; |
miu
2014/08/05 21:52:07
nit/bike-shedding: How about killing the extra |bi
Alpha Left Google
2014/08/06 01:24:54
bitrate is used in line 153.
| |
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 |