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

Side by Side Diff: webrtc/video/video_send_stream.cc

Issue 2060403002: Add task queue to Call. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@move_getpadding
Patch Set: Use SequencedTaskChecker in i420_buffer_pool.cc Created 4 years, 5 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
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10
11 #include "webrtc/video/video_send_stream.h" 10 #include "webrtc/video/video_send_stream.h"
12 11
13 #include <algorithm> 12 #include <algorithm>
14 #include <sstream> 13 #include <sstream>
15 #include <string> 14 #include <string>
16 #include <utility> 15 #include <utility>
17 #include <vector> 16 #include <vector>
18 17
19 #include "webrtc/base/checks.h" 18 #include "webrtc/base/checks.h"
20 #include "webrtc/base/logging.h" 19 #include "webrtc/base/logging.h"
21 #include "webrtc/base/trace_event.h" 20 #include "webrtc/base/trace_event.h"
22 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
23 #include "webrtc/modules/bitrate_controller/include/bitrate_controller.h" 21 #include "webrtc/modules/bitrate_controller/include/bitrate_controller.h"
24 #include "webrtc/modules/congestion_controller/include/congestion_controller.h" 22 #include "webrtc/modules/congestion_controller/include/congestion_controller.h"
25 #include "webrtc/modules/pacing/packet_router.h" 23 #include "webrtc/modules/pacing/packet_router.h"
26 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h" 24 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
27 #include "webrtc/modules/utility/include/process_thread.h" 25 #include "webrtc/modules/utility/include/process_thread.h"
28 #include "webrtc/modules/video_coding/utility/ivf_file_writer.h" 26 #include "webrtc/modules/video_coding/utility/ivf_file_writer.h"
29 #include "webrtc/video/call_stats.h" 27 #include "webrtc/video/call_stats.h"
30 #include "webrtc/video/video_capture_input.h"
31 #include "webrtc/video/vie_remb.h" 28 #include "webrtc/video/vie_remb.h"
32 #include "webrtc/video_send_stream.h" 29 #include "webrtc/video_send_stream.h"
33 30
34 namespace webrtc { 31 namespace webrtc {
35 32
36 class RtcpIntraFrameObserver;
37 class TransportFeedbackObserver;
38
39 static const int kMinSendSidePacketHistorySize = 600; 33 static const int kMinSendSidePacketHistorySize = 600;
40 static const int kEncoderTimeOutMs = 2000;
41
42 namespace { 34 namespace {
43 35
44 std::vector<RtpRtcp*> CreateRtpRtcpModules( 36 std::vector<RtpRtcp*> CreateRtpRtcpModules(
45 Transport* outgoing_transport, 37 Transport* outgoing_transport,
46 RtcpIntraFrameObserver* intra_frame_callback, 38 RtcpIntraFrameObserver* intra_frame_callback,
47 RtcpBandwidthObserver* bandwidth_callback, 39 RtcpBandwidthObserver* bandwidth_callback,
48 TransportFeedbackObserver* transport_feedback_callback, 40 TransportFeedbackObserver* transport_feedback_callback,
49 RtcpRttStats* rtt_stats, 41 RtcpRttStats* rtt_stats,
50 RtpPacketSender* paced_sender, 42 RtpPacketSender* paced_sender,
51 TransportSequenceNumberAllocator* transport_sequence_number_allocator, 43 TransportSequenceNumberAllocator* transport_sequence_number_allocator,
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 } 135 }
144 136
145 std::string VideoSendStream::Config::ToString() const { 137 std::string VideoSendStream::Config::ToString() const {
146 std::stringstream ss; 138 std::stringstream ss;
147 ss << "{encoder_settings: " << encoder_settings.ToString(); 139 ss << "{encoder_settings: " << encoder_settings.ToString();
148 ss << ", rtp: " << rtp.ToString(); 140 ss << ", rtp: " << rtp.ToString();
149 ss << ", pre_encode_callback: " 141 ss << ", pre_encode_callback: "
150 << (pre_encode_callback ? "(I420FrameCallback)" : "nullptr"); 142 << (pre_encode_callback ? "(I420FrameCallback)" : "nullptr");
151 ss << ", post_encode_callback: " 143 ss << ", post_encode_callback: "
152 << (post_encode_callback ? "(EncodedFrameObserver)" : "nullptr"); 144 << (post_encode_callback ? "(EncodedFrameObserver)" : "nullptr");
153 ss << ", local_renderer: "
154 << (local_renderer ? "(VideoRenderer)" : "nullptr");
155 ss << ", render_delay_ms: " << render_delay_ms; 145 ss << ", render_delay_ms: " << render_delay_ms;
156 ss << ", target_delay_ms: " << target_delay_ms; 146 ss << ", target_delay_ms: " << target_delay_ms;
157 ss << ", suspend_below_min_bitrate: " << (suspend_below_min_bitrate ? "on" 147 ss << ", suspend_below_min_bitrate: " << (suspend_below_min_bitrate ? "on"
158 : "off"); 148 : "off");
159 ss << '}'; 149 ss << '}';
160 return ss.str(); 150 return ss.str();
161 } 151 }
162 152
163 namespace { 153 namespace {
164 154
165 VideoCodecType PayloadNameToCodecType(const std::string& payload_name) {
166 if (payload_name == "VP8")
167 return kVideoCodecVP8;
168 if (payload_name == "VP9")
169 return kVideoCodecVP9;
170 if (payload_name == "H264")
171 return kVideoCodecH264;
172 return kVideoCodecGeneric;
173 }
174
175 bool PayloadTypeSupportsSkippingFecPackets(const std::string& payload_name) { 155 bool PayloadTypeSupportsSkippingFecPackets(const std::string& payload_name) {
176 switch (PayloadNameToCodecType(payload_name)) { 156 if (payload_name == "VP8" || payload_name == "VP9")
177 case kVideoCodecVP8: 157 return true;
178 case kVideoCodecVP9: 158 RTC_DCHECK(payload_name == "H264" || payload_name == "FAKE")
179 return true; 159 << "unknown payload_name " << payload_name;
180 case kVideoCodecH264:
181 case kVideoCodecGeneric:
182 return false;
183 case kVideoCodecI420:
184 case kVideoCodecRED:
185 case kVideoCodecULPFEC:
186 case kVideoCodecUnknown:
187 RTC_NOTREACHED();
188 return false;
189 }
190 RTC_NOTREACHED();
191 return false; 160 return false;
192 } 161 }
193 162
194 // TODO(pbos): Lower these thresholds (to closer to 100%) when we handle 163 int CalculateMaxPadBitrateBps(const VideoEncoderConfig& config,
195 // pipelining encoders better (multiple input frames before something comes
196 // out). This should effectively turn off CPU adaptations for systems that
197 // remotely cope with the load right now.
198 CpuOveruseOptions GetCpuOveruseOptions(bool full_overuse_time) {
199 CpuOveruseOptions options;
200 if (full_overuse_time) {
201 options.low_encode_usage_threshold_percent = 150;
202 options.high_encode_usage_threshold_percent = 200;
203 }
204 return options;
205 }
206
207 VideoCodec VideoEncoderConfigToVideoCodec(const VideoEncoderConfig& config,
208 const std::string& payload_name,
209 int payload_type) {
210 const std::vector<VideoStream>& streams = config.streams;
211 static const int kEncoderMinBitrateKbps = 30;
212 RTC_DCHECK(!streams.empty());
213 RTC_DCHECK_GE(config.min_transmit_bitrate_bps, 0);
214
215 VideoCodec video_codec;
216 memset(&video_codec, 0, sizeof(video_codec));
217 video_codec.codecType = PayloadNameToCodecType(payload_name);
218
219 switch (config.content_type) {
220 case VideoEncoderConfig::ContentType::kRealtimeVideo:
221 video_codec.mode = kRealtimeVideo;
222 break;
223 case VideoEncoderConfig::ContentType::kScreen:
224 video_codec.mode = kScreensharing;
225 if (config.streams.size() == 1 &&
226 config.streams[0].temporal_layer_thresholds_bps.size() == 1) {
227 video_codec.targetBitrate =
228 config.streams[0].temporal_layer_thresholds_bps[0] / 1000;
229 }
230 break;
231 }
232
233 switch (video_codec.codecType) {
234 case kVideoCodecVP8: {
235 if (config.encoder_specific_settings) {
236 video_codec.codecSpecific.VP8 = *reinterpret_cast<const VideoCodecVP8*>(
237 config.encoder_specific_settings);
238 } else {
239 video_codec.codecSpecific.VP8 = VideoEncoder::GetDefaultVp8Settings();
240 }
241 video_codec.codecSpecific.VP8.numberOfTemporalLayers =
242 static_cast<unsigned char>(
243 streams.back().temporal_layer_thresholds_bps.size() + 1);
244 break;
245 }
246 case kVideoCodecVP9: {
247 if (config.encoder_specific_settings) {
248 video_codec.codecSpecific.VP9 = *reinterpret_cast<const VideoCodecVP9*>(
249 config.encoder_specific_settings);
250 if (video_codec.mode == kScreensharing) {
251 video_codec.codecSpecific.VP9.flexibleMode = true;
252 // For now VP9 screensharing use 1 temporal and 2 spatial layers.
253 RTC_DCHECK_EQ(video_codec.codecSpecific.VP9.numberOfTemporalLayers,
254 1);
255 RTC_DCHECK_EQ(video_codec.codecSpecific.VP9.numberOfSpatialLayers, 2);
256 }
257 } else {
258 video_codec.codecSpecific.VP9 = VideoEncoder::GetDefaultVp9Settings();
259 }
260 video_codec.codecSpecific.VP9.numberOfTemporalLayers =
261 static_cast<unsigned char>(
262 streams.back().temporal_layer_thresholds_bps.size() + 1);
263 break;
264 }
265 case kVideoCodecH264: {
266 if (config.encoder_specific_settings) {
267 video_codec.codecSpecific.H264 =
268 *reinterpret_cast<const VideoCodecH264*>(
269 config.encoder_specific_settings);
270 } else {
271 video_codec.codecSpecific.H264 = VideoEncoder::GetDefaultH264Settings();
272 }
273 break;
274 }
275 default:
276 // TODO(pbos): Support encoder_settings codec-agnostically.
277 RTC_DCHECK(!config.encoder_specific_settings)
278 << "Encoder-specific settings for codec type not wired up.";
279 break;
280 }
281
282 strncpy(video_codec.plName, payload_name.c_str(), kPayloadNameSize - 1);
283 video_codec.plName[kPayloadNameSize - 1] = '\0';
284 video_codec.plType = payload_type;
285 video_codec.numberOfSimulcastStreams =
286 static_cast<unsigned char>(streams.size());
287 video_codec.minBitrate = streams[0].min_bitrate_bps / 1000;
288 if (video_codec.minBitrate < kEncoderMinBitrateKbps)
289 video_codec.minBitrate = kEncoderMinBitrateKbps;
290 RTC_DCHECK_LE(streams.size(), static_cast<size_t>(kMaxSimulcastStreams));
291 if (video_codec.codecType == kVideoCodecVP9) {
292 // If the vector is empty, bitrates will be configured automatically.
293 RTC_DCHECK(config.spatial_layers.empty() ||
294 config.spatial_layers.size() ==
295 video_codec.codecSpecific.VP9.numberOfSpatialLayers);
296 RTC_DCHECK_LE(video_codec.codecSpecific.VP9.numberOfSpatialLayers,
297 kMaxSimulcastStreams);
298 for (size_t i = 0; i < config.spatial_layers.size(); ++i)
299 video_codec.spatialLayers[i] = config.spatial_layers[i];
300 }
301 for (size_t i = 0; i < streams.size(); ++i) {
302 SimulcastStream* sim_stream = &video_codec.simulcastStream[i];
303 RTC_DCHECK_GT(streams[i].width, 0u);
304 RTC_DCHECK_GT(streams[i].height, 0u);
305 RTC_DCHECK_GT(streams[i].max_framerate, 0);
306 // Different framerates not supported per stream at the moment.
307 RTC_DCHECK_EQ(streams[i].max_framerate, streams[0].max_framerate);
308 RTC_DCHECK_GE(streams[i].min_bitrate_bps, 0);
309 RTC_DCHECK_GE(streams[i].target_bitrate_bps, streams[i].min_bitrate_bps);
310 RTC_DCHECK_GE(streams[i].max_bitrate_bps, streams[i].target_bitrate_bps);
311 RTC_DCHECK_GE(streams[i].max_qp, 0);
312
313 sim_stream->width = static_cast<uint16_t>(streams[i].width);
314 sim_stream->height = static_cast<uint16_t>(streams[i].height);
315 sim_stream->minBitrate = streams[i].min_bitrate_bps / 1000;
316 sim_stream->targetBitrate = streams[i].target_bitrate_bps / 1000;
317 sim_stream->maxBitrate = streams[i].max_bitrate_bps / 1000;
318 sim_stream->qpMax = streams[i].max_qp;
319 sim_stream->numberOfTemporalLayers = static_cast<unsigned char>(
320 streams[i].temporal_layer_thresholds_bps.size() + 1);
321
322 video_codec.width = std::max(video_codec.width,
323 static_cast<uint16_t>(streams[i].width));
324 video_codec.height = std::max(
325 video_codec.height, static_cast<uint16_t>(streams[i].height));
326 video_codec.minBitrate =
327 std::min(static_cast<uint16_t>(video_codec.minBitrate),
328 static_cast<uint16_t>(streams[i].min_bitrate_bps / 1000));
329 video_codec.maxBitrate += streams[i].max_bitrate_bps / 1000;
330 video_codec.qpMax = std::max(video_codec.qpMax,
331 static_cast<unsigned int>(streams[i].max_qp));
332 }
333
334 if (video_codec.maxBitrate == 0) {
335 // Unset max bitrate -> cap to one bit per pixel.
336 video_codec.maxBitrate =
337 (video_codec.width * video_codec.height * video_codec.maxFramerate) /
338 1000;
339 }
340 if (video_codec.maxBitrate < kEncoderMinBitrateKbps)
341 video_codec.maxBitrate = kEncoderMinBitrateKbps;
342
343 RTC_DCHECK_GT(streams[0].max_framerate, 0);
344 video_codec.maxFramerate = streams[0].max_framerate;
345 video_codec.expect_encode_from_texture = config.expect_encode_from_texture;
346
347 return video_codec;
348 }
349
350 int CalulcateMaxPadBitrateBps(const VideoEncoderConfig& config,
351 bool pad_to_min_bitrate) { 164 bool pad_to_min_bitrate) {
352 int pad_up_to_bitrate_bps = 0; 165 int pad_up_to_bitrate_bps = 0;
353 // Calculate max padding bitrate for a multi layer codec. 166 // Calculate max padding bitrate for a multi layer codec.
354 if (config.streams.size() > 1) { 167 if (config.streams.size() > 1) {
355 // Pad to min bitrate of the highest layer. 168 // Pad to min bitrate of the highest layer.
356 pad_up_to_bitrate_bps = 169 pad_up_to_bitrate_bps =
357 config.streams[config.streams.size() - 1].min_bitrate_bps; 170 config.streams[config.streams.size() - 1].min_bitrate_bps;
358 // Add target_bitrate_bps of the lower layers. 171 // Add target_bitrate_bps of the lower layers.
359 for (size_t i = 0; i < config.streams.size() - 1; ++i) 172 for (size_t i = 0; i < config.streams.size() - 1; ++i)
360 pad_up_to_bitrate_bps += config.streams[i].target_bitrate_bps; 173 pad_up_to_bitrate_bps += config.streams[i].target_bitrate_bps;
361 } else if (pad_to_min_bitrate) { 174 } else if (pad_to_min_bitrate) {
362 pad_up_to_bitrate_bps = config.streams[0].min_bitrate_bps; 175 pad_up_to_bitrate_bps = config.streams[0].min_bitrate_bps;
363 } 176 }
364 177
365 pad_up_to_bitrate_bps = 178 pad_up_to_bitrate_bps =
366 std::max(pad_up_to_bitrate_bps, config.min_transmit_bitrate_bps); 179 std::max(pad_up_to_bitrate_bps, config.min_transmit_bitrate_bps);
367 180
368 return pad_up_to_bitrate_bps; 181 return pad_up_to_bitrate_bps;
369 } 182 }
370 183
371 } // namespace 184 } // namespace
372 185
373 namespace internal { 186 namespace internal {
187
188 // VideoSendStreamImpl implements internal::VideoSendStream.
189 // It is created and destroyed on |worker_queue|. The intent is to decrease the
190 // need for locking and to ensure methods are called in sequence.
191 // Public methods except |DeliverRtcp| must be called on |worker_queue|.
192 // DeliverRtcp is called on the libjingle worker thread or a network thread.
193 // An encoder may deliver frames through the EncodedImageCallback| on an
pbos-webrtc 2016/07/13 12:35:38 zero or two |s
perkj_webrtc 2016/07/14 10:11:27 Done.
194 // arbitrary thread.
195 class VideoSendStreamImpl : public webrtc::BitrateAllocatorObserver,
196 public webrtc::VCMProtectionCallback,
197 public EncodedImageCallback {
198 public:
199 VideoSendStreamImpl(SendStatisticsProxy* stats_proxy,
200 rtc::TaskQueue* worker_queue,
201 CallStats* call_stats,
202 CongestionController* congestion_controller,
203 BitrateAllocator* bitrate_allocator,
204 SendDelayStats* send_delay_stats,
205 VieRemb* remb,
206 ViEEncoder* vie_encoder,
207 RtcEventLog* event_log,
208 const VideoSendStream::Config* config,
209 std::map<uint32_t, RtpState> suspended_ssrcs);
210 ~VideoSendStreamImpl() override;
211
212 // RegisterProcessThread register |module_process_thread| with those objects
213 // that use it. Registration have to happen on the thread where
214 // |module_process_thread| where created (libjingles worker thread).
pbos-webrtc 2016/07/13 12:35:39 s/where/were, and 's
perkj_webrtc 2016/07/14 10:11:27 Done.
215 // TODO(perkj): Replace the use of |module_process_thread| with a TaskQueue,
216 // maybe |worker_queue|.
217 void RegisterProcessThread(ProcessThread* module_process_thread);
218 void DeRegisterProcessThread();
219
220 void SignalNetworkState(NetworkState state);
221 bool DeliverRtcp(const uint8_t* packet, size_t length);
222 void Start();
223 void Stop();
224
225 void ReconfigureVideoEncoder(const VideoEncoderConfig& config);
226 VideoSendStream::RtpStateMap GetRtpStates() const;
227
228 // Implements BitrateAllocatorObserver.
229 uint32_t OnBitrateUpdated(uint32_t bitrate_bps,
230 uint8_t fraction_loss,
231 int64_t rtt) override;
232
233 protected:
234 // Implements webrtc::VCMProtectionCallback.
235 int ProtectionRequest(const FecProtectionParams* delta_params,
pbos-webrtc 2016/07/13 12:35:39 Why protected? Either public or private is fine ri
perkj_webrtc 2016/07/14 10:11:27 Done.
236 const FecProtectionParams* key_params,
237 uint32_t* sent_video_rate_bps,
238 uint32_t* sent_nack_rate_bps,
239 uint32_t* sent_fec_rate_bps) override;
240
241 private:
242 class CheckEncoderActivityTask;
243
244 // Implements EncodedImageCallback. The implementation routes encoded frames
245 // to the |payload_router_| and |config.pre_encode_callback| if set.
246 // Called on an arbitrary encoder callback thread.
247 int32_t Encoded(const EncodedImage& encoded_image,
248 const CodecSpecificInfo* codec_specific_info,
249 const RTPFragmentationHeader* fragmentation) override;
250
251 void ConfigureProtection();
252 void ConfigureSsrcs();
253 void SignalEncoderTimedOut();
254 void SignalEncoderActive();
255
256 SendStatisticsProxy* const stats_proxy_;
257 const VideoSendStream::Config* const config_;
258 std::map<uint32_t, RtpState> suspended_ssrcs_;
259
260 ProcessThread* module_process_thread_;
261 rtc::ThreadChecker module_process_thread_checker_;
262 rtc::TaskQueue* const worker_queue_;
263
264 rtc::CriticalSection encoder_activity_crit_sect_;
265 CheckEncoderActivityTask* check_encoder_activity_task_
266 GUARDED_BY(encoder_activity_crit_sect_);
267 CallStats* const call_stats_;
268 CongestionController* const congestion_controller_;
269 BitrateAllocator* const bitrate_allocator_;
270 VieRemb* const remb_;
271
272 static const bool kEnableFrameRecording = false;
273 static const int kMaxLayers = 3;
274 std::unique_ptr<IvfFileWriter> file_writers_[kMaxLayers];
275
276 int max_padding_bitrate_;
277 int encoder_min_bitrate_bps_;
278 uint32_t encoder_max_bitrate_bps_;
279 uint32_t encoder_target_rate_bps_;
280
281 ViEEncoder* const vie_encoder_;
282 EncoderStateFeedback encoder_feedback_;
283 ProtectionBitrateCalculator protection_bitrate_calculator_;
284
285 const std::unique_ptr<RtcpBandwidthObserver> bandwidth_observer_;
286 // RtpRtcp modules, declared here as they use other members on construction.
287 const std::vector<RtpRtcp*> rtp_rtcp_modules_;
288 PayloadRouter payload_router_;
289 };
290
291 // TODO(tommi): See if there's a more elegant way to create a task that creates
292 // an object on the correct task queue.
293 class VideoSendStream::ConstructionTask : public rtc::QueuedTask {
294 public:
295 ConstructionTask(std::unique_ptr<VideoSendStreamImpl>* send_stream,
296 rtc::Event* done_event,
297 SendStatisticsProxy* stats_proxy,
298 ViEEncoder* vie_encoder,
299 ProcessThread* module_process_thread,
300 CallStats* call_stats,
301 CongestionController* congestion_controller,
302 BitrateAllocator* bitrate_allocator,
303 SendDelayStats* send_delay_stats,
304 VieRemb* remb,
305 RtcEventLog* event_log,
306 const VideoSendStream::Config* config,
307 const std::map<uint32_t, RtpState>& suspended_ssrcs)
308 : send_stream_(send_stream),
309 done_event_(done_event),
310 stats_proxy_(stats_proxy),
311 vie_encoder_(vie_encoder),
312 call_stats_(call_stats),
313 congestion_controller_(congestion_controller),
314 bitrate_allocator_(bitrate_allocator),
315 send_delay_stats_(send_delay_stats),
316 remb_(remb),
317 event_log_(event_log),
318 config_(config),
319 suspended_ssrcs_(suspended_ssrcs) {}
320
321 ~ConstructionTask() override { done_event_->Set(); }
322
323 private:
324 bool Run() override {
325 send_stream_->reset(new VideoSendStreamImpl(
326 stats_proxy_, rtc::TaskQueue::Current(), call_stats_,
327 congestion_controller_, bitrate_allocator_, send_delay_stats_, remb_,
328 vie_encoder_, event_log_, config_, std::move(suspended_ssrcs_)));
329 return true;
330 }
331
332 std::unique_ptr<VideoSendStreamImpl>* send_stream_;
pbos-webrtc 2016/07/13 12:35:38 * const
perkj_webrtc 2016/07/14 10:11:28 Done.
333 rtc::Event* done_event_;
pbos-webrtc 2016/07/13 12:35:39 Event* const
perkj_webrtc 2016/07/14 10:11:27 Done.
334 SendStatisticsProxy* const stats_proxy_;
335 ViEEncoder* const vie_encoder_;
336 CallStats* const call_stats_;
337 CongestionController* const congestion_controller_;
338 BitrateAllocator* const bitrate_allocator_;
339 SendDelayStats* const send_delay_stats_;
340 VieRemb* const remb_;
341 RtcEventLog* const event_log_;
342 const VideoSendStream::Config* config_;
343 std::map<uint32_t, RtpState> suspended_ssrcs_;
344 };
345
346 class VideoSendStream::DestructAndGetRtpStateTask : public rtc::QueuedTask {
347 public:
348 DestructAndGetRtpStateTask(VideoSendStream::RtpStateMap* state_map,
349 std::unique_ptr<VideoSendStreamImpl> send_stream,
350 rtc::Event* done_event)
351 : state_map_(state_map),
352 send_stream_(std::move(send_stream)),
353 done_event_(done_event) {}
354
355 ~DestructAndGetRtpStateTask() override {
356 send_stream_.reset();
pbos-webrtc 2016/07/13 12:35:38 Remove this from destructor, should be done as par
perkj_webrtc 2016/07/14 10:11:27 Done. fyi taskqueues does not guarantee that a tas
357 done_event_->Set();
358 }
359
360 private:
361 bool Run() override {
362 send_stream_->Stop();
363 *state_map_ = send_stream_->GetRtpStates();
364 send_stream_.reset();
365 return true;
366 }
367
368 VideoSendStream::RtpStateMap* state_map_;
369 std::unique_ptr<VideoSendStreamImpl> send_stream_;
370 rtc::Event* done_event_;
371 };
372
373 // CheckEncoderActivityTask is used for tracking when the encoder last produced
374 // and encoded video frame. If the encoder has not produced anything the last
375 // kEncoderTimeOutMs we also want to stop sending padding.
376 class VideoSendStreamImpl::CheckEncoderActivityTask : public rtc::QueuedTask {
377 public:
378 static const int kEncoderTimeOutMs = 2000;
379 explicit CheckEncoderActivityTask(VideoSendStreamImpl* send_stream)
380 : activity_(0), send_stream_(send_stream), timed_out_(false) {
381 encoder_task_checker_.Detach();
382 }
383
384 void Stop() {
385 RTC_CHECK(task_checker_.CalledSequentially());
386 send_stream_ = nullptr;
387 }
388
389 void UpdateEncoderActivity() {
390 RTC_CHECK(encoder_task_checker_.CalledSequentially());
391 rtc::AtomicOps::ReleaseStore(&activity_, 1);
392 }
393
394 private:
395 bool Run() override {
396 RTC_CHECK(task_checker_.CalledSequentially());
397 if (!send_stream_)
398 return true;
399 if (!rtc::AtomicOps::AcquireLoad(&activity_)) {
400 if (!timed_out_) {
401 send_stream_->SignalEncoderTimedOut();
402 }
403 timed_out_ = true;
404 } else if (timed_out_) {
405 send_stream_->SignalEncoderActive();
406 timed_out_ = false;
407 }
408 rtc::AtomicOps::ReleaseStore(&activity_, 0);
409
410 rtc::TaskQueue::Current()->PostDelayedTask(
411 std::unique_ptr<rtc::QueuedTask>(this), kEncoderTimeOutMs);
412 // Return false to prevent this task from being deleted. Ownership has been
413 // transferred to the task queue when PostDelayedTask was called.
414 return false;
415 }
416
417 rtc::SequencedTaskChecker encoder_task_checker_;
418 volatile int activity_;
pbos-webrtc 2016/07/13 12:35:39 This is always called on this encoder_task_checker
perkj_webrtc 2016/07/14 10:11:27 See the updated comment.
419
420 rtc::SequencedTaskChecker task_checker_;
421 VideoSendStreamImpl* send_stream_;
422 bool timed_out_;
423 };
424
425 class ReconfigureVideoEncoderTask : public rtc::QueuedTask {
426 public:
427 ReconfigureVideoEncoderTask(VideoSendStreamImpl* send_stream,
428 VideoEncoderConfig config)
429 : send_stream_(send_stream), config_(std::move(config)) {}
430
431 private:
432 bool Run() override {
433 send_stream_->ReconfigureVideoEncoder(std::move(config_));
434 return true;
435 }
436
437 VideoSendStreamImpl* send_stream_;
438 VideoEncoderConfig config_;
439 };
440
374 VideoSendStream::VideoSendStream( 441 VideoSendStream::VideoSendStream(
375 int num_cpu_cores, 442 int num_cpu_cores,
376 ProcessThread* module_process_thread, 443 ProcessThread* module_process_thread,
444 rtc::TaskQueue* worker_queue,
377 CallStats* call_stats, 445 CallStats* call_stats,
378 CongestionController* congestion_controller, 446 CongestionController* congestion_controller,
379 BitrateAllocator* bitrate_allocator, 447 BitrateAllocator* bitrate_allocator,
380 SendDelayStats* send_delay_stats, 448 SendDelayStats* send_delay_stats,
381 VieRemb* remb, 449 VieRemb* remb,
382 RtcEventLog* event_log, 450 RtcEventLog* event_log,
383 const VideoSendStream::Config& config, 451 VideoSendStream::Config config,
384 const VideoEncoderConfig& encoder_config, 452 VideoEncoderConfig encoder_config,
385 const std::map<uint32_t, RtpState>& suspended_ssrcs) 453 const std::map<uint32_t, RtpState>& suspended_ssrcs)
386 : stats_proxy_(Clock::GetRealTimeClock(), 454 : worker_queue_(worker_queue),
455 thread_sync_event_(false /* manual_reset */, false),
456 stats_proxy_(Clock::GetRealTimeClock(),
387 config, 457 config,
388 encoder_config.content_type), 458 encoder_config.content_type),
459 config_(std::move(config)) {
460 vie_encoder_.reset(
461 new ViEEncoder(num_cpu_cores, &stats_proxy_, config_.encoder_settings,
462 config_.pre_encode_callback, config_.overuse_callback,
463 config_.post_encode_callback));
464
465 worker_queue_->PostTask(std::unique_ptr<rtc::QueuedTask>(new ConstructionTask(
466 &send_stream_, &thread_sync_event_, &stats_proxy_, vie_encoder_.get(),
467 module_process_thread, call_stats, congestion_controller,
468 bitrate_allocator, send_delay_stats, remb, event_log, &config_,
469 suspended_ssrcs)));
470
471 // Wait for ConstructionTask to complete so that |send_stream_| can be used.
472 // |module_process_thread| must be registered and deregistered on the thread
473 // it was created on.
474 thread_sync_event_.Wait(rtc::Event::kForever);
475 send_stream_->RegisterProcessThread(module_process_thread);
476
477 vie_encoder_->RegisterProcessThread(module_process_thread);
478
479 ReconfigureVideoEncoder(std::move(encoder_config));
480 }
481
482 VideoSendStream::~VideoSendStream() {
483 RTC_DCHECK_RUN_ON(&thread_checker_);
484 RTC_DCHECK(!send_stream_);
485 }
486
487 void VideoSendStream::Start() {
488 RTC_DCHECK_RUN_ON(&thread_checker_);
489 LOG(LS_INFO) << "VideoSendStream::Start";
490 VideoSendStreamImpl* send_stream = send_stream_.get();
491 worker_queue_->PostTask([this, send_stream] {
492 send_stream->Start();
493 thread_sync_event_.Set();
494 });
495
496 // It is expected that after VideoSendStream::Start has been called, incoming
497 // frames are not dropped in ViEEncoder. To ensure this, Start has to be
498 // synchronized.
499 thread_sync_event_.Wait(rtc::Event::kForever);
500 }
501
502 void VideoSendStream::Stop() {
503 RTC_DCHECK_RUN_ON(&thread_checker_);
504 LOG(LS_INFO) << "VideoSendStream::Stop";
505 VideoSendStreamImpl* send_stream = send_stream_.get();
506 worker_queue_->PostTask([send_stream] { send_stream->Stop(); });
507 }
508
509 VideoCaptureInput* VideoSendStream::Input() {
510 // Input() will be called on the thread that deliverers video frames from
511 // libjingle.
512 // TODO(perkj): Refactor ViEEncoder to register directly as a VideoSink to the
513 // VideoSource.
514 return vie_encoder_.get();
515 }
516
517 void VideoSendStream::ReconfigureVideoEncoder(VideoEncoderConfig config) {
518 // ReconfigureVideoEncoder will be called on the thread that deliverers video
519 // frames. We must change the encoder settings immediately so that
520 // the codec settings matches the next frame.
521 // TODO(perkj): Move logic for reconfiguration the encoder due to frame size
522 // change from WebRtcVideoChannel2::WebRtcVideoSendStream::OnFrame to
523 // be internally handled by ViEEncoder.
524 vie_encoder_->ConfigureEncoder(config, config_.rtp.max_packet_size);
525
526 worker_queue_->PostTask(std::unique_ptr<rtc::QueuedTask>(
527 new ReconfigureVideoEncoderTask(send_stream_.get(), std::move(config))));
528 }
529
530 VideoSendStream::Stats VideoSendStream::GetStats() {
531 // TODO(perkj, solenberg): Some test cases in EndToEndTest call GetStats from
532 // a network thread. See comment in Call::GetStats().
533 // RTC_DCHECK_RUN_ON(&thread_checker_);
534 return stats_proxy_.GetStats();
535 }
536
537 void VideoSendStream::SignalNetworkState(NetworkState state) {
538 RTC_DCHECK_RUN_ON(&thread_checker_);
539 VideoSendStreamImpl* send_stream = send_stream_.get();
540 worker_queue_->PostTask(
541 [send_stream, state] { send_stream->SignalNetworkState(state); });
542 }
543
544 VideoSendStream::RtpStateMap VideoSendStream::StopPermanentlyAndGetRtpStates() {
545 RTC_DCHECK_RUN_ON(&thread_checker_);
546 vie_encoder_->Stop();
547 vie_encoder_->DeRegisterProcessThread();
548 VideoSendStream::RtpStateMap state_map;
549 send_stream_->DeRegisterProcessThread();
550 worker_queue_->PostTask(
551 std::unique_ptr<rtc::QueuedTask>(new DestructAndGetRtpStateTask(
552 &state_map, std::move(send_stream_), &thread_sync_event_)));
553 thread_sync_event_.Wait(rtc::Event::kForever);
554 return state_map;
555 }
556
557 bool VideoSendStream::DeliverRtcp(const uint8_t* packet, size_t length) {
558 // Called on a network thread.
559 return send_stream_->DeliverRtcp(packet, length);
560 }
561
562 VideoSendStreamImpl::VideoSendStreamImpl(
563 SendStatisticsProxy* stats_proxy,
564 rtc::TaskQueue* worker_queue,
565 CallStats* call_stats,
566 CongestionController* congestion_controller,
567 BitrateAllocator* bitrate_allocator,
568 SendDelayStats* send_delay_stats,
569 VieRemb* remb,
570 ViEEncoder* vie_encoder,
571 RtcEventLog* event_log,
572 const VideoSendStream::Config* config,
573 std::map<uint32_t, RtpState> suspended_ssrcs)
574 : stats_proxy_(stats_proxy),
389 config_(config), 575 config_(config),
390 suspended_ssrcs_(suspended_ssrcs), 576 suspended_ssrcs_(std::move(suspended_ssrcs)),
391 module_process_thread_(module_process_thread), 577 module_process_thread_(nullptr),
578 worker_queue_(worker_queue),
579 check_encoder_activity_task_(nullptr),
392 call_stats_(call_stats), 580 call_stats_(call_stats),
393 congestion_controller_(congestion_controller), 581 congestion_controller_(congestion_controller),
394 bitrate_allocator_(bitrate_allocator), 582 bitrate_allocator_(bitrate_allocator),
395 remb_(remb), 583 remb_(remb),
396 encoder_thread_(EncoderThreadFunction, this, "EncoderThread"), 584 max_padding_bitrate_(0),
397 encoder_wakeup_event_(false, false), 585 encoder_min_bitrate_bps_(0),
398 stop_encoder_thread_(0),
399 encoder_max_bitrate_bps_(0), 586 encoder_max_bitrate_bps_(0),
400 encoder_target_rate_bps_(0), 587 encoder_target_rate_bps_(0),
401 state_(State::kStopped), 588 vie_encoder_(vie_encoder),
402 overuse_detector_(
403 Clock::GetRealTimeClock(),
404 GetCpuOveruseOptions(config.encoder_settings.full_overuse_time),
405 this,
406 config.post_encode_callback,
407 &stats_proxy_),
408 vie_encoder_(num_cpu_cores,
409 module_process_thread_,
410 &stats_proxy_,
411 &overuse_detector_,
412 this),
413 encoder_feedback_(Clock::GetRealTimeClock(), 589 encoder_feedback_(Clock::GetRealTimeClock(),
414 config.rtp.ssrcs, 590 config_->rtp.ssrcs,
415 &vie_encoder_), 591 vie_encoder),
416 protection_bitrate_calculator_(Clock::GetRealTimeClock(), this), 592 protection_bitrate_calculator_(Clock::GetRealTimeClock(), this),
417 video_sender_(vie_encoder_.video_sender()),
418 bandwidth_observer_(congestion_controller_->GetBitrateController() 593 bandwidth_observer_(congestion_controller_->GetBitrateController()
419 ->CreateRtcpBandwidthObserver()), 594 ->CreateRtcpBandwidthObserver()),
420 rtp_rtcp_modules_(CreateRtpRtcpModules( 595 rtp_rtcp_modules_(CreateRtpRtcpModules(
421 config.send_transport, 596 config_->send_transport,
422 &encoder_feedback_, 597 &encoder_feedback_,
423 bandwidth_observer_.get(), 598 bandwidth_observer_.get(),
424 congestion_controller_->GetTransportFeedbackObserver(), 599 congestion_controller_->GetTransportFeedbackObserver(),
425 call_stats_->rtcp_rtt_stats(), 600 call_stats_->rtcp_rtt_stats(),
426 congestion_controller_->pacer(), 601 congestion_controller_->pacer(),
427 congestion_controller_->packet_router(), 602 congestion_controller_->packet_router(),
428 &stats_proxy_, 603 stats_proxy_,
429 send_delay_stats, 604 send_delay_stats,
430 event_log, 605 event_log,
431 config_.rtp.ssrcs.size())), 606 config_->rtp.ssrcs.size())),
432 payload_router_(rtp_rtcp_modules_, config.encoder_settings.payload_type), 607 payload_router_(rtp_rtcp_modules_,
433 input_(&encoder_wakeup_event_, 608 config_->encoder_settings.payload_type) {
434 config_.local_renderer, 609 RTC_DCHECK_RUN_ON(worker_queue_);
435 &stats_proxy_, 610 LOG(LS_INFO) << "VideoSendStreamInternal: " << config_->ToString();
436 &overuse_detector_) { 611 module_process_thread_checker_.DetachFromThread();
437 LOG(LS_INFO) << "VideoSendStream: " << config_.ToString(); 612
438 613 RTC_DCHECK(!config_->rtp.ssrcs.empty());
439 RTC_DCHECK(!config_.rtp.ssrcs.empty());
440 RTC_DCHECK(module_process_thread_);
441 RTC_DCHECK(call_stats_); 614 RTC_DCHECK(call_stats_);
442 RTC_DCHECK(congestion_controller_); 615 RTC_DCHECK(congestion_controller_);
443 RTC_DCHECK(remb_); 616 RTC_DCHECK(remb_);
444 617
445 // RTP/RTCP initialization. 618 // RTP/RTCP initialization.
446 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { 619 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
447 module_process_thread_->RegisterModule(rtp_rtcp);
448 congestion_controller_->packet_router()->AddRtpModule(rtp_rtcp); 620 congestion_controller_->packet_router()->AddRtpModule(rtp_rtcp);
449 } 621 }
450 622
451 for (size_t i = 0; i < config_.rtp.extensions.size(); ++i) { 623 for (size_t i = 0; i < config_->rtp.extensions.size(); ++i) {
452 const std::string& extension = config_.rtp.extensions[i].uri; 624 const std::string& extension = config_->rtp.extensions[i].uri;
453 int id = config_.rtp.extensions[i].id; 625 int id = config_->rtp.extensions[i].id;
454 // One-byte-extension local identifiers are in the range 1-14 inclusive. 626 // One-byte-extension local identifiers are in the range 1-14 inclusive.
455 RTC_DCHECK_GE(id, 1); 627 RTC_DCHECK_GE(id, 1);
456 RTC_DCHECK_LE(id, 14); 628 RTC_DCHECK_LE(id, 14);
457 RTC_DCHECK(RtpExtension::IsSupportedForVideo(extension)); 629 RTC_DCHECK(RtpExtension::IsSupportedForVideo(extension));
458 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { 630 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
459 RTC_CHECK_EQ(0, rtp_rtcp->RegisterSendRtpHeaderExtension( 631 RTC_CHECK_EQ(0, rtp_rtcp->RegisterSendRtpHeaderExtension(
460 StringToRtpExtensionType(extension), id)); 632 StringToRtpExtensionType(extension), id));
461 } 633 }
462 } 634 }
463 635
464 remb_->AddRembSender(rtp_rtcp_modules_[0]); 636 remb_->AddRembSender(rtp_rtcp_modules_[0]);
465 rtp_rtcp_modules_[0]->SetREMBStatus(true); 637 rtp_rtcp_modules_[0]->SetREMBStatus(true);
466 638
467 ConfigureProtection(); 639 ConfigureProtection();
468 ConfigureSsrcs(); 640 ConfigureSsrcs();
469 641
470 // TODO(pbos): Should we set CNAME on all RTP modules? 642 // TODO(pbos): Should we set CNAME on all RTP modules?
471 rtp_rtcp_modules_.front()->SetCNAME(config_.rtp.c_name.c_str()); 643 rtp_rtcp_modules_.front()->SetCNAME(config_->rtp.c_name.c_str());
472 // 28 to match packet overhead in ModuleRtpRtcpImpl. 644 // 28 to match packet overhead in ModuleRtpRtcpImpl.
473 static const size_t kRtpPacketSizeOverhead = 28; 645 static const size_t kRtpPacketSizeOverhead = 28;
474 RTC_DCHECK_LE(config_.rtp.max_packet_size, 0xFFFFu + kRtpPacketSizeOverhead); 646 RTC_DCHECK_LE(config_->rtp.max_packet_size, 0xFFFFu + kRtpPacketSizeOverhead);
475 const uint16_t mtu = static_cast<uint16_t>(config_.rtp.max_packet_size + 647 const uint16_t mtu = static_cast<uint16_t>(config_->rtp.max_packet_size +
476 kRtpPacketSizeOverhead); 648 kRtpPacketSizeOverhead);
477 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { 649 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
478 rtp_rtcp->RegisterRtcpStatisticsCallback(&stats_proxy_); 650 rtp_rtcp->RegisterRtcpStatisticsCallback(stats_proxy_);
479 rtp_rtcp->RegisterSendChannelRtpStatisticsCallback(&stats_proxy_); 651 rtp_rtcp->RegisterSendChannelRtpStatisticsCallback(stats_proxy_);
480 rtp_rtcp->SetMaxTransferUnit(mtu); 652 rtp_rtcp->SetMaxTransferUnit(mtu);
481 rtp_rtcp->RegisterVideoSendPayload( 653 rtp_rtcp->RegisterVideoSendPayload(
482 config_.encoder_settings.payload_type, 654 config_->encoder_settings.payload_type,
483 config_.encoder_settings.payload_name.c_str()); 655 config_->encoder_settings.payload_name.c_str());
484 } 656 }
485 657
486 RTC_DCHECK(config.encoder_settings.encoder); 658 RTC_DCHECK(config_->encoder_settings.encoder);
487 RTC_DCHECK_GE(config.encoder_settings.payload_type, 0); 659 RTC_DCHECK_GE(config_->encoder_settings.payload_type, 0);
488 RTC_DCHECK_LE(config.encoder_settings.payload_type, 127); 660 RTC_DCHECK_LE(config_->encoder_settings.payload_type, 127);
489 ReconfigureVideoEncoder(encoder_config);
490 661
491 module_process_thread_->RegisterModule(&overuse_detector_); 662 vie_encoder_->SetStartBitrate(bitrate_allocator_->GetStartBitrate(this));
492 663 vie_encoder_->SetSink(this);
493 encoder_thread_checker_.DetachFromThread();
494 encoder_thread_.Start();
495 encoder_thread_.SetPriority(rtc::kHighPriority);
496 } 664 }
497 665
498 VideoSendStream::~VideoSendStream() { 666 void VideoSendStreamImpl::RegisterProcessThread(
499 LOG(LS_INFO) << "~VideoSendStream: " << config_.ToString(); 667 ProcessThread* module_process_thread) {
668 RTC_DCHECK_RUN_ON(&module_process_thread_checker_);
669 RTC_DCHECK(!module_process_thread_);
670 module_process_thread_ = module_process_thread;
500 671
501 Stop(); 672 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_)
673 module_process_thread_->RegisterModule(rtp_rtcp);
674 }
502 675
503 // Stop the encoder thread permanently. 676 void VideoSendStreamImpl::DeRegisterProcessThread() {
504 rtc::AtomicOps::ReleaseStore(&stop_encoder_thread_, 1); 677 RTC_DCHECK_RUN_ON(&module_process_thread_checker_);
505 encoder_wakeup_event_.Set(); 678 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_)
506 encoder_thread_.Stop(); 679 module_process_thread_->DeRegisterModule(rtp_rtcp);
680 }
507 681
508 // This needs to happen after stopping the encoder thread, 682 VideoSendStreamImpl::~VideoSendStreamImpl() {
509 // since the encoder thread calls AddObserver. 683 RTC_DCHECK_RUN_ON(worker_queue_);
510 bitrate_allocator_->RemoveObserver(this); 684 RTC_DCHECK(!payload_router_.active())
511 685 << "VideoSendStreamImpl::Stop not called";
512 module_process_thread_->DeRegisterModule(&overuse_detector_); 686 LOG(LS_INFO) << "~VideoSendStreamInternal: " << config_->ToString();
513 687
514 rtp_rtcp_modules_[0]->SetREMBStatus(false); 688 rtp_rtcp_modules_[0]->SetREMBStatus(false);
515 remb_->RemoveRembSender(rtp_rtcp_modules_[0]); 689 remb_->RemoveRembSender(rtp_rtcp_modules_[0]);
516 690
517 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { 691 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
518 congestion_controller_->packet_router()->RemoveRtpModule(rtp_rtcp); 692 congestion_controller_->packet_router()->RemoveRtpModule(rtp_rtcp);
519 module_process_thread_->DeRegisterModule(rtp_rtcp);
520 delete rtp_rtcp; 693 delete rtp_rtcp;
521 } 694 }
522 } 695 }
523 696
524 bool VideoSendStream::DeliverRtcp(const uint8_t* packet, size_t length) { 697 bool VideoSendStreamImpl::DeliverRtcp(const uint8_t* packet, size_t length) {
698 // Runs on a network thread.
699 RTC_DCHECK(!worker_queue_->IsCurrent());
525 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) 700 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_)
526 rtp_rtcp->IncomingRtcpPacket(packet, length); 701 rtp_rtcp->IncomingRtcpPacket(packet, length);
527 return true; 702 return true;
528 } 703 }
529 704
530 void VideoSendStream::Start() { 705 void VideoSendStreamImpl::Start() {
706 RTC_DCHECK_RUN_ON(worker_queue_);
531 LOG(LS_INFO) << "VideoSendStream::Start"; 707 LOG(LS_INFO) << "VideoSendStream::Start";
532 if (payload_router_.active()) 708 if (payload_router_.active())
533 return; 709 return;
534 TRACE_EVENT_INSTANT0("webrtc", "VideoSendStream::Start"); 710 TRACE_EVENT_INSTANT0("webrtc", "VideoSendStream::Start");
535 payload_router_.set_active(true); 711 payload_router_.set_active(true);
712
713 bitrate_allocator_->AddObserver(
714 this, encoder_min_bitrate_bps_, encoder_max_bitrate_bps_,
715 max_padding_bitrate_, !config_->suspend_below_min_bitrate);
716
717 // Start monitoring encoder activity.
536 { 718 {
537 rtc::CritScope lock(&encoder_settings_crit_); 719 rtc::CritScope lock(&encoder_activity_crit_sect_);
538 pending_state_change_ = rtc::Optional<State>(State::kStarted); 720 RTC_DCHECK(!check_encoder_activity_task_);
721 check_encoder_activity_task_ = new CheckEncoderActivityTask(this);
722 worker_queue_->PostDelayedTask(
723 std::unique_ptr<rtc::QueuedTask>(check_encoder_activity_task_),
724 CheckEncoderActivityTask::kEncoderTimeOutMs);
539 } 725 }
540 encoder_wakeup_event_.Set(); 726
727 vie_encoder_->SendKeyFrame();
541 } 728 }
542 729
543 void VideoSendStream::Stop() { 730 void VideoSendStreamImpl::Stop() {
731 RTC_DCHECK_RUN_ON(worker_queue_);
544 LOG(LS_INFO) << "VideoSendStream::Stop"; 732 LOG(LS_INFO) << "VideoSendStream::Stop";
545 if (!payload_router_.active()) 733 if (!payload_router_.active())
546 return; 734 return;
547 TRACE_EVENT_INSTANT0("webrtc", "VideoSendStream::Stop"); 735 TRACE_EVENT_INSTANT0("webrtc", "VideoSendStream::Stop");
548 payload_router_.set_active(false); 736 payload_router_.set_active(false);
737 bitrate_allocator_->RemoveObserver(this);
549 { 738 {
550 rtc::CritScope lock(&encoder_settings_crit_); 739 rtc::CritScope lock(&encoder_activity_crit_sect_);
551 pending_state_change_ = rtc::Optional<State>(State::kStopped); 740 check_encoder_activity_task_->Stop();
741 check_encoder_activity_task_ = nullptr;
552 } 742 }
553 encoder_wakeup_event_.Set(); 743 vie_encoder_->OnBitrateUpdated(0, 0, 0);
744 stats_proxy_->OnSetEncoderTargetRate(0);
554 } 745 }
555 746
556 VideoCaptureInput* VideoSendStream::Input() { 747 void VideoSendStreamImpl::SignalEncoderTimedOut() {
557 return &input_; 748 RTC_DCHECK_RUN_ON(worker_queue_);
749 // If the encoder has not produced anything the last kEncoderTimeOutMs and it
750 // is supposed to, deregister as BitrateAllocatorObserver. This can happen
751 // if a camera stops producing frames.
752 if (encoder_target_rate_bps_ > 0) {
753 LOG_F(LS_INFO) << "Encoder timed out.";
pbos-webrtc 2016/07/13 12:35:38 s/LOG_F/LOG
perkj_webrtc 2016/07/14 10:11:27 ok, agree, but you and stefan disagrees.
754 bitrate_allocator_->RemoveObserver(this);
755 }
558 } 756 }
559 757
560 bool VideoSendStream::EncoderThreadFunction(void* obj) { 758 void VideoSendStreamImpl::SignalEncoderActive() {
561 static_cast<VideoSendStream*>(obj)->EncoderProcess(); 759 RTC_DCHECK_RUN_ON(worker_queue_);
562 // We're done, return false to abort. 760 LOG_F(LS_INFO) << "Encoder is active.";
pbos-webrtc 2016/07/13 12:35:39 s/LOG_F/LOG
perkj_webrtc 2016/07/14 10:11:27 Done.
563 return false; 761 bitrate_allocator_->AddObserver(
762 this, encoder_min_bitrate_bps_, encoder_max_bitrate_bps_,
763 max_padding_bitrate_, !config_->suspend_below_min_bitrate);
564 } 764 }
565 765
566 void VideoSendStream::EncoderProcess() { 766 void VideoSendStreamImpl::ReconfigureVideoEncoder(
pbos-webrtc 2016/07/13 12:35:39 This name is confusing because it doesn't actually
perkj_webrtc 2016/07/14 10:11:27 SignalEncoderConfigurationChanged
567 RTC_CHECK_EQ(0, vie_encoder_.RegisterExternalEncoder( 767 const VideoEncoderConfig& config) {
568 config_.encoder_settings.encoder, 768 RTC_DCHECK_GE(config_->rtp.ssrcs.size(), config.streams.size());
569 config_.encoder_settings.payload_type, 769 TRACE_EVENT0("webrtc", "VideoSendStream::(Re)configureVideoEncoder");
570 config_.encoder_settings.internal_source)); 770 LOG(LS_INFO) << "(Re)configureVideoEncoder: " << config.ToString();
571 RTC_DCHECK_RUN_ON(&encoder_thread_checker_); 771 RTC_DCHECK_GE(config_->rtp.ssrcs.size(), config.streams.size());
572 while (true) { 772 RTC_DCHECK_RUN_ON(worker_queue_);
573 // Wake up every kEncodeCheckForActivityPeriodMs to check if the encoder is
574 // active. If not, deregister as BitrateAllocatorObserver.
575 const int kEncodeCheckForActivityPeriodMs = 1000;
576 encoder_wakeup_event_.Wait(kEncodeCheckForActivityPeriodMs);
577 if (rtc::AtomicOps::AcquireLoad(&stop_encoder_thread_))
578 break;
579 bool change_settings = false;
580 rtc::Optional<State> pending_state_change;
581 {
582 rtc::CritScope lock(&encoder_settings_crit_);
583 if (pending_encoder_settings_) {
584 std::swap(current_encoder_settings_, pending_encoder_settings_);
585 pending_encoder_settings_.reset();
586 change_settings = true;
587 } else if (pending_state_change_) {
588 swap(pending_state_change, pending_state_change_);
589 }
590 }
591 if (change_settings) {
592 current_encoder_settings_->video_codec.startBitrate = std::max(
593 bitrate_allocator_->GetStartBitrate(this) / 1000,
594 static_cast<int>(current_encoder_settings_->video_codec.minBitrate));
595 773
596 if (state_ == State::kStarted) { 774 const int kEncoderMinBitrateBps = 30000;
597 bitrate_allocator_->AddObserver( 775 encoder_min_bitrate_bps_ =
598 this, current_encoder_settings_->video_codec.minBitrate * 1000, 776 std::max(config.streams[0].min_bitrate_bps, kEncoderMinBitrateBps);
599 current_encoder_settings_->video_codec.maxBitrate * 1000, 777 encoder_max_bitrate_bps_ = 0;
600 CalulcateMaxPadBitrateBps(current_encoder_settings_->config, 778 for (const auto& stream : config.streams)
601 config_.suspend_below_min_bitrate), 779 encoder_max_bitrate_bps_ += stream.max_bitrate_bps;
602 !config_.suspend_below_min_bitrate); 780 max_padding_bitrate_ =
603 } 781 CalculateMaxPadBitrateBps(config, config_->suspend_below_min_bitrate);
604 782
605 payload_router_.SetSendStreams(current_encoder_settings_->config.streams); 783 payload_router_.SetSendStreams(config.streams);
606 vie_encoder_.SetEncoder(current_encoder_settings_->video_codec,
607 payload_router_.MaxPayloadLength());
608 784
609 // Clear stats for disabled layers. 785 // Clear stats for disabled layers.
610 for (size_t i = current_encoder_settings_->config.streams.size(); 786 for (size_t i = config.streams.size(); i < config_->rtp.ssrcs.size(); ++i) {
611 i < config_.rtp.ssrcs.size(); ++i) { 787 stats_proxy_->OnInactiveSsrc(config_->rtp.ssrcs[i]);
612 stats_proxy_.OnInactiveSsrc(config_.rtp.ssrcs[i]); 788 }
613 }
614 789
615 size_t number_of_temporal_layers = 790 size_t number_of_temporal_layers =
616 current_encoder_settings_->config.streams.back() 791 config.streams.back().temporal_layer_thresholds_bps.size() + 1;
617 .temporal_layer_thresholds_bps.size() + 792 protection_bitrate_calculator_.SetEncodingData(
618 1; 793 config.streams[0].width, config.streams[0].height,
619 protection_bitrate_calculator_.SetEncodingData( 794 number_of_temporal_layers, config_->rtp.max_packet_size);
620 current_encoder_settings_->video_codec.width,
621 current_encoder_settings_->video_codec.height,
622 number_of_temporal_layers, payload_router_.MaxPayloadLength());
623 795
624 // We might've gotten new settings while configuring the encoder settings, 796 if (payload_router_.active()) {
625 // restart from the top to see if that's the case before trying to encode 797 // The send stream is started already. Update the allocator with new bitrate
626 // a frame (which might correspond to the last frame size). 798 // limits.
627 encoder_wakeup_event_.Set(); 799 bitrate_allocator_->AddObserver(
628 continue; 800 this, encoder_min_bitrate_bps_, encoder_max_bitrate_bps_,
629 } 801 max_padding_bitrate_, !config_->suspend_below_min_bitrate);
630
631 if (pending_state_change) {
632 if (*pending_state_change == State::kStarted &&
633 state_ == State::kStopped) {
634 bitrate_allocator_->AddObserver(
635 this, current_encoder_settings_->video_codec.minBitrate * 1000,
636 current_encoder_settings_->video_codec.maxBitrate * 1000,
637 CalulcateMaxPadBitrateBps(current_encoder_settings_->config,
638 config_.suspend_below_min_bitrate),
639 !config_.suspend_below_min_bitrate);
640 vie_encoder_.SendKeyFrame();
641 state_ = State::kStarted;
642 LOG_F(LS_INFO) << "Encoder started.";
643 } else if (*pending_state_change == State::kStopped) {
644 bitrate_allocator_->RemoveObserver(this);
645 vie_encoder_.OnBitrateUpdated(0, 0, 0);
646 stats_proxy_.OnSetEncoderTargetRate(0);
647 state_ = State::kStopped;
648 LOG_F(LS_INFO) << "Encoder stopped.";
649 }
650 encoder_wakeup_event_.Set();
651 continue;
652 }
653
654 // Check if the encoder has produced anything the last kEncoderTimeOutMs.
655 // If not, deregister as BitrateAllocatorObserver.
656 if (state_ == State::kStarted &&
657 vie_encoder_.time_of_last_frame_activity_ms() <
658 rtc::TimeMillis() - kEncoderTimeOutMs) {
659 // The encoder has timed out.
660 LOG_F(LS_INFO) << "Encoder timed out.";
661 bitrate_allocator_->RemoveObserver(this);
662 state_ = State::kEncoderTimedOut;
663 }
664 if (state_ == State::kEncoderTimedOut &&
665 vie_encoder_.time_of_last_frame_activity_ms() >
666 rtc::TimeMillis() - kEncoderTimeOutMs) {
667 LOG_F(LS_INFO) << "Encoder is active.";
668 bitrate_allocator_->AddObserver(
669 this, current_encoder_settings_->video_codec.minBitrate * 1000,
670 current_encoder_settings_->video_codec.maxBitrate * 1000,
671 CalulcateMaxPadBitrateBps(current_encoder_settings_->config,
672 config_.suspend_below_min_bitrate),
673 !config_.suspend_below_min_bitrate);
674 state_ = State::kStarted;
675 }
676
677 VideoFrame frame;
678 if (input_.GetVideoFrame(&frame)) {
679 // TODO(perkj): |pre_encode_callback| is only used by tests. Tests should
680 // register as a sink to the VideoSource instead.
681 if (config_.pre_encode_callback) {
682 config_.pre_encode_callback->OnFrame(frame);
683 }
684 vie_encoder_.EncodeVideoFrame(frame);
685 }
686 } 802 }
687 vie_encoder_.DeRegisterExternalEncoder(config_.encoder_settings.payload_type);
688 } 803 }
689 804
690 void VideoSendStream::ReconfigureVideoEncoder( 805 int32_t VideoSendStreamImpl::Encoded(
691 const VideoEncoderConfig& config) { 806 const EncodedImage& encoded_image,
692 TRACE_EVENT0("webrtc", "VideoSendStream::(Re)configureVideoEncoder"); 807 const CodecSpecificInfo* codec_specific_info,
693 LOG(LS_INFO) << "(Re)configureVideoEncoder: " << config.ToString(); 808 const RTPFragmentationHeader* fragmentation) {
694 RTC_DCHECK_GE(config_.rtp.ssrcs.size(), config.streams.size()); 809 if (config_->post_encode_callback) {
695 VideoCodec video_codec = VideoEncoderConfigToVideoCodec( 810 config_->post_encode_callback->EncodedFrameCallback(
696 config, config_.encoder_settings.payload_name,
697 config_.encoder_settings.payload_type);
698 {
699 rtc::CritScope lock(&encoder_settings_crit_);
700 encoder_max_bitrate_bps_ = video_codec.maxBitrate * 1000;
701 pending_encoder_settings_.reset(new EncoderSettings({video_codec, config}));
702 }
703 encoder_wakeup_event_.Set();
704 }
705
706 VideoSendStream::Stats VideoSendStream::GetStats() {
707 return stats_proxy_.GetStats();
708 }
709
710 void VideoSendStream::OveruseDetected() {
711 if (config_.overuse_callback)
712 config_.overuse_callback->OnLoadUpdate(LoadObserver::kOveruse);
713 }
714
715 void VideoSendStream::NormalUsage() {
716 if (config_.overuse_callback)
717 config_.overuse_callback->OnLoadUpdate(LoadObserver::kUnderuse);
718 }
719
720 int32_t VideoSendStream::Encoded(const EncodedImage& encoded_image,
721 const CodecSpecificInfo* codec_specific_info,
722 const RTPFragmentationHeader* fragmentation) {
723 if (config_.post_encode_callback) {
724 config_.post_encode_callback->EncodedFrameCallback(
725 EncodedFrame(encoded_image._buffer, encoded_image._length, 811 EncodedFrame(encoded_image._buffer, encoded_image._length,
726 encoded_image._frameType)); 812 encoded_image._frameType));
727 } 813 }
814 {
815 rtc::CritScope lock(&encoder_activity_crit_sect_);
816 if (check_encoder_activity_task_)
817 check_encoder_activity_task_->UpdateEncoderActivity();
818 }
728 819
729 protection_bitrate_calculator_.UpdateWithEncodedData(encoded_image); 820 protection_bitrate_calculator_.UpdateWithEncodedData(encoded_image);
730 int32_t return_value = payload_router_.Encoded( 821 int32_t return_value = payload_router_.Encoded(
731 encoded_image, codec_specific_info, fragmentation); 822 encoded_image, codec_specific_info, fragmentation);
732 823
733 if (kEnableFrameRecording) { 824 if (kEnableFrameRecording) {
734 int layer = codec_specific_info->codecType == kVideoCodecVP8 825 int layer = codec_specific_info->codecType == kVideoCodecVP8
735 ? codec_specific_info->codecSpecific.VP8.simulcastIdx 826 ? codec_specific_info->codecSpecific.VP8.simulcastIdx
736 : 0; 827 : 0;
737 IvfFileWriter* file_writer; 828 IvfFileWriter* file_writer;
738 { 829 {
739 if (file_writers_[layer] == nullptr) { 830 if (file_writers_[layer] == nullptr) {
740 std::ostringstream oss; 831 std::ostringstream oss;
741 oss << "send_bitstream_ssrc"; 832 oss << "send_bitstream_ssrc";
742 for (uint32_t ssrc : config_.rtp.ssrcs) 833 for (uint32_t ssrc : config_->rtp.ssrcs)
743 oss << "_" << ssrc; 834 oss << "_" << ssrc;
744 oss << "_layer" << layer << ".ivf"; 835 oss << "_layer" << layer << ".ivf";
745 file_writers_[layer] = 836 file_writers_[layer] =
746 IvfFileWriter::Open(oss.str(), codec_specific_info->codecType); 837 IvfFileWriter::Open(oss.str(), codec_specific_info->codecType);
747 } 838 }
748 file_writer = file_writers_[layer].get(); 839 file_writer = file_writers_[layer].get();
749 } 840 }
750 if (file_writer) { 841 if (file_writer) {
751 bool ok = file_writer->WriteFrame(encoded_image); 842 bool ok = file_writer->WriteFrame(encoded_image);
752 RTC_DCHECK(ok); 843 RTC_DCHECK(ok);
753 } 844 }
754 } 845 }
755 846
756 return return_value; 847 return return_value;
757 } 848 }
758 849
759 void VideoSendStream::ConfigureProtection() { 850 void VideoSendStreamImpl::ConfigureProtection() {
851 RTC_DCHECK_RUN_ON(worker_queue_);
760 // Enable NACK, FEC or both. 852 // Enable NACK, FEC or both.
761 const bool enable_protection_nack = config_.rtp.nack.rtp_history_ms > 0; 853 const bool enable_protection_nack = config_->rtp.nack.rtp_history_ms > 0;
762 bool enable_protection_fec = config_.rtp.fec.ulpfec_payload_type != -1; 854 bool enable_protection_fec = config_->rtp.fec.ulpfec_payload_type != -1;
763 // Payload types without picture ID cannot determine that a stream is complete 855 // Payload types without picture ID cannot determine that a stream is complete
764 // without retransmitting FEC, so using FEC + NACK for H.264 (for instance) is 856 // without retransmitting FEC, so using FEC + NACK for H.264 (for instance) is
765 // a waste of bandwidth since FEC packets still have to be transmitted. Note 857 // a waste of bandwidth since FEC packets still have to be transmitted. Note
766 // that this is not the case with FLEXFEC. 858 // that this is not the case with FLEXFEC.
767 if (enable_protection_nack && 859 if (enable_protection_nack &&
768 !PayloadTypeSupportsSkippingFecPackets( 860 !PayloadTypeSupportsSkippingFecPackets(
769 config_.encoder_settings.payload_name)) { 861 config_->encoder_settings.payload_name)) {
770 LOG(LS_WARNING) << "Transmitting payload type without picture ID using" 862 LOG(LS_WARNING) << "Transmitting payload type without picture ID using"
771 "NACK+FEC is a waste of bandwidth since FEC packets " 863 "NACK+FEC is a waste of bandwidth since FEC packets "
772 "also have to be retransmitted. Disabling FEC."; 864 "also have to be retransmitted. Disabling FEC.";
773 enable_protection_fec = false; 865 enable_protection_fec = false;
774 } 866 }
775 867
776 // Set to valid uint8_ts to be castable later without signed overflows. 868 // Set to valid uint8_ts to be castable later without signed overflows.
777 uint8_t payload_type_red = 0; 869 uint8_t payload_type_red = 0;
778 uint8_t payload_type_fec = 0; 870 uint8_t payload_type_fec = 0;
779 871
780 // TODO(changbin): Should set RTX for RED mapping in RTP sender in future. 872 // TODO(changbin): Should set RTX for RED mapping in RTP sender in future.
781 // Validate payload types. If either RED or FEC payload types are set then 873 // Validate payload types. If either RED or FEC payload types are set then
782 // both should be. If FEC is enabled then they both have to be set. 874 // both should be. If FEC is enabled then they both have to be set.
783 if (config_.rtp.fec.red_payload_type != -1) { 875 if (config_->rtp.fec.red_payload_type != -1) {
784 RTC_DCHECK_GE(config_.rtp.fec.red_payload_type, 0); 876 RTC_DCHECK_GE(config_->rtp.fec.red_payload_type, 0);
785 RTC_DCHECK_LE(config_.rtp.fec.red_payload_type, 127); 877 RTC_DCHECK_LE(config_->rtp.fec.red_payload_type, 127);
786 // TODO(holmer): We should only enable red if ulpfec is also enabled, but 878 // TODO(holmer): We should only enable red if ulpfec is also enabled, but
787 // but due to an incompatibility issue with previous versions the receiver 879 // but due to an incompatibility issue with previous versions the receiver
788 // assumes rtx packets are containing red if it has been configured to 880 // assumes rtx packets are containing red if it has been configured to
789 // receive red. Remove this in a few versions once the incompatibility 881 // receive red. Remove this in a few versions once the incompatibility
790 // issue is resolved (M53 timeframe). 882 // issue is resolved (M53 timeframe).
791 payload_type_red = static_cast<uint8_t>(config_.rtp.fec.red_payload_type); 883 payload_type_red = static_cast<uint8_t>(config_->rtp.fec.red_payload_type);
792 } 884 }
793 if (config_.rtp.fec.ulpfec_payload_type != -1) { 885 if (config_->rtp.fec.ulpfec_payload_type != -1) {
794 RTC_DCHECK_GE(config_.rtp.fec.ulpfec_payload_type, 0); 886 RTC_DCHECK_GE(config_->rtp.fec.ulpfec_payload_type, 0);
795 RTC_DCHECK_LE(config_.rtp.fec.ulpfec_payload_type, 127); 887 RTC_DCHECK_LE(config_->rtp.fec.ulpfec_payload_type, 127);
796 payload_type_fec = 888 payload_type_fec =
797 static_cast<uint8_t>(config_.rtp.fec.ulpfec_payload_type); 889 static_cast<uint8_t>(config_->rtp.fec.ulpfec_payload_type);
798 } 890 }
799 891
800 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { 892 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
801 // Set NACK. 893 // Set NACK.
802 rtp_rtcp->SetStorePacketsStatus( 894 rtp_rtcp->SetStorePacketsStatus(
803 enable_protection_nack || congestion_controller_->pacer(), 895 enable_protection_nack || congestion_controller_->pacer(),
804 kMinSendSidePacketHistorySize); 896 kMinSendSidePacketHistorySize);
805 // Set FEC. 897 // Set FEC.
806 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { 898 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
807 rtp_rtcp->SetGenericFECStatus(enable_protection_fec, payload_type_red, 899 rtp_rtcp->SetGenericFECStatus(enable_protection_fec, payload_type_red,
808 payload_type_fec); 900 payload_type_fec);
809 } 901 }
810 } 902 }
811 903
812 protection_bitrate_calculator_.SetProtectionMethod(enable_protection_fec, 904 protection_bitrate_calculator_.SetProtectionMethod(enable_protection_fec,
813 enable_protection_nack); 905 enable_protection_nack);
814 } 906 }
815 907
816 void VideoSendStream::ConfigureSsrcs() { 908 void VideoSendStreamImpl::ConfigureSsrcs() {
909 RTC_DCHECK_RUN_ON(worker_queue_);
817 // Configure regular SSRCs. 910 // Configure regular SSRCs.
818 for (size_t i = 0; i < config_.rtp.ssrcs.size(); ++i) { 911 for (size_t i = 0; i < config_->rtp.ssrcs.size(); ++i) {
819 uint32_t ssrc = config_.rtp.ssrcs[i]; 912 uint32_t ssrc = config_->rtp.ssrcs[i];
820 RtpRtcp* const rtp_rtcp = rtp_rtcp_modules_[i]; 913 RtpRtcp* const rtp_rtcp = rtp_rtcp_modules_[i];
821 rtp_rtcp->SetSSRC(ssrc); 914 rtp_rtcp->SetSSRC(ssrc);
822 915
823 // Restore RTP state if previous existed. 916 // Restore RTP state if previous existed.
824 RtpStateMap::iterator it = suspended_ssrcs_.find(ssrc); 917 VideoSendStream::RtpStateMap::iterator it = suspended_ssrcs_.find(ssrc);
825 if (it != suspended_ssrcs_.end()) 918 if (it != suspended_ssrcs_.end())
826 rtp_rtcp->SetRtpState(it->second); 919 rtp_rtcp->SetRtpState(it->second);
827 } 920 }
828 921
829 // Set up RTX if available. 922 // Set up RTX if available.
830 if (config_.rtp.rtx.ssrcs.empty()) 923 if (config_->rtp.rtx.ssrcs.empty())
831 return; 924 return;
832 925
833 // Configure RTX SSRCs. 926 // Configure RTX SSRCs.
834 RTC_DCHECK_EQ(config_.rtp.rtx.ssrcs.size(), config_.rtp.ssrcs.size()); 927 RTC_DCHECK_EQ(config_->rtp.rtx.ssrcs.size(), config_->rtp.ssrcs.size());
835 for (size_t i = 0; i < config_.rtp.rtx.ssrcs.size(); ++i) { 928 for (size_t i = 0; i < config_->rtp.rtx.ssrcs.size(); ++i) {
836 uint32_t ssrc = config_.rtp.rtx.ssrcs[i]; 929 uint32_t ssrc = config_->rtp.rtx.ssrcs[i];
837 RtpRtcp* const rtp_rtcp = rtp_rtcp_modules_[i]; 930 RtpRtcp* const rtp_rtcp = rtp_rtcp_modules_[i];
838 rtp_rtcp->SetRtxSsrc(ssrc); 931 rtp_rtcp->SetRtxSsrc(ssrc);
839 RtpStateMap::iterator it = suspended_ssrcs_.find(ssrc); 932 VideoSendStream::RtpStateMap::iterator it = suspended_ssrcs_.find(ssrc);
840 if (it != suspended_ssrcs_.end()) 933 if (it != suspended_ssrcs_.end())
841 rtp_rtcp->SetRtxState(it->second); 934 rtp_rtcp->SetRtxState(it->second);
842 } 935 }
843 936
844 // Configure RTX payload types. 937 // Configure RTX payload types.
845 RTC_DCHECK_GE(config_.rtp.rtx.payload_type, 0); 938 RTC_DCHECK_GE(config_->rtp.rtx.payload_type, 0);
846 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { 939 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
847 rtp_rtcp->SetRtxSendPayloadType(config_.rtp.rtx.payload_type, 940 rtp_rtcp->SetRtxSendPayloadType(config_->rtp.rtx.payload_type,
848 config_.encoder_settings.payload_type); 941 config_->encoder_settings.payload_type);
849 rtp_rtcp->SetRtxSendStatus(kRtxRetransmitted | kRtxRedundantPayloads); 942 rtp_rtcp->SetRtxSendStatus(kRtxRetransmitted | kRtxRedundantPayloads);
850 } 943 }
851 if (config_.rtp.fec.red_payload_type != -1 && 944 if (config_->rtp.fec.red_payload_type != -1 &&
852 config_.rtp.fec.red_rtx_payload_type != -1) { 945 config_->rtp.fec.red_rtx_payload_type != -1) {
853 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { 946 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
854 rtp_rtcp->SetRtxSendPayloadType(config_.rtp.fec.red_rtx_payload_type, 947 rtp_rtcp->SetRtxSendPayloadType(config_->rtp.fec.red_rtx_payload_type,
855 config_.rtp.fec.red_payload_type); 948 config_->rtp.fec.red_payload_type);
856 } 949 }
857 } 950 }
858 } 951 }
859 952
860 std::map<uint32_t, RtpState> VideoSendStream::GetRtpStates() const { 953 std::map<uint32_t, RtpState> VideoSendStreamImpl::GetRtpStates() const {
954 RTC_DCHECK_RUN_ON(worker_queue_);
861 std::map<uint32_t, RtpState> rtp_states; 955 std::map<uint32_t, RtpState> rtp_states;
862 for (size_t i = 0; i < config_.rtp.ssrcs.size(); ++i) { 956 for (size_t i = 0; i < config_->rtp.ssrcs.size(); ++i) {
863 uint32_t ssrc = config_.rtp.ssrcs[i]; 957 uint32_t ssrc = config_->rtp.ssrcs[i];
864 RTC_DCHECK_EQ(ssrc, rtp_rtcp_modules_[i]->SSRC()); 958 RTC_DCHECK_EQ(ssrc, rtp_rtcp_modules_[i]->SSRC());
865 rtp_states[ssrc] = rtp_rtcp_modules_[i]->GetRtpState(); 959 rtp_states[ssrc] = rtp_rtcp_modules_[i]->GetRtpState();
866 } 960 }
867 961
868 for (size_t i = 0; i < config_.rtp.rtx.ssrcs.size(); ++i) { 962 for (size_t i = 0; i < config_->rtp.rtx.ssrcs.size(); ++i) {
869 uint32_t ssrc = config_.rtp.rtx.ssrcs[i]; 963 uint32_t ssrc = config_->rtp.rtx.ssrcs[i];
870 rtp_states[ssrc] = rtp_rtcp_modules_[i]->GetRtxState(); 964 rtp_states[ssrc] = rtp_rtcp_modules_[i]->GetRtxState();
871 } 965 }
872 966
873 return rtp_states; 967 return rtp_states;
874 } 968 }
875 969
876 void VideoSendStream::SignalNetworkState(NetworkState state) { 970 void VideoSendStreamImpl::SignalNetworkState(NetworkState state) {
971 RTC_DCHECK_RUN_ON(worker_queue_);
877 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { 972 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
878 rtp_rtcp->SetRTCPStatus(state == kNetworkUp ? config_.rtp.rtcp_mode 973 rtp_rtcp->SetRTCPStatus(state == kNetworkUp ? config_->rtp.rtcp_mode
879 : RtcpMode::kOff); 974 : RtcpMode::kOff);
880 } 975 }
881 } 976 }
882 977
883 uint32_t VideoSendStream::OnBitrateUpdated(uint32_t bitrate_bps, 978 uint32_t VideoSendStreamImpl::OnBitrateUpdated(uint32_t bitrate_bps,
884 uint8_t fraction_loss, 979 uint8_t fraction_loss,
885 int64_t rtt) { 980 int64_t rtt) {
981 RTC_DCHECK_RUN_ON(worker_queue_);
982 RTC_DCHECK(payload_router_.active())
983 << "VideoSendStream::Start has not been called.";
886 payload_router_.SetTargetSendBitrate(bitrate_bps); 984 payload_router_.SetTargetSendBitrate(bitrate_bps);
887 // Get the encoder target rate. It is the estimated network rate - 985 // Get the encoder target rate. It is the estimated network rate -
888 // protection overhead. 986 // protection overhead.
889 uint32_t encoder_target_rate_bps = 987 encoder_target_rate_bps_ = protection_bitrate_calculator_.SetTargetRates(
890 protection_bitrate_calculator_.SetTargetRates( 988 bitrate_bps, stats_proxy_->GetSendFrameRate(), fraction_loss, rtt);
891 bitrate_bps, stats_proxy_.GetSendFrameRate(), fraction_loss, rtt); 989 uint32_t protection_bitrate = bitrate_bps - encoder_target_rate_bps_;
892 990
893 uint32_t protection_bitrate = bitrate_bps - encoder_target_rate_bps; 991 encoder_target_rate_bps_ =
894 { 992 std::min(encoder_max_bitrate_bps_, encoder_target_rate_bps_);
895 // Limit the target bitrate to the configured max bitrate. 993 vie_encoder_->OnBitrateUpdated(encoder_target_rate_bps_, fraction_loss, rtt);
896 rtc::CritScope lock(&encoder_settings_crit_); 994 stats_proxy_->OnSetEncoderTargetRate(encoder_target_rate_bps_);
897 encoder_target_rate_bps =
898 std::min(encoder_max_bitrate_bps_, encoder_target_rate_bps);
899 if ((encoder_target_rate_bps_ == 0 && encoder_target_rate_bps > 0) ||
900 (encoder_target_rate_bps_ > 0 && encoder_target_rate_bps == 0)) {
901 LOG(LS_INFO)
902 << "OnBitrateUpdated: Encoder state changed, target bitrate "
903 << encoder_target_rate_bps << " bps.";
904 }
905 encoder_target_rate_bps_ = encoder_target_rate_bps;
906 }
907 vie_encoder_.OnBitrateUpdated(encoder_target_rate_bps, fraction_loss, rtt);
908 stats_proxy_.OnSetEncoderTargetRate(encoder_target_rate_bps);
909
910 return protection_bitrate; 995 return protection_bitrate;
911 } 996 }
912 997
913 int VideoSendStream::ProtectionRequest(const FecProtectionParams* delta_params, 998 int VideoSendStreamImpl::ProtectionRequest(
914 const FecProtectionParams* key_params, 999 const FecProtectionParams* delta_params,
915 uint32_t* sent_video_rate_bps, 1000 const FecProtectionParams* key_params,
916 uint32_t* sent_nack_rate_bps, 1001 uint32_t* sent_video_rate_bps,
917 uint32_t* sent_fec_rate_bps) { 1002 uint32_t* sent_nack_rate_bps,
1003 uint32_t* sent_fec_rate_bps) {
1004 RTC_DCHECK_RUN_ON(worker_queue_);
918 *sent_video_rate_bps = 0; 1005 *sent_video_rate_bps = 0;
919 *sent_nack_rate_bps = 0; 1006 *sent_nack_rate_bps = 0;
920 *sent_fec_rate_bps = 0; 1007 *sent_fec_rate_bps = 0;
921 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { 1008 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
922 uint32_t not_used = 0; 1009 uint32_t not_used = 0;
923 uint32_t module_video_rate = 0; 1010 uint32_t module_video_rate = 0;
924 uint32_t module_fec_rate = 0; 1011 uint32_t module_fec_rate = 0;
925 uint32_t module_nack_rate = 0; 1012 uint32_t module_nack_rate = 0;
926 rtp_rtcp->SetFecParameters(delta_params, key_params); 1013 rtp_rtcp->SetFecParameters(delta_params, key_params);
927 rtp_rtcp->BitrateSent(&not_used, &module_video_rate, &module_fec_rate, 1014 rtp_rtcp->BitrateSent(&not_used, &module_video_rate, &module_fec_rate,
928 &module_nack_rate); 1015 &module_nack_rate);
929 *sent_video_rate_bps += module_video_rate; 1016 *sent_video_rate_bps += module_video_rate;
930 *sent_nack_rate_bps += module_nack_rate; 1017 *sent_nack_rate_bps += module_nack_rate;
931 *sent_fec_rate_bps += module_fec_rate; 1018 *sent_fec_rate_bps += module_fec_rate;
932 } 1019 }
933 return 0; 1020 return 0;
934 } 1021 }
935 1022
936 } // namespace internal 1023 } // namespace internal
937 } // namespace webrtc 1024 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698