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

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

Issue 1864313003: Move Ownership of RtpModules to VideoSendStream. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Rebased Created 4 years, 8 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 10
(...skipping 16 matching lines...) Expand all
27 #include "webrtc/video/call_stats.h" 27 #include "webrtc/video/call_stats.h"
28 #include "webrtc/video/video_capture_input.h" 28 #include "webrtc/video/video_capture_input.h"
29 #include "webrtc/video/vie_remb.h" 29 #include "webrtc/video/vie_remb.h"
30 #include "webrtc/video_send_stream.h" 30 #include "webrtc/video_send_stream.h"
31 31
32 namespace webrtc { 32 namespace webrtc {
33 33
34 class RtcpIntraFrameObserver; 34 class RtcpIntraFrameObserver;
35 class TransportFeedbackObserver; 35 class TransportFeedbackObserver;
36 36
37 static const int kMinSendSidePacketHistorySize = 600;
38
39 namespace {
40
41 std::vector<RtpRtcp*> CreateRtpRtcpModules(
42 Transport* outgoing_transport,
43 RtcpIntraFrameObserver* intra_frame_callback,
44 RtcpBandwidthObserver* bandwidth_callback,
45 TransportFeedbackObserver* transport_feedback_callback,
46 RtcpRttStats* rtt_stats,
47 RtpPacketSender* paced_sender,
48 TransportSequenceNumberAllocator* transport_sequence_number_allocator,
49 SendStatisticsProxy* stats_proxy,
50 size_t num_modules) {
51 RTC_DCHECK_GT(num_modules, 0u);
52 RtpRtcp::Configuration configuration;
53 ReceiveStatistics* null_receive_statistics = configuration.receive_statistics;
54 configuration.audio = false;
55 configuration.receiver_only = false;
56 configuration.receive_statistics = null_receive_statistics;
57 configuration.outgoing_transport = outgoing_transport;
58 configuration.intra_frame_callback = intra_frame_callback;
59 configuration.rtt_stats = rtt_stats;
60 configuration.rtcp_packet_type_counter_observer = stats_proxy;
61 configuration.paced_sender = paced_sender;
62 configuration.transport_sequence_number_allocator =
63 transport_sequence_number_allocator;
64 configuration.send_bitrate_observer = stats_proxy;
65 configuration.send_frame_count_observer = stats_proxy;
66 configuration.send_side_delay_observer = stats_proxy;
67 configuration.bandwidth_callback = bandwidth_callback;
68 configuration.transport_feedback_callback = transport_feedback_callback;
69
70 std::vector<RtpRtcp*> modules;
71 for (size_t i = 0; i < num_modules; ++i) {
72 RtpRtcp* rtp_rtcp = RtpRtcp::CreateRtpRtcp(configuration);
73 rtp_rtcp->SetSendingStatus(false);
74 rtp_rtcp->SetSendingMediaStatus(false);
75 rtp_rtcp->SetRTCPStatus(RtcpMode::kCompound);
76 modules.push_back(rtp_rtcp);
77 }
78 return modules;
79 }
80
81 } // namespace
82
37 std::string 83 std::string
38 VideoSendStream::Config::EncoderSettings::ToString() const { 84 VideoSendStream::Config::EncoderSettings::ToString() const {
39 std::stringstream ss; 85 std::stringstream ss;
40 ss << "{payload_name: " << payload_name; 86 ss << "{payload_name: " << payload_name;
41 ss << ", payload_type: " << payload_type; 87 ss << ", payload_type: " << payload_type;
42 ss << ", encoder: " << (encoder ? "(VideoEncoder)" : "nullptr"); 88 ss << ", encoder: " << (encoder ? "(VideoEncoder)" : "nullptr");
43 ss << '}'; 89 ss << '}';
44 return ss.str(); 90 return ss.str();
45 } 91 }
46 92
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 remb_(remb), 222 remb_(remb),
177 encoder_thread_(EncoderThreadFunction, this, "EncoderThread"), 223 encoder_thread_(EncoderThreadFunction, this, "EncoderThread"),
178 encoder_wakeup_event_(false, false), 224 encoder_wakeup_event_(false, false),
179 stop_encoder_thread_(0), 225 stop_encoder_thread_(0),
180 overuse_detector_( 226 overuse_detector_(
181 Clock::GetRealTimeClock(), 227 Clock::GetRealTimeClock(),
182 GetCpuOveruseOptions(config.encoder_settings.full_overuse_time), 228 GetCpuOveruseOptions(config.encoder_settings.full_overuse_time),
183 this, 229 this,
184 config.post_encode_callback, 230 config.post_encode_callback,
185 &stats_proxy_), 231 &stats_proxy_),
186 vie_channel_(config.send_transport,
187 module_process_thread_,
188 &payload_router_,
189 nullptr,
190 &encoder_feedback_,
191 congestion_controller_->GetBitrateController()
192 ->CreateRtcpBandwidthObserver(),
193 congestion_controller_->GetTransportFeedbackObserver(),
194 nullptr,
195 call_stats_->rtcp_rtt_stats(),
196 congestion_controller_->pacer(),
197 congestion_controller_->packet_router(),
198 config_.rtp.ssrcs.size(),
199 true),
200 vie_receiver_(vie_channel_.vie_receiver()),
201 vie_encoder_(num_cpu_cores, 232 vie_encoder_(num_cpu_cores,
202 config_.rtp.ssrcs, 233 config_.rtp.ssrcs,
203 module_process_thread_, 234 module_process_thread_,
204 &stats_proxy_, 235 &stats_proxy_,
205 config.pre_encode_callback, 236 config.pre_encode_callback,
206 &overuse_detector_, 237 &overuse_detector_,
207 congestion_controller_->pacer(), 238 congestion_controller_->pacer(),
208 &payload_router_), 239 &payload_router_),
209 vcm_(vie_encoder_.vcm()), 240 vcm_(vie_encoder_.vcm()),
210 rtp_rtcp_modules_(vie_channel_.rtp_rtcp()), 241 bandwidth_observer_(congestion_controller_->GetBitrateController()
242 ->CreateRtcpBandwidthObserver()),
243 rtp_rtcp_modules_(CreateRtpRtcpModules(
244 config.send_transport,
245 &encoder_feedback_,
246 bandwidth_observer_.get(),
247 congestion_controller_->GetTransportFeedbackObserver(),
248 call_stats_->rtcp_rtt_stats(),
249 congestion_controller_->pacer(),
250 congestion_controller_->packet_router(),
251 &stats_proxy_,
252 config_.rtp.ssrcs.size())),
253 payload_router_(rtp_rtcp_modules_),
211 input_(&encoder_wakeup_event_, 254 input_(&encoder_wakeup_event_,
212 config_.local_renderer, 255 config_.local_renderer,
213 &stats_proxy_, 256 &stats_proxy_,
214 &overuse_detector_) { 257 &overuse_detector_) {
215 LOG(LS_INFO) << "VideoSendStream: " << config_.ToString(); 258 LOG(LS_INFO) << "VideoSendStream: " << config_.ToString();
216 259
217 RTC_DCHECK(!config_.rtp.ssrcs.empty()); 260 RTC_DCHECK(!config_.rtp.ssrcs.empty());
218 RTC_DCHECK(module_process_thread_); 261 RTC_DCHECK(module_process_thread_);
219 RTC_DCHECK(call_stats_); 262 RTC_DCHECK(call_stats_);
220 RTC_DCHECK(congestion_controller_); 263 RTC_DCHECK(congestion_controller_);
221 RTC_DCHECK(remb_); 264 RTC_DCHECK(remb_);
222 265
223 payload_router_.Init(rtp_rtcp_modules_);
224 RTC_CHECK(vie_encoder_.Init()); 266 RTC_CHECK(vie_encoder_.Init());
225 encoder_feedback_.Init(config_.rtp.ssrcs, &vie_encoder_); 267 encoder_feedback_.Init(config_.rtp.ssrcs, &vie_encoder_);
226 RTC_CHECK(vie_channel_.Init() == 0);
227 268
228 vcm_->RegisterProtectionCallback(vie_channel_.vcm_protection_callback()); 269 // RTP/RTCP initialization.
270 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
271 module_process_thread_->RegisterModule(rtp_rtcp);
272 congestion_controller_->packet_router()->AddRtpModule(rtp_rtcp);
273 }
229 274
230 call_stats_->RegisterStatsObserver(vie_channel_.GetStatsObserver()); 275 vcm_->RegisterProtectionCallback(this);
276
277 // NOW! This only seems to be used receive side from looking at the code??
stefan-webrtc 2016/04/12 07:59:10 AFAICT you are right.
perkj_webrtc 2016/04/13 11:43:49 Done.
278 // call_stats_->RegisterStatsObserver(vie_channel_.GetStatsObserver());
231 279
232 for (size_t i = 0; i < config_.rtp.extensions.size(); ++i) { 280 for (size_t i = 0; i < config_.rtp.extensions.size(); ++i) {
233 const std::string& extension = config_.rtp.extensions[i].name; 281 const std::string& extension = config_.rtp.extensions[i].name;
234 int id = config_.rtp.extensions[i].id; 282 int id = config_.rtp.extensions[i].id;
235 // One-byte-extension local identifiers are in the range 1-14 inclusive. 283 // One-byte-extension local identifiers are in the range 1-14 inclusive.
236 RTC_DCHECK_GE(id, 1); 284 RTC_DCHECK_GE(id, 1);
237 RTC_DCHECK_LE(id, 14); 285 RTC_DCHECK_LE(id, 14);
238 RTC_DCHECK(RtpExtension::IsSupportedForVideo(extension)); 286 RTC_DCHECK(RtpExtension::IsSupportedForVideo(extension));
239 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { 287 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
240 RTC_CHECK_EQ(0, rtp_rtcp->RegisterSendRtpHeaderExtension( 288 RTC_CHECK_EQ(0, rtp_rtcp->RegisterSendRtpHeaderExtension(
241 StringToRtpExtensionType(extension), id)); 289 StringToRtpExtensionType(extension), id));
242 } 290 }
243 } 291 }
244 292
245 remb_->AddRembSender(rtp_rtcp_modules_[0]); 293 remb_->AddRembSender(rtp_rtcp_modules_[0]);
246 rtp_rtcp_modules_[0]->SetREMBStatus(true); 294 rtp_rtcp_modules_[0]->SetREMBStatus(true);
247 295
248 // Enable NACK, FEC or both. 296 ConfigureProtection();
249 const bool enable_protection_nack = config_.rtp.nack.rtp_history_ms > 0;
250 bool enable_protection_fec = config_.rtp.fec.red_payload_type != -1;
251 // Payload types without picture ID cannot determine that a stream is complete
252 // without retransmitting FEC, so using FEC + NACK for H.264 (for instance) is
253 // a waste of bandwidth since FEC packets still have to be transmitted. Note
254 // that this is not the case with FLEXFEC.
255 if (enable_protection_nack &&
256 !PayloadTypeSupportsSkippingFecPackets(
257 config_.encoder_settings.payload_name)) {
258 LOG(LS_WARNING) << "Transmitting payload type without picture ID using"
259 "NACK+FEC is a waste of bandwidth since FEC packets "
260 "also have to be retransmitted. Disabling FEC.";
261 enable_protection_fec = false;
262 }
263 // TODO(changbin): Should set RTX for RED mapping in RTP sender in future.
264 vie_channel_.SetProtectionMode(enable_protection_nack, enable_protection_fec,
265 config_.rtp.fec.red_payload_type,
266 config_.rtp.fec.ulpfec_payload_type);
267 vie_encoder_.SetProtectionMethod(enable_protection_nack,
268 enable_protection_fec);
269
270 ConfigureSsrcs(); 297 ConfigureSsrcs();
271 298
272 // TODO(pbos): Should we set CNAME on all RTP modules? 299 // TODO(pbos): Should we set CNAME on all RTP modules?
273 rtp_rtcp_modules_.front()->SetCNAME(config_.rtp.c_name.c_str()); 300 rtp_rtcp_modules_.front()->SetCNAME(config_.rtp.c_name.c_str());
274 // 28 to match packet overhead in ModuleRtpRtcpImpl. 301 // 28 to match packet overhead in ModuleRtpRtcpImpl.
275 static const size_t kRtpPacketSizeOverhead = 28; 302 static const size_t kRtpPacketSizeOverhead = 28;
276 RTC_DCHECK_LE(config_.rtp.max_packet_size, 0xFFFFu + kRtpPacketSizeOverhead); 303 RTC_DCHECK_LE(config_.rtp.max_packet_size, 0xFFFFu + kRtpPacketSizeOverhead);
277 const uint16_t mtu = static_cast<uint16_t>(config_.rtp.max_packet_size + 304 const uint16_t mtu = static_cast<uint16_t>(config_.rtp.max_packet_size +
278 kRtpPacketSizeOverhead); 305 kRtpPacketSizeOverhead);
279 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { 306 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
280 rtp_rtcp->RegisterRtcpStatisticsCallback(&stats_proxy_); 307 rtp_rtcp->RegisterRtcpStatisticsCallback(&stats_proxy_);
281 rtp_rtcp->RegisterSendChannelRtpStatisticsCallback(&stats_proxy_); 308 rtp_rtcp->RegisterSendChannelRtpStatisticsCallback(&stats_proxy_);
282 rtp_rtcp->SetMaxTransferUnit(mtu); 309 rtp_rtcp->SetMaxTransferUnit(mtu);
283 rtp_rtcp->RegisterVideoSendPayload( 310 rtp_rtcp->RegisterVideoSendPayload(
284 config_.encoder_settings.payload_type, 311 config_.encoder_settings.payload_type,
285 config_.encoder_settings.payload_name.c_str()); 312 config_.encoder_settings.payload_name.c_str());
286 } 313 }
287 314
288 RTC_DCHECK(config.encoder_settings.encoder); 315 RTC_DCHECK(config.encoder_settings.encoder);
289 RTC_DCHECK_GE(config.encoder_settings.payload_type, 0); 316 RTC_DCHECK_GE(config.encoder_settings.payload_type, 0);
290 RTC_DCHECK_LE(config.encoder_settings.payload_type, 127); 317 RTC_DCHECK_LE(config.encoder_settings.payload_type, 127);
291 RTC_CHECK_EQ(0, vie_encoder_.RegisterExternalEncoder( 318 RTC_CHECK_EQ(0, vie_encoder_.RegisterExternalEncoder(
292 config.encoder_settings.encoder, 319 config.encoder_settings.encoder,
293 config.encoder_settings.payload_type, 320 config.encoder_settings.payload_type,
294 config.encoder_settings.internal_source)); 321 config.encoder_settings.internal_source));
295 322
296 ReconfigureVideoEncoder(encoder_config); 323 ReconfigureVideoEncoder(encoder_config);
297 324
298 vie_channel_.RegisterSendSideDelayObserver(&stats_proxy_);
299
300 if (config_.post_encode_callback) 325 if (config_.post_encode_callback)
301 vie_encoder_.RegisterPostEncodeImageCallback(&encoded_frame_proxy_); 326 vie_encoder_.RegisterPostEncodeImageCallback(&encoded_frame_proxy_);
302 327
303 if (config_.suspend_below_min_bitrate) { 328 if (config_.suspend_below_min_bitrate) {
304 vcm_->SuspendBelowMinBitrate(); 329 vcm_->SuspendBelowMinBitrate();
305 bitrate_allocator_->EnforceMinBitrate(false); 330 bitrate_allocator_->EnforceMinBitrate(false);
306 } 331 }
307 332
308 vie_channel_.RegisterRtcpPacketTypeCounterObserver(&stats_proxy_);
309 vie_channel_.RegisterSendBitrateObserver(&stats_proxy_);
310 vie_channel_.RegisterSendFrameCountObserver(&stats_proxy_);
311
312 module_process_thread_->RegisterModule(&overuse_detector_); 333 module_process_thread_->RegisterModule(&overuse_detector_);
313 334
314 encoder_thread_.Start(); 335 encoder_thread_.Start();
315 encoder_thread_.SetPriority(rtc::kHighPriority); 336 encoder_thread_.SetPriority(rtc::kHighPriority);
316 } 337 }
317 338
318 VideoSendStream::~VideoSendStream() { 339 VideoSendStream::~VideoSendStream() {
319 LOG(LS_INFO) << "~VideoSendStream: " << config_.ToString(); 340 LOG(LS_INFO) << "~VideoSendStream: " << config_.ToString();
320 341
321 Stop(); 342 Stop();
322 343
323 // Stop the encoder thread permanently. 344 // Stop the encoder thread permanently.
324 rtc::AtomicOps::ReleaseStore(&stop_encoder_thread_, 1); 345 rtc::AtomicOps::ReleaseStore(&stop_encoder_thread_, 1);
325 encoder_wakeup_event_.Set(); 346 encoder_wakeup_event_.Set();
326 encoder_thread_.Stop(); 347 encoder_thread_.Stop();
327 348
328 // This needs to happen after stopping the encoder thread, 349 // This needs to happen after stopping the encoder thread,
329 // since the encoder thread calls AddObserver. 350 // since the encoder thread calls AddObserver.
330 bitrate_allocator_->RemoveObserver(this); 351 bitrate_allocator_->RemoveObserver(this);
331 352
332 module_process_thread_->DeRegisterModule(&overuse_detector_); 353 module_process_thread_->DeRegisterModule(&overuse_detector_);
333 vie_channel_.RegisterSendFrameCountObserver(nullptr);
334 vie_channel_.RegisterSendBitrateObserver(nullptr);
335 vie_channel_.RegisterRtcpPacketTypeCounterObserver(nullptr);
336 354
337 vie_encoder_.DeRegisterExternalEncoder(config_.encoder_settings.payload_type); 355 vie_encoder_.DeRegisterExternalEncoder(config_.encoder_settings.payload_type);
338 356
339 call_stats_->DeregisterStatsObserver(vie_channel_.GetStatsObserver()); 357 // call_stats_->DeregisterStatsObserver(vie_channel_.GetStatsObserver());
340 rtp_rtcp_modules_[0]->SetREMBStatus(false); 358 rtp_rtcp_modules_[0]->SetREMBStatus(false);
341 remb_->RemoveRembSender(rtp_rtcp_modules_[0]); 359 remb_->RemoveRembSender(rtp_rtcp_modules_[0]);
342 360
343 // ViEChannel outlives ViEEncoder so remove encoder from feedback before 361 // What is this???????
stefan-webrtc 2016/04/12 07:59:10 Looks incorrect to me, and should be removed since
perkj_webrtc 2016/04/13 11:43:49 Done.
344 // destruction. 362 // congestion_controller_->GetRemoteBitrateEstimator(false)->RemoveStream(
345 encoder_feedback_.TearDown(); 363 // vie_receiver_->GetRemoteSsrc());
346 364
347 congestion_controller_->GetRemoteBitrateEstimator(false)->RemoveStream( 365 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
348 vie_receiver_->GetRemoteSsrc()); 366 congestion_controller_->packet_router()->RemoveRtpModule(rtp_rtcp);
367 module_process_thread_->DeRegisterModule(rtp_rtcp);
368 delete rtp_rtcp;
369 }
349 } 370 }
350 371
351 VideoCaptureInput* VideoSendStream::Input() { 372 VideoCaptureInput* VideoSendStream::Input() {
352 return &input_; 373 return &input_;
353 } 374 }
354 375
355 void VideoSendStream::Start() { 376 void VideoSendStream::Start() {
356 if (payload_router_.active()) 377 if (payload_router_.active())
357 return; 378 return;
358 vie_encoder_.Pause(); 379 vie_encoder_.Pause();
359 payload_router_.set_active(true); 380 payload_router_.set_active(true);
360 // Was not already started, trigger a keyframe. 381 // Was not already started, trigger a keyframe.
361 vie_encoder_.SendKeyFrame(); 382 vie_encoder_.SendKeyFrame();
362 vie_encoder_.Restart(); 383 vie_encoder_.Restart();
363 vie_receiver_->StartReceive();
364 } 384 }
365 385
366 void VideoSendStream::Stop() { 386 void VideoSendStream::Stop() {
367 if (!payload_router_.active()) 387 if (!payload_router_.active())
368 return; 388 return;
369 // TODO(pbos): Make sure the encoder stops here. 389 // TODO(pbos): Make sure the encoder stops here.
370 payload_router_.set_active(false); 390 payload_router_.set_active(false);
371 vie_receiver_->StopReceive();
372 } 391 }
373 392
374 bool VideoSendStream::EncoderThreadFunction(void* obj) { 393 bool VideoSendStream::EncoderThreadFunction(void* obj) {
375 static_cast<VideoSendStream*>(obj)->EncoderProcess(); 394 static_cast<VideoSendStream*>(obj)->EncoderProcess();
376 // We're done, return false to abort. 395 // We're done, return false to abort.
377 return false; 396 return false;
378 } 397 }
379 398
380 void VideoSendStream::EncoderProcess() { 399 void VideoSendStream::EncoderProcess() {
381 while (true) { 400 while (true) {
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
526 video_codec.maxFramerate = streams[0].max_framerate; 545 video_codec.maxFramerate = streams[0].max_framerate;
527 546
528 video_codec.startBitrate = 547 video_codec.startBitrate =
529 bitrate_allocator_->AddObserver(this, 548 bitrate_allocator_->AddObserver(this,
530 video_codec.minBitrate * 1000, 549 video_codec.minBitrate * 1000,
531 video_codec.maxBitrate * 1000) / 1000; 550 video_codec.maxBitrate * 1000) / 1000;
532 vie_encoder_.SetEncoder(video_codec, config.min_transmit_bitrate_bps); 551 vie_encoder_.SetEncoder(video_codec, config.min_transmit_bitrate_bps);
533 } 552 }
534 553
535 bool VideoSendStream::DeliverRtcp(const uint8_t* packet, size_t length) { 554 bool VideoSendStream::DeliverRtcp(const uint8_t* packet, size_t length) {
536 return vie_receiver_->DeliverRtcp(packet, length); 555 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_)
556 rtp_rtcp->IncomingRtcpPacket(packet, length);
557 return true;
537 } 558 }
538 559
539 VideoSendStream::Stats VideoSendStream::GetStats() { 560 VideoSendStream::Stats VideoSendStream::GetStats() {
540 return stats_proxy_.GetStats(); 561 return stats_proxy_.GetStats();
541 } 562 }
542 563
543 void VideoSendStream::OveruseDetected() { 564 void VideoSendStream::OveruseDetected() {
544 if (config_.overuse_callback) 565 if (config_.overuse_callback)
545 config_.overuse_callback->OnLoadUpdate(LoadObserver::kOveruse); 566 config_.overuse_callback->OnLoadUpdate(LoadObserver::kOveruse);
546 } 567 }
547 568
548 void VideoSendStream::NormalUsage() { 569 void VideoSendStream::NormalUsage() {
549 if (config_.overuse_callback) 570 if (config_.overuse_callback)
550 config_.overuse_callback->OnLoadUpdate(LoadObserver::kUnderuse); 571 config_.overuse_callback->OnLoadUpdate(LoadObserver::kUnderuse);
551 } 572 }
552 573
574 void VideoSendStream::ConfigureProtection() {
575 // Enable NACK, FEC or both.
576 const bool enable_protection_nack = config_.rtp.nack.rtp_history_ms > 0;
577 bool enable_protection_fec = config_.rtp.fec.red_payload_type != -1;
578 // Payload types without picture ID cannot determine that a stream is complete
579 // without retransmitting FEC, so using FEC + NACK for H.264 (for instance) is
580 // a waste of bandwidth since FEC packets still have to be transmitted. Note
581 // that this is not the case with FLEXFEC.
582 if (enable_protection_nack &&
583 !PayloadTypeSupportsSkippingFecPackets(
584 config_.encoder_settings.payload_name)) {
585 LOG(LS_WARNING) << "Transmitting payload type without picture ID using"
586 "NACK+FEC is a waste of bandwidth since FEC packets "
587 "also have to be retransmitted. Disabling FEC.";
588 enable_protection_fec = false;
589 }
590
591 // Set to valid uint8_ts to be castable later without signed overflows.
592 uint8_t payload_type_red = 0;
593 uint8_t payload_type_fec = 0;
594 // TODO(changbin): Should set RTX for RED mapping in RTP sender in future.
595 // Validate payload types. If either RED or FEC payload types are set then
596 // both should be. If FEC is enabled then they both have to be set.
597 if (enable_protection_fec || config_.rtp.fec.red_payload_type != -1 ||
598 config_.rtp.fec.ulpfec_payload_type != -1) {
599 RTC_DCHECK_GE(config_.rtp.fec.red_payload_type, 0);
600 RTC_DCHECK_GE(config_.rtp.fec.ulpfec_payload_type, 0);
601 RTC_DCHECK_LE(config_.rtp.fec.red_payload_type, 127);
602 RTC_DCHECK_LE(config_.rtp.fec.ulpfec_payload_type, 127);
603 payload_type_red = static_cast<uint8_t>(config_.rtp.fec.red_payload_type);
604 payload_type_fec =
605 static_cast<uint8_t>(config_.rtp.fec.ulpfec_payload_type);
606 } else {
607 // Payload types unset.
608 RTC_DCHECK_EQ(config_.rtp.fec.red_payload_type, -1);
609 RTC_DCHECK_EQ(config_.rtp.fec.ulpfec_payload_type, -1);
610 }
611
612 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
613 // Set NACK.
614 rtp_rtcp->SetStorePacketsStatus(
615 enable_protection_nack || congestion_controller_->pacer(),
616 kMinSendSidePacketHistorySize);
617 // Set FEC.
618 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
619 rtp_rtcp->SetGenericFECStatus(enable_protection_fec, payload_type_red,
620 payload_type_fec);
621 }
622 }
623
624 vie_encoder_.SetProtectionMethod(enable_protection_nack,
625 enable_protection_fec);
626 }
627
553 void VideoSendStream::ConfigureSsrcs() { 628 void VideoSendStream::ConfigureSsrcs() {
554 // Configure regular SSRCs. 629 // Configure regular SSRCs.
555 for (size_t i = 0; i < config_.rtp.ssrcs.size(); ++i) { 630 for (size_t i = 0; i < config_.rtp.ssrcs.size(); ++i) {
556 uint32_t ssrc = config_.rtp.ssrcs[i]; 631 uint32_t ssrc = config_.rtp.ssrcs[i];
557 RtpRtcp* const rtp_rtcp = rtp_rtcp_modules_[i]; 632 RtpRtcp* const rtp_rtcp = rtp_rtcp_modules_[i];
558 rtp_rtcp->SetSSRC(ssrc); 633 rtp_rtcp->SetSSRC(ssrc);
559 634
560 // Restore RTP state if previous existed. 635 // Restore RTP state if previous existed.
561 RtpStateMap::iterator it = suspended_ssrcs_.find(ssrc); 636 RtpStateMap::iterator it = suspended_ssrcs_.find(ssrc);
562 if (it != suspended_ssrcs_.end()) 637 if (it != suspended_ssrcs_.end())
563 rtp_rtcp->SetRtpStateForSsrc(ssrc, it->second); 638 rtp_rtcp->SetRtpState(it->second);
564 } 639 }
565 640
566 // Set up RTX if available. 641 // Set up RTX if available.
567 if (config_.rtp.rtx.ssrcs.empty()) 642 if (config_.rtp.rtx.ssrcs.empty())
568 return; 643 return;
569 644
570 // Configure RTX SSRCs. 645 // Configure RTX SSRCs.
571 RTC_DCHECK_EQ(config_.rtp.rtx.ssrcs.size(), config_.rtp.ssrcs.size()); 646 RTC_DCHECK_EQ(config_.rtp.rtx.ssrcs.size(), config_.rtp.ssrcs.size());
572 for (size_t i = 0; i < config_.rtp.rtx.ssrcs.size(); ++i) { 647 for (size_t i = 0; i < config_.rtp.rtx.ssrcs.size(); ++i) {
573 uint32_t ssrc = config_.rtp.rtx.ssrcs[i]; 648 uint32_t ssrc = config_.rtp.rtx.ssrcs[i];
574 RtpRtcp* const rtp_rtcp = rtp_rtcp_modules_[i]; 649 RtpRtcp* const rtp_rtcp = rtp_rtcp_modules_[i];
575 rtp_rtcp->SetRtxSsrc(ssrc); 650 rtp_rtcp->SetRtxSsrc(ssrc);
576 RtpStateMap::iterator it = suspended_ssrcs_.find(ssrc); 651 RtpStateMap::iterator it = suspended_ssrcs_.find(ssrc);
577 if (it != suspended_ssrcs_.end()) 652 if (it != suspended_ssrcs_.end())
578 rtp_rtcp->SetRtpStateForSsrc(ssrc, it->second); 653 rtp_rtcp->SetRtxState(it->second);
579 } 654 }
580 655
581 // Configure RTX payload types. 656 // Configure RTX payload types.
582 RTC_DCHECK_GE(config_.rtp.rtx.payload_type, 0); 657 RTC_DCHECK_GE(config_.rtp.rtx.payload_type, 0);
583 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { 658 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
584 rtp_rtcp->SetRtxSendPayloadType(config_.rtp.rtx.payload_type, 659 rtp_rtcp->SetRtxSendPayloadType(config_.rtp.rtx.payload_type,
585 config_.encoder_settings.payload_type); 660 config_.encoder_settings.payload_type);
586 rtp_rtcp->SetRtxSendStatus(kRtxRetransmitted | kRtxRedundantPayloads); 661 rtp_rtcp->SetRtxSendStatus(kRtxRetransmitted | kRtxRedundantPayloads);
587 } 662 }
588 if (config_.rtp.fec.red_payload_type != -1 && 663 if (config_.rtp.fec.red_payload_type != -1 &&
589 config_.rtp.fec.red_rtx_payload_type != -1) { 664 config_.rtp.fec.red_rtx_payload_type != -1) {
590 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { 665 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
591 rtp_rtcp->SetRtxSendPayloadType(config_.rtp.fec.red_rtx_payload_type, 666 rtp_rtcp->SetRtxSendPayloadType(config_.rtp.fec.red_rtx_payload_type,
592 config_.rtp.fec.red_payload_type); 667 config_.rtp.fec.red_payload_type);
593 } 668 }
594 } 669 }
595 } 670 }
596 671
597 std::map<uint32_t, RtpState> VideoSendStream::GetRtpStates() const { 672 std::map<uint32_t, RtpState> VideoSendStream::GetRtpStates() const {
598 std::map<uint32_t, RtpState> rtp_states; 673 std::map<uint32_t, RtpState> rtp_states;
599 for (size_t i = 0; i < config_.rtp.ssrcs.size(); ++i) { 674 for (size_t i = 0; i < config_.rtp.ssrcs.size(); ++i) {
600 uint32_t ssrc = config_.rtp.ssrcs[i]; 675 uint32_t ssrc = config_.rtp.ssrcs[i];
601 rtp_states[ssrc] = vie_channel_.GetRtpStateForSsrc(ssrc); 676 RTC_DCHECK_EQ(ssrc, rtp_rtcp_modules_[i]->SSRC());
677 rtp_states[ssrc] = rtp_rtcp_modules_[i]->GetRtpState();
602 } 678 }
603 679
604 for (size_t i = 0; i < config_.rtp.rtx.ssrcs.size(); ++i) { 680 for (size_t i = 0; i < config_.rtp.rtx.ssrcs.size(); ++i) {
605 uint32_t ssrc = config_.rtp.rtx.ssrcs[i]; 681 uint32_t ssrc = config_.rtp.rtx.ssrcs[i];
606 rtp_states[ssrc] = vie_channel_.GetRtpStateForSsrc(ssrc); 682 rtp_states[ssrc] = rtp_rtcp_modules_[i]->GetRtxState();
607 } 683 }
608 684
609 return rtp_states; 685 return rtp_states;
610 } 686 }
611 687
612 void VideoSendStream::SignalNetworkState(NetworkState state) { 688 void VideoSendStream::SignalNetworkState(NetworkState state) {
613 // When network goes up, enable RTCP status before setting transmission state. 689 // When network goes up, enable RTCP status before setting transmission state.
614 // When it goes down, disable RTCP afterwards. This ensures that any packets 690 // When it goes down, disable RTCP afterwards. This ensures that any packets
615 // sent due to the network state changed will not be dropped. 691 // sent due to the network state changed will not be dropped.
616 if (state == kNetworkUp) { 692 if (state == kNetworkUp) {
(...skipping 10 matching lines...) Expand all
627 int VideoSendStream::GetPaddingNeededBps() const { 703 int VideoSendStream::GetPaddingNeededBps() const {
628 return vie_encoder_.GetPaddingNeededBps(); 704 return vie_encoder_.GetPaddingNeededBps();
629 } 705 }
630 706
631 void VideoSendStream::OnBitrateUpdated(uint32_t bitrate_bps, 707 void VideoSendStream::OnBitrateUpdated(uint32_t bitrate_bps,
632 uint8_t fraction_loss, 708 uint8_t fraction_loss,
633 int64_t rtt) { 709 int64_t rtt) {
634 vie_encoder_.OnBitrateUpdated(bitrate_bps, fraction_loss, rtt); 710 vie_encoder_.OnBitrateUpdated(bitrate_bps, fraction_loss, rtt);
635 } 711 }
636 712
713 int VideoSendStream::ProtectionRequest(const FecProtectionParams* delta_params,
714 const FecProtectionParams* key_params,
715 uint32_t* sent_video_rate_bps,
716 uint32_t* sent_nack_rate_bps,
717 uint32_t* sent_fec_rate_bps) {
718 *sent_video_rate_bps = 0;
719 *sent_nack_rate_bps = 0;
720 *sent_fec_rate_bps = 0;
721 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
722 uint32_t not_used = 0;
723 uint32_t module_video_rate = 0;
724 uint32_t module_fec_rate = 0;
725 uint32_t module_nack_rate = 0;
726 rtp_rtcp->SetFecParameters(delta_params, key_params);
727 rtp_rtcp->BitrateSent(&not_used, &module_video_rate, &module_fec_rate,
728 &module_nack_rate);
729 *sent_video_rate_bps += module_video_rate;
730 *sent_nack_rate_bps += module_nack_rate;
731 *sent_fec_rate_bps += module_fec_rate;
732 }
733 return 0;
734 }
735
637 } // namespace internal 736 } // namespace internal
638 } // namespace webrtc 737 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698