OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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(¬_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 |
OLD | NEW |