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 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
190 vie_encoder_(num_cpu_cores, | 190 vie_encoder_(num_cpu_cores, |
191 config_.rtp.ssrcs, | 191 config_.rtp.ssrcs, |
192 module_process_thread_, | 192 module_process_thread_, |
193 &stats_proxy_, | 193 &stats_proxy_, |
194 config.pre_encode_callback, | 194 config.pre_encode_callback, |
195 &overuse_detector_, | 195 &overuse_detector_, |
196 congestion_controller_->pacer(), | 196 congestion_controller_->pacer(), |
197 &payload_router_, | 197 &payload_router_, |
198 bitrate_allocator), | 198 bitrate_allocator), |
199 vcm_(vie_encoder_.vcm()), | 199 vcm_(vie_encoder_.vcm()), |
| 200 rtp_rtcp_modules_(vie_channel_.rtp_rtcp()), |
200 input_(&vie_encoder_, | 201 input_(&vie_encoder_, |
201 config_.local_renderer, | 202 config_.local_renderer, |
202 &stats_proxy_, | 203 &stats_proxy_, |
203 &overuse_detector_) { | 204 &overuse_detector_) { |
204 LOG(LS_INFO) << "VideoSendStream: " << config_.ToString(); | 205 LOG(LS_INFO) << "VideoSendStream: " << config_.ToString(); |
205 | 206 |
206 RTC_DCHECK(!config_.rtp.ssrcs.empty()); | 207 RTC_DCHECK(!config_.rtp.ssrcs.empty()); |
207 RTC_DCHECK(module_process_thread_); | 208 RTC_DCHECK(module_process_thread_); |
208 RTC_DCHECK(call_stats_); | 209 RTC_DCHECK(call_stats_); |
209 RTC_DCHECK(congestion_controller_); | 210 RTC_DCHECK(congestion_controller_); |
(...skipping 19 matching lines...) Expand all Loading... |
229 RTC_CHECK_EQ(0, vie_channel_.SetSendAbsoluteSendTimeStatus(true, id)); | 230 RTC_CHECK_EQ(0, vie_channel_.SetSendAbsoluteSendTimeStatus(true, id)); |
230 } else if (extension == RtpExtension::kVideoRotation) { | 231 } else if (extension == RtpExtension::kVideoRotation) { |
231 RTC_CHECK_EQ(0, vie_channel_.SetSendVideoRotationStatus(true, id)); | 232 RTC_CHECK_EQ(0, vie_channel_.SetSendVideoRotationStatus(true, id)); |
232 } else if (extension == RtpExtension::kTransportSequenceNumber) { | 233 } else if (extension == RtpExtension::kTransportSequenceNumber) { |
233 RTC_CHECK_EQ(0, vie_channel_.SetSendTransportSequenceNumber(true, id)); | 234 RTC_CHECK_EQ(0, vie_channel_.SetSendTransportSequenceNumber(true, id)); |
234 } else { | 235 } else { |
235 RTC_NOTREACHED() << "Registering unsupported RTP extension."; | 236 RTC_NOTREACHED() << "Registering unsupported RTP extension."; |
236 } | 237 } |
237 } | 238 } |
238 | 239 |
239 RtpRtcp* rtp_module = vie_channel_.rtp_rtcp(); | 240 remb_->AddRembSender(rtp_rtcp_modules_[0]); |
240 remb_->AddRembSender(rtp_module); | 241 rtp_rtcp_modules_[0]->SetREMBStatus(true); |
241 rtp_module->SetREMBStatus(true); | |
242 | 242 |
243 // Enable NACK, FEC or both. | 243 // Enable NACK, FEC or both. |
244 const bool enable_protection_nack = config_.rtp.nack.rtp_history_ms > 0; | 244 const bool enable_protection_nack = config_.rtp.nack.rtp_history_ms > 0; |
245 bool enable_protection_fec = config_.rtp.fec.red_payload_type != -1; | 245 bool enable_protection_fec = config_.rtp.fec.red_payload_type != -1; |
246 // Payload types without picture ID cannot determine that a stream is complete | 246 // Payload types without picture ID cannot determine that a stream is complete |
247 // without retransmitting FEC, so using FEC + NACK for H.264 (for instance) is | 247 // without retransmitting FEC, so using FEC + NACK for H.264 (for instance) is |
248 // a waste of bandwidth since FEC packets still have to be transmitted. Note | 248 // a waste of bandwidth since FEC packets still have to be transmitted. Note |
249 // that this is not the case with FLEXFEC. | 249 // that this is not the case with FLEXFEC. |
250 if (enable_protection_nack && | 250 if (enable_protection_nack && |
251 !PayloadTypeSupportsSkippingFecPackets( | 251 !PayloadTypeSupportsSkippingFecPackets( |
252 config_.encoder_settings.payload_name)) { | 252 config_.encoder_settings.payload_name)) { |
253 LOG(LS_WARNING) << "Transmitting payload type without picture ID using" | 253 LOG(LS_WARNING) << "Transmitting payload type without picture ID using" |
254 "NACK+FEC is a waste of bandwidth since FEC packets " | 254 "NACK+FEC is a waste of bandwidth since FEC packets " |
255 "also have to be retransmitted. Disabling FEC."; | 255 "also have to be retransmitted. Disabling FEC."; |
256 enable_protection_fec = false; | 256 enable_protection_fec = false; |
257 } | 257 } |
258 // TODO(changbin): Should set RTX for RED mapping in RTP sender in future. | 258 // TODO(changbin): Should set RTX for RED mapping in RTP sender in future. |
259 vie_channel_.SetProtectionMode(enable_protection_nack, enable_protection_fec, | 259 vie_channel_.SetProtectionMode(enable_protection_nack, enable_protection_fec, |
260 config_.rtp.fec.red_payload_type, | 260 config_.rtp.fec.red_payload_type, |
261 config_.rtp.fec.ulpfec_payload_type); | 261 config_.rtp.fec.ulpfec_payload_type); |
262 vie_encoder_.SetProtectionMethod(enable_protection_nack, | 262 vie_encoder_.SetProtectionMethod(enable_protection_nack, |
263 enable_protection_fec); | 263 enable_protection_fec); |
264 | 264 |
265 ConfigureSsrcs(); | 265 ConfigureSsrcs(); |
266 | 266 |
267 vie_channel_.SetRTCPCName(config_.rtp.c_name.c_str()); | 267 // TODO(pbos): Should we set CNAME on all RTP modules? |
268 | 268 rtp_rtcp_modules_.front()->SetCNAME(config_.rtp.c_name.c_str()); |
269 // 28 to match packet overhead in ModuleRtpRtcpImpl. | 269 // 28 to match packet overhead in ModuleRtpRtcpImpl. |
270 RTC_DCHECK_LE(config_.rtp.max_packet_size, static_cast<size_t>(0xFFFF - 28)); | 270 static const size_t kRtpPacketSizeOverhead = 28; |
271 vie_channel_.SetMTU(static_cast<uint16_t>(config_.rtp.max_packet_size + 28)); | 271 RTC_DCHECK_LE(config_.rtp.max_packet_size, 0xFFFFu + kRtpPacketSizeOverhead); |
| 272 const uint16_t mtu = static_cast<uint16_t>(config_.rtp.max_packet_size + |
| 273 kRtpPacketSizeOverhead); |
| 274 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { |
| 275 rtp_rtcp->RegisterRtcpStatisticsCallback(&stats_proxy_); |
| 276 rtp_rtcp->RegisterSendChannelRtpStatisticsCallback(&stats_proxy_); |
| 277 rtp_rtcp->SetMaxTransferUnit(mtu); |
| 278 } |
272 | 279 |
273 RTC_DCHECK(config.encoder_settings.encoder != nullptr); | 280 RTC_DCHECK(config.encoder_settings.encoder != nullptr); |
274 RTC_DCHECK_GE(config.encoder_settings.payload_type, 0); | 281 RTC_DCHECK_GE(config.encoder_settings.payload_type, 0); |
275 RTC_DCHECK_LE(config.encoder_settings.payload_type, 127); | 282 RTC_DCHECK_LE(config.encoder_settings.payload_type, 127); |
276 RTC_CHECK_EQ(0, vie_encoder_.RegisterExternalEncoder( | 283 RTC_CHECK_EQ(0, vie_encoder_.RegisterExternalEncoder( |
277 config.encoder_settings.encoder, | 284 config.encoder_settings.encoder, |
278 config.encoder_settings.payload_type, | 285 config.encoder_settings.payload_type, |
279 config.encoder_settings.internal_source)); | 286 config.encoder_settings.internal_source)); |
280 | 287 |
281 RTC_CHECK(ReconfigureVideoEncoder(encoder_config)); | 288 RTC_CHECK(ReconfigureVideoEncoder(encoder_config)); |
282 | 289 |
283 vie_channel_.RegisterSendSideDelayObserver(&stats_proxy_); | 290 vie_channel_.RegisterSendSideDelayObserver(&stats_proxy_); |
284 | 291 |
285 if (config_.post_encode_callback) | 292 if (config_.post_encode_callback) |
286 vie_encoder_.RegisterPostEncodeImageCallback(&encoded_frame_proxy_); | 293 vie_encoder_.RegisterPostEncodeImageCallback(&encoded_frame_proxy_); |
287 | 294 |
288 if (config_.suspend_below_min_bitrate) | 295 if (config_.suspend_below_min_bitrate) |
289 vie_encoder_.SuspendBelowMinBitrate(); | 296 vie_encoder_.SuspendBelowMinBitrate(); |
290 | 297 |
291 vie_channel_.RegisterSendChannelRtcpStatisticsCallback(&stats_proxy_); | |
292 vie_channel_.RegisterSendChannelRtpStatisticsCallback(&stats_proxy_); | |
293 vie_channel_.RegisterRtcpPacketTypeCounterObserver(&stats_proxy_); | 298 vie_channel_.RegisterRtcpPacketTypeCounterObserver(&stats_proxy_); |
294 vie_channel_.RegisterSendBitrateObserver(&stats_proxy_); | 299 vie_channel_.RegisterSendBitrateObserver(&stats_proxy_); |
295 vie_channel_.RegisterSendFrameCountObserver(&stats_proxy_); | 300 vie_channel_.RegisterSendFrameCountObserver(&stats_proxy_); |
296 | 301 |
297 module_process_thread_->RegisterModule(&overuse_detector_); | 302 module_process_thread_->RegisterModule(&overuse_detector_); |
298 } | 303 } |
299 | 304 |
300 VideoSendStream::~VideoSendStream() { | 305 VideoSendStream::~VideoSendStream() { |
301 LOG(LS_INFO) << "~VideoSendStream: " << config_.ToString(); | 306 LOG(LS_INFO) << "~VideoSendStream: " << config_.ToString(); |
302 Stop(); | 307 Stop(); |
303 | 308 |
304 module_process_thread_->DeRegisterModule(&overuse_detector_); | 309 module_process_thread_->DeRegisterModule(&overuse_detector_); |
305 vie_channel_.RegisterSendFrameCountObserver(nullptr); | 310 vie_channel_.RegisterSendFrameCountObserver(nullptr); |
306 vie_channel_.RegisterSendBitrateObserver(nullptr); | 311 vie_channel_.RegisterSendBitrateObserver(nullptr); |
307 vie_channel_.RegisterRtcpPacketTypeCounterObserver(nullptr); | 312 vie_channel_.RegisterRtcpPacketTypeCounterObserver(nullptr); |
308 vie_channel_.RegisterSendChannelRtpStatisticsCallback(nullptr); | |
309 vie_channel_.RegisterSendChannelRtcpStatisticsCallback(nullptr); | |
310 | 313 |
311 vie_encoder_.DeRegisterExternalEncoder( | 314 vie_encoder_.DeRegisterExternalEncoder(config_.encoder_settings.payload_type); |
312 config_.encoder_settings.payload_type); | |
313 | 315 |
314 call_stats_->DeregisterStatsObserver(vie_channel_.GetStatsObserver()); | 316 call_stats_->DeregisterStatsObserver(vie_channel_.GetStatsObserver()); |
315 | 317 rtp_rtcp_modules_[0]->SetREMBStatus(false); |
316 RtpRtcp* rtp_module = vie_channel_.rtp_rtcp(); | 318 remb_->RemoveRembSender(rtp_rtcp_modules_[0]); |
317 rtp_module->SetREMBStatus(false); | |
318 remb_->RemoveRembSender(rtp_module); | |
319 | 319 |
320 // ViEChannel outlives ViEEncoder so remove encoder from feedback before | 320 // ViEChannel outlives ViEEncoder so remove encoder from feedback before |
321 // destruction. | 321 // destruction. |
322 encoder_feedback_.TearDown(); | 322 encoder_feedback_.TearDown(); |
323 | 323 |
324 congestion_controller_->GetRemoteBitrateEstimator(false)->RemoveStream( | 324 congestion_controller_->GetRemoteBitrateEstimator(false)->RemoveStream( |
325 vie_receiver_->GetRemoteSsrc()); | 325 vie_receiver_->GetRemoteSsrc()); |
326 } | 326 } |
327 | 327 |
328 VideoCaptureInput* VideoSendStream::Input() { | 328 VideoCaptureInput* VideoSendStream::Input() { |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
502 if (config_.overuse_callback) | 502 if (config_.overuse_callback) |
503 config_.overuse_callback->OnLoadUpdate(LoadObserver::kOveruse); | 503 config_.overuse_callback->OnLoadUpdate(LoadObserver::kOveruse); |
504 } | 504 } |
505 | 505 |
506 void VideoSendStream::NormalUsage() { | 506 void VideoSendStream::NormalUsage() { |
507 if (config_.overuse_callback) | 507 if (config_.overuse_callback) |
508 config_.overuse_callback->OnLoadUpdate(LoadObserver::kUnderuse); | 508 config_.overuse_callback->OnLoadUpdate(LoadObserver::kUnderuse); |
509 } | 509 } |
510 | 510 |
511 void VideoSendStream::ConfigureSsrcs() { | 511 void VideoSendStream::ConfigureSsrcs() { |
512 vie_channel_.SetSSRC(config_.rtp.ssrcs.front(), kViEStreamTypeNormal, 0); | 512 // Configure regular SSRCs. |
513 for (size_t i = 0; i < config_.rtp.ssrcs.size(); ++i) { | 513 for (size_t i = 0; i < config_.rtp.ssrcs.size(); ++i) { |
514 uint32_t ssrc = config_.rtp.ssrcs[i]; | 514 uint32_t ssrc = config_.rtp.ssrcs[i]; |
515 vie_channel_.SetSSRC(ssrc, kViEStreamTypeNormal, | 515 RtpRtcp* const rtp_rtcp = rtp_rtcp_modules_[i]; |
516 static_cast<unsigned char>(i)); | 516 rtp_rtcp->SetSSRC(ssrc); |
| 517 |
| 518 // Restore RTP state if previous existed. |
517 RtpStateMap::iterator it = suspended_ssrcs_.find(ssrc); | 519 RtpStateMap::iterator it = suspended_ssrcs_.find(ssrc); |
518 if (it != suspended_ssrcs_.end()) | 520 if (it != suspended_ssrcs_.end()) |
519 vie_channel_.SetRtpStateForSsrc(ssrc, it->second); | 521 rtp_rtcp->SetRtpStateForSsrc(ssrc, it->second); |
520 } | 522 } |
521 | 523 |
522 if (config_.rtp.rtx.ssrcs.empty()) { | 524 // Set up RTX if available. |
| 525 if (config_.rtp.rtx.ssrcs.empty()) |
523 return; | 526 return; |
524 } | |
525 | 527 |
526 // Set up RTX. | 528 // Configure RTX SSRCs. |
527 RTC_DCHECK_EQ(config_.rtp.rtx.ssrcs.size(), config_.rtp.ssrcs.size()); | 529 RTC_DCHECK_EQ(config_.rtp.rtx.ssrcs.size(), config_.rtp.ssrcs.size()); |
528 for (size_t i = 0; i < config_.rtp.rtx.ssrcs.size(); ++i) { | 530 for (size_t i = 0; i < config_.rtp.rtx.ssrcs.size(); ++i) { |
529 uint32_t ssrc = config_.rtp.rtx.ssrcs[i]; | 531 uint32_t ssrc = config_.rtp.rtx.ssrcs[i]; |
530 vie_channel_.SetSSRC(config_.rtp.rtx.ssrcs[i], kViEStreamTypeRtx, | 532 RtpRtcp* const rtp_rtcp = rtp_rtcp_modules_[i]; |
531 static_cast<unsigned char>(i)); | 533 rtp_rtcp->SetRtxSsrc(ssrc); |
532 RtpStateMap::iterator it = suspended_ssrcs_.find(ssrc); | 534 RtpStateMap::iterator it = suspended_ssrcs_.find(ssrc); |
533 if (it != suspended_ssrcs_.end()) | 535 if (it != suspended_ssrcs_.end()) |
534 vie_channel_.SetRtpStateForSsrc(ssrc, it->second); | 536 rtp_rtcp->SetRtpStateForSsrc(ssrc, it->second); |
535 } | 537 } |
536 | 538 |
| 539 // Configure RTX payload types. |
537 RTC_DCHECK_GE(config_.rtp.rtx.payload_type, 0); | 540 RTC_DCHECK_GE(config_.rtp.rtx.payload_type, 0); |
538 vie_channel_.SetRtxSendPayloadType(config_.rtp.rtx.payload_type, | 541 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { |
539 config_.encoder_settings.payload_type); | 542 rtp_rtcp->SetRtxSendPayloadType(config_.rtp.rtx.payload_type, |
| 543 config_.encoder_settings.payload_type); |
| 544 rtp_rtcp->SetRtxSendStatus(kRtxRetransmitted | kRtxRedundantPayloads); |
| 545 } |
540 if (config_.rtp.fec.red_payload_type != -1 && | 546 if (config_.rtp.fec.red_payload_type != -1 && |
541 config_.rtp.fec.red_rtx_payload_type != -1) { | 547 config_.rtp.fec.red_rtx_payload_type != -1) { |
542 vie_channel_.SetRtxSendPayloadType(config_.rtp.fec.red_rtx_payload_type, | 548 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { |
543 config_.rtp.fec.red_payload_type); | 549 rtp_rtcp->SetRtxSendPayloadType(config_.rtp.fec.red_rtx_payload_type, |
| 550 config_.rtp.fec.red_payload_type); |
| 551 } |
544 } | 552 } |
545 } | 553 } |
546 | 554 |
547 std::map<uint32_t, RtpState> VideoSendStream::GetRtpStates() const { | 555 std::map<uint32_t, RtpState> VideoSendStream::GetRtpStates() const { |
548 std::map<uint32_t, RtpState> rtp_states; | 556 std::map<uint32_t, RtpState> rtp_states; |
549 for (size_t i = 0; i < config_.rtp.ssrcs.size(); ++i) { | 557 for (size_t i = 0; i < config_.rtp.ssrcs.size(); ++i) { |
550 uint32_t ssrc = config_.rtp.ssrcs[i]; | 558 uint32_t ssrc = config_.rtp.ssrcs[i]; |
551 rtp_states[ssrc] = vie_channel_.GetRtpStateForSsrc(ssrc); | 559 rtp_states[ssrc] = vie_channel_.GetRtpStateForSsrc(ssrc); |
552 } | 560 } |
553 | 561 |
554 for (size_t i = 0; i < config_.rtp.rtx.ssrcs.size(); ++i) { | 562 for (size_t i = 0; i < config_.rtp.rtx.ssrcs.size(); ++i) { |
555 uint32_t ssrc = config_.rtp.rtx.ssrcs[i]; | 563 uint32_t ssrc = config_.rtp.rtx.ssrcs[i]; |
556 rtp_states[ssrc] = vie_channel_.GetRtpStateForSsrc(ssrc); | 564 rtp_states[ssrc] = vie_channel_.GetRtpStateForSsrc(ssrc); |
557 } | 565 } |
558 | 566 |
559 return rtp_states; | 567 return rtp_states; |
560 } | 568 } |
561 | 569 |
562 void VideoSendStream::SignalNetworkState(NetworkState state) { | 570 void VideoSendStream::SignalNetworkState(NetworkState state) { |
563 // When network goes up, enable RTCP status before setting transmission state. | 571 // When network goes up, enable RTCP status before setting transmission state. |
564 // When it goes down, disable RTCP afterwards. This ensures that any packets | 572 // When it goes down, disable RTCP afterwards. This ensures that any packets |
565 // sent due to the network state changed will not be dropped. | 573 // sent due to the network state changed will not be dropped. |
566 if (state == kNetworkUp) | 574 if (state == kNetworkUp) { |
567 vie_channel_.SetRTCPMode(config_.rtp.rtcp_mode); | 575 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) |
| 576 rtp_rtcp->SetRTCPStatus(config_.rtp.rtcp_mode); |
| 577 } |
568 vie_encoder_.SetNetworkTransmissionState(state == kNetworkUp); | 578 vie_encoder_.SetNetworkTransmissionState(state == kNetworkUp); |
569 if (state == kNetworkDown) | 579 if (state == kNetworkDown) { |
570 vie_channel_.SetRTCPMode(RtcpMode::kOff); | 580 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) |
| 581 rtp_rtcp->SetRTCPStatus(RtcpMode::kOff); |
| 582 } |
571 } | 583 } |
572 | 584 |
573 int VideoSendStream::GetPaddingNeededBps() const { | 585 int VideoSendStream::GetPaddingNeededBps() const { |
574 return vie_encoder_.GetPaddingNeededBps(); | 586 return vie_encoder_.GetPaddingNeededBps(); |
575 } | 587 } |
576 | 588 |
577 bool VideoSendStream::SetSendCodec(VideoCodec video_codec) { | 589 bool VideoSendStream::SetSendCodec(VideoCodec video_codec) { |
578 static const int kEncoderMinBitrate = 30; | 590 static const int kEncoderMinBitrate = 30; |
579 if (video_codec.maxBitrate == 0) { | 591 if (video_codec.maxBitrate == 0) { |
580 // Unset max bitrate -> cap to one bit per pixel. | 592 // Unset max bitrate -> cap to one bit per pixel. |
(...skipping 20 matching lines...) Expand all Loading... |
601 return false; | 613 return false; |
602 } | 614 } |
603 | 615 |
604 // Restart the media flow | 616 // Restart the media flow |
605 vie_encoder_.Restart(); | 617 vie_encoder_.Restart(); |
606 | 618 |
607 return true; | 619 return true; |
608 } | 620 } |
609 } // namespace internal | 621 } // namespace internal |
610 } // namespace webrtc | 622 } // namespace webrtc |
OLD | NEW |