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

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
« no previous file with comments | « webrtc/video/video_send_stream.h ('k') | webrtc/video/vie_channel.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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);
231 276
232 for (size_t i = 0; i < config_.rtp.extensions.size(); ++i) { 277 for (size_t i = 0; i < config_.rtp.extensions.size(); ++i) {
233 const std::string& extension = config_.rtp.extensions[i].name; 278 const std::string& extension = config_.rtp.extensions[i].name;
234 int id = config_.rtp.extensions[i].id; 279 int id = config_.rtp.extensions[i].id;
235 // One-byte-extension local identifiers are in the range 1-14 inclusive. 280 // One-byte-extension local identifiers are in the range 1-14 inclusive.
236 RTC_DCHECK_GE(id, 1); 281 RTC_DCHECK_GE(id, 1);
237 RTC_DCHECK_LE(id, 14); 282 RTC_DCHECK_LE(id, 14);
238 RTC_DCHECK(RtpExtension::IsSupportedForVideo(extension)); 283 RTC_DCHECK(RtpExtension::IsSupportedForVideo(extension));
239 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { 284 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
240 RTC_CHECK_EQ(0, rtp_rtcp->RegisterSendRtpHeaderExtension( 285 RTC_CHECK_EQ(0, rtp_rtcp->RegisterSendRtpHeaderExtension(
241 StringToRtpExtensionType(extension), id)); 286 StringToRtpExtensionType(extension), id));
242 } 287 }
243 } 288 }
244 289
245 remb_->AddRembSender(rtp_rtcp_modules_[0]); 290 remb_->AddRembSender(rtp_rtcp_modules_[0]);
246 rtp_rtcp_modules_[0]->SetREMBStatus(true); 291 rtp_rtcp_modules_[0]->SetREMBStatus(true);
247 292
248 // Enable NACK, FEC or both. 293 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(); 294 ConfigureSsrcs();
271 295
272 // TODO(pbos): Should we set CNAME on all RTP modules? 296 // TODO(pbos): Should we set CNAME on all RTP modules?
273 rtp_rtcp_modules_.front()->SetCNAME(config_.rtp.c_name.c_str()); 297 rtp_rtcp_modules_.front()->SetCNAME(config_.rtp.c_name.c_str());
274 // 28 to match packet overhead in ModuleRtpRtcpImpl. 298 // 28 to match packet overhead in ModuleRtpRtcpImpl.
275 static const size_t kRtpPacketSizeOverhead = 28; 299 static const size_t kRtpPacketSizeOverhead = 28;
276 RTC_DCHECK_LE(config_.rtp.max_packet_size, 0xFFFFu + kRtpPacketSizeOverhead); 300 RTC_DCHECK_LE(config_.rtp.max_packet_size, 0xFFFFu + kRtpPacketSizeOverhead);
277 const uint16_t mtu = static_cast<uint16_t>(config_.rtp.max_packet_size + 301 const uint16_t mtu = static_cast<uint16_t>(config_.rtp.max_packet_size +
278 kRtpPacketSizeOverhead); 302 kRtpPacketSizeOverhead);
279 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { 303 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
280 rtp_rtcp->RegisterRtcpStatisticsCallback(&stats_proxy_); 304 rtp_rtcp->RegisterRtcpStatisticsCallback(&stats_proxy_);
281 rtp_rtcp->RegisterSendChannelRtpStatisticsCallback(&stats_proxy_); 305 rtp_rtcp->RegisterSendChannelRtpStatisticsCallback(&stats_proxy_);
282 rtp_rtcp->SetMaxTransferUnit(mtu); 306 rtp_rtcp->SetMaxTransferUnit(mtu);
283 rtp_rtcp->RegisterVideoSendPayload( 307 rtp_rtcp->RegisterVideoSendPayload(
284 config_.encoder_settings.payload_type, 308 config_.encoder_settings.payload_type,
285 config_.encoder_settings.payload_name.c_str()); 309 config_.encoder_settings.payload_name.c_str());
286 } 310 }
287 311
288 RTC_DCHECK(config.encoder_settings.encoder); 312 RTC_DCHECK(config.encoder_settings.encoder);
289 RTC_DCHECK_GE(config.encoder_settings.payload_type, 0); 313 RTC_DCHECK_GE(config.encoder_settings.payload_type, 0);
290 RTC_DCHECK_LE(config.encoder_settings.payload_type, 127); 314 RTC_DCHECK_LE(config.encoder_settings.payload_type, 127);
291 RTC_CHECK_EQ(0, vie_encoder_.RegisterExternalEncoder( 315 RTC_CHECK_EQ(0, vie_encoder_.RegisterExternalEncoder(
292 config.encoder_settings.encoder, 316 config.encoder_settings.encoder,
293 config.encoder_settings.payload_type, 317 config.encoder_settings.payload_type,
294 config.encoder_settings.internal_source)); 318 config.encoder_settings.internal_source));
295 319
296 ReconfigureVideoEncoder(encoder_config); 320 ReconfigureVideoEncoder(encoder_config);
297 321
298 vie_channel_.RegisterSendSideDelayObserver(&stats_proxy_);
299
300 if (config_.post_encode_callback) 322 if (config_.post_encode_callback)
301 vie_encoder_.RegisterPostEncodeImageCallback(&encoded_frame_proxy_); 323 vie_encoder_.RegisterPostEncodeImageCallback(&encoded_frame_proxy_);
302 324
303 if (config_.suspend_below_min_bitrate) { 325 if (config_.suspend_below_min_bitrate) {
304 vcm_->SuspendBelowMinBitrate(); 326 vcm_->SuspendBelowMinBitrate();
305 bitrate_allocator_->EnforceMinBitrate(false); 327 bitrate_allocator_->EnforceMinBitrate(false);
306 } 328 }
307 329
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_); 330 module_process_thread_->RegisterModule(&overuse_detector_);
313 331
314 encoder_thread_.Start(); 332 encoder_thread_.Start();
315 encoder_thread_.SetPriority(rtc::kHighPriority); 333 encoder_thread_.SetPriority(rtc::kHighPriority);
316 } 334 }
317 335
318 VideoSendStream::~VideoSendStream() { 336 VideoSendStream::~VideoSendStream() {
319 LOG(LS_INFO) << "~VideoSendStream: " << config_.ToString(); 337 LOG(LS_INFO) << "~VideoSendStream: " << config_.ToString();
320 338
321 Stop(); 339 Stop();
322 340
323 // Stop the encoder thread permanently. 341 // Stop the encoder thread permanently.
324 rtc::AtomicOps::ReleaseStore(&stop_encoder_thread_, 1); 342 rtc::AtomicOps::ReleaseStore(&stop_encoder_thread_, 1);
325 encoder_wakeup_event_.Set(); 343 encoder_wakeup_event_.Set();
326 encoder_thread_.Stop(); 344 encoder_thread_.Stop();
327 345
328 // This needs to happen after stopping the encoder thread, 346 // This needs to happen after stopping the encoder thread,
329 // since the encoder thread calls AddObserver. 347 // since the encoder thread calls AddObserver.
330 bitrate_allocator_->RemoveObserver(this); 348 bitrate_allocator_->RemoveObserver(this);
331 349
332 module_process_thread_->DeRegisterModule(&overuse_detector_); 350 module_process_thread_->DeRegisterModule(&overuse_detector_);
333 vie_channel_.RegisterSendFrameCountObserver(nullptr);
334 vie_channel_.RegisterSendBitrateObserver(nullptr);
335 vie_channel_.RegisterRtcpPacketTypeCounterObserver(nullptr);
336 351
337 vie_encoder_.DeRegisterExternalEncoder(config_.encoder_settings.payload_type); 352 vie_encoder_.DeRegisterExternalEncoder(config_.encoder_settings.payload_type);
338 353
339 call_stats_->DeregisterStatsObserver(vie_channel_.GetStatsObserver());
340 rtp_rtcp_modules_[0]->SetREMBStatus(false); 354 rtp_rtcp_modules_[0]->SetREMBStatus(false);
341 remb_->RemoveRembSender(rtp_rtcp_modules_[0]); 355 remb_->RemoveRembSender(rtp_rtcp_modules_[0]);
342 356
343 // ViEChannel outlives ViEEncoder so remove encoder from feedback before 357 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
344 // destruction. 358 congestion_controller_->packet_router()->RemoveRtpModule(rtp_rtcp);
345 encoder_feedback_.TearDown(); 359 module_process_thread_->DeRegisterModule(rtp_rtcp);
346 360 delete rtp_rtcp;
347 congestion_controller_->GetRemoteBitrateEstimator(false)->RemoveStream( 361 }
348 vie_receiver_->GetRemoteSsrc());
349 } 362 }
350 363
351 VideoCaptureInput* VideoSendStream::Input() { 364 VideoCaptureInput* VideoSendStream::Input() {
352 return &input_; 365 return &input_;
353 } 366 }
354 367
355 void VideoSendStream::Start() { 368 void VideoSendStream::Start() {
356 if (payload_router_.active()) 369 if (payload_router_.active())
357 return; 370 return;
358 TRACE_EVENT_INSTANT0("webrtc", "VideoSendStream::Start"); 371 TRACE_EVENT_INSTANT0("webrtc", "VideoSendStream::Start");
359 vie_encoder_.Pause(); 372 vie_encoder_.Pause();
360 payload_router_.set_active(true); 373 payload_router_.set_active(true);
361 // Was not already started, trigger a keyframe. 374 // Was not already started, trigger a keyframe.
362 vie_encoder_.SendKeyFrame(); 375 vie_encoder_.SendKeyFrame();
363 vie_encoder_.Restart(); 376 vie_encoder_.Restart();
364 vie_receiver_->StartReceive();
365 } 377 }
366 378
367 void VideoSendStream::Stop() { 379 void VideoSendStream::Stop() {
368 if (!payload_router_.active()) 380 if (!payload_router_.active())
369 return; 381 return;
370 TRACE_EVENT_INSTANT0("webrtc", "VideoSendStream::Stop"); 382 TRACE_EVENT_INSTANT0("webrtc", "VideoSendStream::Stop");
371 // TODO(pbos): Make sure the encoder stops here. 383 // TODO(pbos): Make sure the encoder stops here.
372 payload_router_.set_active(false); 384 payload_router_.set_active(false);
373 vie_receiver_->StopReceive();
374 } 385 }
375 386
376 bool VideoSendStream::EncoderThreadFunction(void* obj) { 387 bool VideoSendStream::EncoderThreadFunction(void* obj) {
377 static_cast<VideoSendStream*>(obj)->EncoderProcess(); 388 static_cast<VideoSendStream*>(obj)->EncoderProcess();
378 // We're done, return false to abort. 389 // We're done, return false to abort.
379 return false; 390 return false;
380 } 391 }
381 392
382 void VideoSendStream::EncoderProcess() { 393 void VideoSendStream::EncoderProcess() {
383 while (true) { 394 while (true) {
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
528 video_codec.maxFramerate = streams[0].max_framerate; 539 video_codec.maxFramerate = streams[0].max_framerate;
529 540
530 video_codec.startBitrate = 541 video_codec.startBitrate =
531 bitrate_allocator_->AddObserver(this, 542 bitrate_allocator_->AddObserver(this,
532 video_codec.minBitrate * 1000, 543 video_codec.minBitrate * 1000,
533 video_codec.maxBitrate * 1000) / 1000; 544 video_codec.maxBitrate * 1000) / 1000;
534 vie_encoder_.SetEncoder(video_codec, config.min_transmit_bitrate_bps); 545 vie_encoder_.SetEncoder(video_codec, config.min_transmit_bitrate_bps);
535 } 546 }
536 547
537 bool VideoSendStream::DeliverRtcp(const uint8_t* packet, size_t length) { 548 bool VideoSendStream::DeliverRtcp(const uint8_t* packet, size_t length) {
538 return vie_receiver_->DeliverRtcp(packet, length); 549 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_)
550 rtp_rtcp->IncomingRtcpPacket(packet, length);
551 return true;
539 } 552 }
540 553
541 VideoSendStream::Stats VideoSendStream::GetStats() { 554 VideoSendStream::Stats VideoSendStream::GetStats() {
542 return stats_proxy_.GetStats(); 555 return stats_proxy_.GetStats();
543 } 556 }
544 557
545 void VideoSendStream::OveruseDetected() { 558 void VideoSendStream::OveruseDetected() {
546 if (config_.overuse_callback) 559 if (config_.overuse_callback)
547 config_.overuse_callback->OnLoadUpdate(LoadObserver::kOveruse); 560 config_.overuse_callback->OnLoadUpdate(LoadObserver::kOveruse);
548 } 561 }
549 562
550 void VideoSendStream::NormalUsage() { 563 void VideoSendStream::NormalUsage() {
551 if (config_.overuse_callback) 564 if (config_.overuse_callback)
552 config_.overuse_callback->OnLoadUpdate(LoadObserver::kUnderuse); 565 config_.overuse_callback->OnLoadUpdate(LoadObserver::kUnderuse);
553 } 566 }
554 567
568 void VideoSendStream::ConfigureProtection() {
569 // Enable NACK, FEC or both.
570 const bool enable_protection_nack = config_.rtp.nack.rtp_history_ms > 0;
571 bool enable_protection_fec = config_.rtp.fec.red_payload_type != -1;
572 // Payload types without picture ID cannot determine that a stream is complete
573 // without retransmitting FEC, so using FEC + NACK for H.264 (for instance) is
574 // a waste of bandwidth since FEC packets still have to be transmitted. Note
575 // that this is not the case with FLEXFEC.
576 if (enable_protection_nack &&
577 !PayloadTypeSupportsSkippingFecPackets(
578 config_.encoder_settings.payload_name)) {
579 LOG(LS_WARNING) << "Transmitting payload type without picture ID using"
580 "NACK+FEC is a waste of bandwidth since FEC packets "
581 "also have to be retransmitted. Disabling FEC.";
582 enable_protection_fec = false;
583 }
584
585 // Set to valid uint8_ts to be castable later without signed overflows.
586 uint8_t payload_type_red = 0;
587 uint8_t payload_type_fec = 0;
588 // TODO(changbin): Should set RTX for RED mapping in RTP sender in future.
589 // Validate payload types. If either RED or FEC payload types are set then
590 // both should be. If FEC is enabled then they both have to be set.
591 if (enable_protection_fec || config_.rtp.fec.red_payload_type != -1 ||
592 config_.rtp.fec.ulpfec_payload_type != -1) {
593 RTC_DCHECK_GE(config_.rtp.fec.red_payload_type, 0);
594 RTC_DCHECK_GE(config_.rtp.fec.ulpfec_payload_type, 0);
595 RTC_DCHECK_LE(config_.rtp.fec.red_payload_type, 127);
596 RTC_DCHECK_LE(config_.rtp.fec.ulpfec_payload_type, 127);
597 payload_type_red = static_cast<uint8_t>(config_.rtp.fec.red_payload_type);
598 payload_type_fec =
599 static_cast<uint8_t>(config_.rtp.fec.ulpfec_payload_type);
600 } else {
601 // Payload types unset.
602 RTC_DCHECK_EQ(config_.rtp.fec.red_payload_type, -1);
603 RTC_DCHECK_EQ(config_.rtp.fec.ulpfec_payload_type, -1);
604 }
605
606 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
607 // Set NACK.
608 rtp_rtcp->SetStorePacketsStatus(
609 enable_protection_nack || congestion_controller_->pacer(),
610 kMinSendSidePacketHistorySize);
611 // Set FEC.
612 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
613 rtp_rtcp->SetGenericFECStatus(enable_protection_fec, payload_type_red,
614 payload_type_fec);
615 }
616 }
617
618 vie_encoder_.SetProtectionMethod(enable_protection_nack,
619 enable_protection_fec);
620 }
621
555 void VideoSendStream::ConfigureSsrcs() { 622 void VideoSendStream::ConfigureSsrcs() {
556 // Configure regular SSRCs. 623 // Configure regular SSRCs.
557 for (size_t i = 0; i < config_.rtp.ssrcs.size(); ++i) { 624 for (size_t i = 0; i < config_.rtp.ssrcs.size(); ++i) {
558 uint32_t ssrc = config_.rtp.ssrcs[i]; 625 uint32_t ssrc = config_.rtp.ssrcs[i];
559 RtpRtcp* const rtp_rtcp = rtp_rtcp_modules_[i]; 626 RtpRtcp* const rtp_rtcp = rtp_rtcp_modules_[i];
560 rtp_rtcp->SetSSRC(ssrc); 627 rtp_rtcp->SetSSRC(ssrc);
561 628
562 // Restore RTP state if previous existed. 629 // Restore RTP state if previous existed.
563 RtpStateMap::iterator it = suspended_ssrcs_.find(ssrc); 630 RtpStateMap::iterator it = suspended_ssrcs_.find(ssrc);
564 if (it != suspended_ssrcs_.end()) 631 if (it != suspended_ssrcs_.end())
565 rtp_rtcp->SetRtpStateForSsrc(ssrc, it->second); 632 rtp_rtcp->SetRtpState(it->second);
566 } 633 }
567 634
568 // Set up RTX if available. 635 // Set up RTX if available.
569 if (config_.rtp.rtx.ssrcs.empty()) 636 if (config_.rtp.rtx.ssrcs.empty())
570 return; 637 return;
571 638
572 // Configure RTX SSRCs. 639 // Configure RTX SSRCs.
573 RTC_DCHECK_EQ(config_.rtp.rtx.ssrcs.size(), config_.rtp.ssrcs.size()); 640 RTC_DCHECK_EQ(config_.rtp.rtx.ssrcs.size(), config_.rtp.ssrcs.size());
574 for (size_t i = 0; i < config_.rtp.rtx.ssrcs.size(); ++i) { 641 for (size_t i = 0; i < config_.rtp.rtx.ssrcs.size(); ++i) {
575 uint32_t ssrc = config_.rtp.rtx.ssrcs[i]; 642 uint32_t ssrc = config_.rtp.rtx.ssrcs[i];
576 RtpRtcp* const rtp_rtcp = rtp_rtcp_modules_[i]; 643 RtpRtcp* const rtp_rtcp = rtp_rtcp_modules_[i];
577 rtp_rtcp->SetRtxSsrc(ssrc); 644 rtp_rtcp->SetRtxSsrc(ssrc);
578 RtpStateMap::iterator it = suspended_ssrcs_.find(ssrc); 645 RtpStateMap::iterator it = suspended_ssrcs_.find(ssrc);
579 if (it != suspended_ssrcs_.end()) 646 if (it != suspended_ssrcs_.end())
580 rtp_rtcp->SetRtpStateForSsrc(ssrc, it->second); 647 rtp_rtcp->SetRtxState(it->second);
581 } 648 }
582 649
583 // Configure RTX payload types. 650 // Configure RTX payload types.
584 RTC_DCHECK_GE(config_.rtp.rtx.payload_type, 0); 651 RTC_DCHECK_GE(config_.rtp.rtx.payload_type, 0);
585 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { 652 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
586 rtp_rtcp->SetRtxSendPayloadType(config_.rtp.rtx.payload_type, 653 rtp_rtcp->SetRtxSendPayloadType(config_.rtp.rtx.payload_type,
587 config_.encoder_settings.payload_type); 654 config_.encoder_settings.payload_type);
588 rtp_rtcp->SetRtxSendStatus(kRtxRetransmitted | kRtxRedundantPayloads); 655 rtp_rtcp->SetRtxSendStatus(kRtxRetransmitted | kRtxRedundantPayloads);
589 } 656 }
590 if (config_.rtp.fec.red_payload_type != -1 && 657 if (config_.rtp.fec.red_payload_type != -1 &&
591 config_.rtp.fec.red_rtx_payload_type != -1) { 658 config_.rtp.fec.red_rtx_payload_type != -1) {
592 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { 659 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
593 rtp_rtcp->SetRtxSendPayloadType(config_.rtp.fec.red_rtx_payload_type, 660 rtp_rtcp->SetRtxSendPayloadType(config_.rtp.fec.red_rtx_payload_type,
594 config_.rtp.fec.red_payload_type); 661 config_.rtp.fec.red_payload_type);
595 } 662 }
596 } 663 }
597 } 664 }
598 665
599 std::map<uint32_t, RtpState> VideoSendStream::GetRtpStates() const { 666 std::map<uint32_t, RtpState> VideoSendStream::GetRtpStates() const {
600 std::map<uint32_t, RtpState> rtp_states; 667 std::map<uint32_t, RtpState> rtp_states;
601 for (size_t i = 0; i < config_.rtp.ssrcs.size(); ++i) { 668 for (size_t i = 0; i < config_.rtp.ssrcs.size(); ++i) {
602 uint32_t ssrc = config_.rtp.ssrcs[i]; 669 uint32_t ssrc = config_.rtp.ssrcs[i];
603 rtp_states[ssrc] = vie_channel_.GetRtpStateForSsrc(ssrc); 670 RTC_DCHECK_EQ(ssrc, rtp_rtcp_modules_[i]->SSRC());
671 rtp_states[ssrc] = rtp_rtcp_modules_[i]->GetRtpState();
604 } 672 }
605 673
606 for (size_t i = 0; i < config_.rtp.rtx.ssrcs.size(); ++i) { 674 for (size_t i = 0; i < config_.rtp.rtx.ssrcs.size(); ++i) {
607 uint32_t ssrc = config_.rtp.rtx.ssrcs[i]; 675 uint32_t ssrc = config_.rtp.rtx.ssrcs[i];
608 rtp_states[ssrc] = vie_channel_.GetRtpStateForSsrc(ssrc); 676 rtp_states[ssrc] = rtp_rtcp_modules_[i]->GetRtxState();
609 } 677 }
610 678
611 return rtp_states; 679 return rtp_states;
612 } 680 }
613 681
614 void VideoSendStream::SignalNetworkState(NetworkState state) { 682 void VideoSendStream::SignalNetworkState(NetworkState state) {
615 // When network goes up, enable RTCP status before setting transmission state. 683 // When network goes up, enable RTCP status before setting transmission state.
616 // When it goes down, disable RTCP afterwards. This ensures that any packets 684 // When it goes down, disable RTCP afterwards. This ensures that any packets
617 // sent due to the network state changed will not be dropped. 685 // sent due to the network state changed will not be dropped.
618 if (state == kNetworkUp) { 686 if (state == kNetworkUp) {
(...skipping 10 matching lines...) Expand all
629 int VideoSendStream::GetPaddingNeededBps() const { 697 int VideoSendStream::GetPaddingNeededBps() const {
630 return vie_encoder_.GetPaddingNeededBps(); 698 return vie_encoder_.GetPaddingNeededBps();
631 } 699 }
632 700
633 void VideoSendStream::OnBitrateUpdated(uint32_t bitrate_bps, 701 void VideoSendStream::OnBitrateUpdated(uint32_t bitrate_bps,
634 uint8_t fraction_loss, 702 uint8_t fraction_loss,
635 int64_t rtt) { 703 int64_t rtt) {
636 vie_encoder_.OnBitrateUpdated(bitrate_bps, fraction_loss, rtt); 704 vie_encoder_.OnBitrateUpdated(bitrate_bps, fraction_loss, rtt);
637 } 705 }
638 706
707 int VideoSendStream::ProtectionRequest(const FecProtectionParams* delta_params,
708 const FecProtectionParams* key_params,
709 uint32_t* sent_video_rate_bps,
710 uint32_t* sent_nack_rate_bps,
711 uint32_t* sent_fec_rate_bps) {
712 *sent_video_rate_bps = 0;
713 *sent_nack_rate_bps = 0;
714 *sent_fec_rate_bps = 0;
715 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
716 uint32_t not_used = 0;
717 uint32_t module_video_rate = 0;
718 uint32_t module_fec_rate = 0;
719 uint32_t module_nack_rate = 0;
720 rtp_rtcp->SetFecParameters(delta_params, key_params);
721 rtp_rtcp->BitrateSent(&not_used, &module_video_rate, &module_fec_rate,
722 &module_nack_rate);
723 *sent_video_rate_bps += module_video_rate;
724 *sent_nack_rate_bps += module_nack_rate;
725 *sent_fec_rate_bps += module_fec_rate;
726 }
727 return 0;
728 }
729
639 } // namespace internal 730 } // namespace internal
640 } // namespace webrtc 731 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/video/video_send_stream.h ('k') | webrtc/video/vie_channel.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698