From d6f1a38165455d743fbe61f6980f22be6a3c4de9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Bostr=C3=B6m?= Date: Tue, 14 Jul 2015 16:08:02 +0200 Subject: [PATCH] Remove ViEChannel simulcast lock. Since the number of streams is now known on construction we can initialize all RTP modules on construction. They are internally locked so we don't nede a simulcast lock anymore. BUG=1695 R=mflodman@webrtc.org, stefan@webrtc.org Review URL: https://webrtc-codereview.appspot.com/52639004 . Cr-Commit-Position: refs/heads/master@{#9577} --- .../modules/rtp_rtcp/source/rtp_rtcp_impl.cc | 5 +- webrtc/modules/rtp_rtcp/source/rtp_sender.cc | 8 +- .../modules/rtp_rtcp/test/testAPI/test_api.cc | 2 - webrtc/video/call.cc | 2 +- webrtc/video/receive_statistics_proxy.h | 1 - webrtc/video/video_send_stream.cc | 6 +- webrtc/video_engine/vie_channel.cc | 931 +++++------------- webrtc/video_engine/vie_channel.h | 108 +- webrtc/video_engine/vie_channel_group.cc | 13 +- webrtc/video_engine/vie_channel_group.h | 2 + webrtc/video_engine/vie_receiver.cc | 21 +- webrtc/video_engine/vie_receiver.h | 6 +- 12 files changed, 341 insertions(+), 764 deletions(-) diff --git a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc index c46664f80d..9e05b767c4 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc +++ b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc @@ -472,10 +472,7 @@ int32_t ModuleRtpRtcpImpl::SetTransportOverhead( } int32_t ModuleRtpRtcpImpl::SetMaxTransferUnit(const uint16_t mtu) { - if (mtu > IP_PACKET_SIZE) { - LOG(LS_ERROR) << "Invalid mtu: " << mtu; - return -1; - } + DCHECK_LE(mtu, IP_PACKET_SIZE) << "Invalid mtu: " << mtu; return rtp_sender_.SetMaxPayloadLength(mtu - packet_overhead_, packet_overhead_); } diff --git a/webrtc/modules/rtp_rtcp/source/rtp_sender.cc b/webrtc/modules/rtp_rtcp/source/rtp_sender.cc index 0456688a89..f7f8bb05ac 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_sender.cc +++ b/webrtc/modules/rtp_rtcp/source/rtp_sender.cc @@ -355,10 +355,8 @@ int RTPSender::SendPayloadFrequency() const { int32_t RTPSender::SetMaxPayloadLength(size_t max_payload_length, uint16_t packet_over_head) { // Sanity check. - if (max_payload_length < 100 || max_payload_length > IP_PACKET_SIZE) { - LOG(LS_ERROR) << "Invalid max payload length: " << max_payload_length; - return -1; - } + DCHECK(max_payload_length >= 100 && max_payload_length <= IP_PACKET_SIZE) + << "Invalid max payload length: " << max_payload_length; CriticalSectionScoped cs(send_critsect_.get()); max_payload_length_ = max_payload_length; packet_over_head_ = packet_over_head; @@ -504,7 +502,7 @@ int32_t RTPSender::SendOutgoingData(FrameType frame_type, return -1; } - uint32_t ret_val; + int32_t ret_val; if (audio_configured_) { TRACE_EVENT_ASYNC_STEP1("webrtc", "Audio", capture_timestamp, "Send", "type", FrameTypeToString(frame_type)); diff --git a/webrtc/modules/rtp_rtcp/test/testAPI/test_api.cc b/webrtc/modules/rtp_rtcp/test/testAPI/test_api.cc index 5731efde9e..bba10654ab 100644 --- a/webrtc/modules/rtp_rtcp/test/testAPI/test_api.cc +++ b/webrtc/modules/rtp_rtcp/test/testAPI/test_api.cc @@ -125,8 +125,6 @@ TEST_F(RtpRtcpAPITest, Basic) { } TEST_F(RtpRtcpAPITest, MTU) { - EXPECT_EQ(-1, module_->SetMaxTransferUnit(10)); - EXPECT_EQ(-1, module_->SetMaxTransferUnit(IP_PACKET_SIZE + 1)); EXPECT_EQ(0, module_->SetMaxTransferUnit(1234)); EXPECT_EQ(1234 - 20 - 8, module_->MaxPayloadLength()); diff --git a/webrtc/video/call.cc b/webrtc/video/call.cc index cde41bc77a..39eb7d6bbc 100644 --- a/webrtc/video/call.cc +++ b/webrtc/video/call.cc @@ -176,7 +176,7 @@ Call::Call(const Call::Config& config) // TODO(pbos): Remove base channel when CreateReceiveChannel no longer // requires one. CHECK(channel_group_->CreateSendChannel( - base_channel_id_, 0, &transport_adapter_, num_cpu_cores_, true)); + base_channel_id_, 0, &transport_adapter_, num_cpu_cores_, 1, true)); if (config.overuse_callback) { overuse_observer_proxy_.reset( diff --git a/webrtc/video/receive_statistics_proxy.h b/webrtc/video/receive_statistics_proxy.h index 3e515658ed..df763ad910 100644 --- a/webrtc/video/receive_statistics_proxy.h +++ b/webrtc/video/receive_statistics_proxy.h @@ -62,7 +62,6 @@ class ReceiveStatisticsProxy : public ViEDecoderObserver, int jitter_buffer_ms, int min_playout_delay_ms, int render_delay_ms) override; - void RequestNewKeyFrame(const int video_channel) override {} // Overrides RtcpStatisticsCallback. void StatisticsUpdated(const webrtc::RtcpStatistics& statistics, diff --git a/webrtc/video/video_send_stream.cc b/webrtc/video/video_send_stream.cc index 4ef90dd849..9001897323 100644 --- a/webrtc/video/video_send_stream.cc +++ b/webrtc/video/video_send_stream.cc @@ -119,13 +119,13 @@ VideoSendStream::VideoSendStream( channel_id_(channel_id), use_config_bitrate_(true), stats_proxy_(Clock::GetRealTimeClock(), config) { + DCHECK(!config_.rtp.ssrcs.empty()); CHECK(channel_group->CreateSendChannel(channel_id_, 0, &transport_adapter_, - num_cpu_cores, true)); + num_cpu_cores, + config_.rtp.ssrcs.size(), true)); vie_channel_ = channel_group_->GetChannel(channel_id_); vie_encoder_ = channel_group_->GetEncoder(channel_id_); - DCHECK(!config_.rtp.ssrcs.empty()); - for (size_t i = 0; i < config_.rtp.extensions.size(); ++i) { const std::string& extension = config_.rtp.extensions[i].name; int id = config_.rtp.extensions[i].id; diff --git a/webrtc/video_engine/vie_channel.cc b/webrtc/video_engine/vie_channel.cc index f4d28eb645..0581226220 100644 --- a/webrtc/video_engine/vie_channel.cc +++ b/webrtc/video_engine/vie_channel.cc @@ -40,7 +40,6 @@ namespace webrtc { const int kMaxDecodeWaitTimeMs = 50; -const int kInvalidRtpExtensionId = 0; static const int kMaxTargetDelayMs = 10000; static const float kMaxIncompleteTimeMultiplier = 3.5f; @@ -84,21 +83,22 @@ ViEChannel::ViEChannel(int32_t channel_id, uint32_t number_of_cores, const Config& config, Transport* transport, - ProcessThread& module_process_thread, + ProcessThread* module_process_thread, RtcpIntraFrameObserver* intra_frame_observer, RtcpBandwidthObserver* bandwidth_observer, RemoteBitrateEstimator* remote_bitrate_estimator, RtcpRttStats* rtt_stats, PacedSender* paced_sender, PacketRouter* packet_router, + size_t max_rtp_streams, bool sender, bool disable_default_encoder) : channel_id_(channel_id), engine_id_(engine_id), number_of_cores_(number_of_cores), - num_socket_threads_(kViESocketThreads), - callback_cs_(CriticalSectionWrapper::CreateCriticalSection()), - rtp_rtcp_cs_(CriticalSectionWrapper::CreateCriticalSection()), + sender_(sender), + module_process_thread_(module_process_thread), + crit_(CriticalSectionWrapper::CreateCriticalSection()), send_payload_router_(new PayloadRouter()), vcm_protection_callback_(new ViEChannelProtectionCallback(this)), vcm_(VideoCodingModule::Create(Clock::GetRealTimeClock(), @@ -109,50 +109,52 @@ ViEChannel::ViEChannel(int32_t channel_id, stats_observer_(new ChannelStatsObserver(this)), vcm_receive_stats_callback_(NULL), incoming_video_stream_(nullptr), - module_process_thread_(module_process_thread), codec_observer_(NULL), - do_key_frame_callbackRequest_(false), intra_frame_observer_(intra_frame_observer), rtt_stats_(rtt_stats), paced_sender_(paced_sender), packet_router_(packet_router), bandwidth_observer_(bandwidth_observer), - send_timestamp_extension_id_(kInvalidRtpExtensionId), - absolute_send_time_extension_id_(kInvalidRtpExtensionId), - video_rotation_extension_id_(kInvalidRtpExtensionId), - transport_(transport), decoder_reset_(true), - wait_for_key_frame_(false), - mtu_(0), - sender_(sender), disable_default_encoder_(disable_default_encoder), nack_history_size_sender_(kSendSidePacketHistorySize), max_nack_reordering_threshold_(kMaxPacketAgeToNack), pre_render_callback_(NULL), - report_block_stats_sender_(new ReportBlockStats()) { - RtpRtcp::Configuration configuration = CreateRtpRtcpConfiguration(); - configuration.remote_bitrate_estimator = remote_bitrate_estimator; - configuration.receive_statistics = vie_receiver_.GetReceiveStatistics(); - rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(configuration)); - vie_receiver_.SetRtpRtcpModule(rtp_rtcp_.get()); + report_block_stats_sender_(new ReportBlockStats()), + rtp_rtcp_modules_( + CreateRtpRtcpModules(ViEModuleId(engine_id_, channel_id_), + !sender, + vie_receiver_.GetReceiveStatistics(), + transport, + sender ? intra_frame_observer_ : nullptr, + sender ? bandwidth_observer_.get() : nullptr, + rtt_stats_, + &rtcp_packet_type_counter_observer_, + remote_bitrate_estimator, + paced_sender_, + &send_bitrate_observer_, + &send_frame_count_observer_, + &send_side_delay_observer_, + max_rtp_streams)), + num_active_rtp_rtcp_modules_(1) { + vie_receiver_.SetRtpRtcpModule(rtp_rtcp_modules_[0]); vcm_->SetNackSettings(kMaxNackListSize, max_nack_reordering_threshold_, 0); } int32_t ViEChannel::Init() { - module_process_thread_.RegisterModule(vie_receiver_.GetReceiveStatistics()); + module_process_thread_->RegisterModule(vie_receiver_.GetReceiveStatistics()); // RTP/RTCP initialization. - rtp_rtcp_->SetSendingMediaStatus(false); - module_process_thread_.RegisterModule(rtp_rtcp_.get()); + module_process_thread_->RegisterModule(rtp_rtcp_modules_[0]); - rtp_rtcp_->SetKeyFrameRequestMethod(kKeyFrameReqFirRtp); - rtp_rtcp_->SetRTCPStatus(kRtcpCompound); + rtp_rtcp_modules_[0]->SetKeyFrameRequestMethod(kKeyFrameReqFirRtp); if (paced_sender_) { - rtp_rtcp_->SetStorePacketsStatus(true, nack_history_size_sender_); + for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) + rtp_rtcp->SetStorePacketsStatus(true, nack_history_size_sender_); } if (sender_) { - packet_router_->AddRtpModule(rtp_rtcp_.get()); - std::list send_rtp_modules(1, rtp_rtcp_.get()); + packet_router_->AddRtpModule(rtp_rtcp_modules_[0]); + std::list send_rtp_modules(1, rtp_rtcp_modules_[0]); send_payload_router_->SetSendingRtpModules(send_rtp_modules); DCHECK(!send_payload_router_->active()); } @@ -167,23 +169,23 @@ int32_t ViEChannel::Init() { vcm_->RegisterDecoderTimingCallback(this); vcm_->SetRenderDelay(kViEDefaultRenderDelayMs); - module_process_thread_.RegisterModule(vcm_); - module_process_thread_.RegisterModule(&vie_sync_); + module_process_thread_->RegisterModule(vcm_); + module_process_thread_->RegisterModule(&vie_sync_); #ifdef VIDEOCODEC_VP8 if (!disable_default_encoder_) { VideoCodec video_codec; if (vcm_->Codec(kVideoCodecVP8, &video_codec) == VCM_OK) { - rtp_rtcp_->RegisterSendPayload(video_codec); + rtp_rtcp_modules_[0]->RegisterSendPayload(video_codec); // TODO(holmer): Can we call SetReceiveCodec() here instead? if (!vie_receiver_.RegisterPayload(video_codec)) { return -1; } vcm_->RegisterReceiveCodec(&video_codec, number_of_cores_); vcm_->RegisterSendCodec(&video_codec, number_of_cores_, - rtp_rtcp_->MaxDataPayloadLength()); + rtp_rtcp_modules_[0]->MaxDataPayloadLength()); } else { - assert(false); + RTC_NOTREACHED(); } } #endif @@ -194,24 +196,15 @@ int32_t ViEChannel::Init() { ViEChannel::~ViEChannel() { UpdateHistograms(); // Make sure we don't get more callbacks from the RTP module. - module_process_thread_.DeRegisterModule(vie_receiver_.GetReceiveStatistics()); - module_process_thread_.DeRegisterModule(rtp_rtcp_.get()); - module_process_thread_.DeRegisterModule(vcm_); - module_process_thread_.DeRegisterModule(&vie_sync_); + module_process_thread_->DeRegisterModule( + vie_receiver_.GetReceiveStatistics()); + module_process_thread_->DeRegisterModule(vcm_); + module_process_thread_->DeRegisterModule(&vie_sync_); send_payload_router_->SetSendingRtpModules(std::list()); - packet_router_->RemoveRtpModule(rtp_rtcp_.get()); - while (simulcast_rtp_rtcp_.size() > 0) { - std::list::iterator it = simulcast_rtp_rtcp_.begin(); - RtpRtcp* rtp_rtcp = *it; + for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { packet_router_->RemoveRtpModule(rtp_rtcp); - module_process_thread_.DeRegisterModule(rtp_rtcp); + module_process_thread_->DeRegisterModule(rtp_rtcp); delete rtp_rtcp; - simulcast_rtp_rtcp_.erase(it); - } - while (removed_rtp_rtcp_.size() > 0) { - std::list::iterator it = removed_rtp_rtcp_.begin(); - delete *it; - removed_rtp_rtcp_.erase(it); } if (decode_thread_) { StopDecodeThread(); @@ -270,7 +263,7 @@ void ViEChannel::UpdateHistograms() { "WebRTC.Video.RetransmittedBitrateSentInKbps", static_cast(rtp_rtx.retransmitted.TotalBytes() * 8 / elapsed_sec / 1000)); - if (rtp_rtcp_->RtxSendStatus() != kRtxOff) { + if (rtp_rtcp_modules_[0]->RtxSendStatus() != kRtxOff) { RTC_HISTOGRAM_COUNTS_10000( "WebRTC.Video.RtxBitrateSentInKbps", static_cast(rtx.transmitted.TotalBytes() * 8 / elapsed_sec / @@ -279,7 +272,8 @@ void ViEChannel::UpdateHistograms() { bool fec_enabled = false; uint8_t pltype_red; uint8_t pltype_fec; - rtp_rtcp_->GenericFECStatus(fec_enabled, pltype_red, pltype_fec); + rtp_rtcp_modules_[0]->GenericFECStatus(fec_enabled, pltype_red, + pltype_fec); if (fec_enabled) { RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.FecBitrateSentInKbps", static_cast(rtp_rtx.fec.TotalBytes() * @@ -359,210 +353,70 @@ int32_t ViEChannel::SetSendCodec(const VideoCodec& video_codec, // Update the RTP module with the settings. // Stop and Start the RTP module -> trigger new SSRC, if an SSRC hasn't been // set explicitly. - bool restart_rtp = false; + // The first layer is always active, so the first module can be checked for + // sending status. + bool is_sending = rtp_rtcp_modules_[0]->Sending(); bool router_was_active = send_payload_router_->active(); send_payload_router_->set_active(false); send_payload_router_->SetSendingRtpModules(std::list()); - packet_router_->RemoveRtpModule(rtp_rtcp_.get()); - for (RtpRtcp* module : simulcast_rtp_rtcp_) + for (RtpRtcp* module : rtp_rtcp_modules_) packet_router_->RemoveRtpModule(module); - if (rtp_rtcp_->Sending() && new_stream) { - restart_rtp = true; - rtp_rtcp_->SetSendingStatus(false); - for (std::list::iterator it = simulcast_rtp_rtcp_.begin(); - it != simulcast_rtp_rtcp_.end(); ++it) { - (*it)->SetSendingStatus(false); - (*it)->SetSendingMediaStatus(false); - } - } - - bool fec_enabled = false; - uint8_t payload_type_red; - uint8_t payload_type_fec; - rtp_rtcp_->GenericFECStatus(fec_enabled, payload_type_red, payload_type_fec); std::vector registered_modules; std::vector deregistered_modules; + size_t num_active_modules = video_codec.numberOfSimulcastStreams > 0 + ? video_codec.numberOfSimulcastStreams + : 1; + size_t num_prev_active_modules; { - CriticalSectionScoped cs(rtp_rtcp_cs_.get()); + // Cache which modules are active so StartSend can know which ones to start. + CriticalSectionScoped cs(crit_.get()); + num_prev_active_modules = num_active_rtp_rtcp_modules_; + num_active_rtp_rtcp_modules_ = num_active_modules; + } + for (size_t i = 0; i < num_active_modules; ++i) + registered_modules.push_back(rtp_rtcp_modules_[i]); - if (video_codec.numberOfSimulcastStreams > 0) { - // Set correct bitrate to base layer. - // Create our simulcast RTP modules. - int num_modules_to_add = video_codec.numberOfSimulcastStreams - - static_cast(simulcast_rtp_rtcp_.size()) - 1; - if (num_modules_to_add < 0) { - num_modules_to_add = 0; - } + for (size_t i = num_active_modules; i < rtp_rtcp_modules_.size(); ++i) + deregistered_modules.push_back(rtp_rtcp_modules_[i]); - // Add back removed rtp modules. Order is important (allocate from front - // of removed modules) to preserve RTP settings such as SSRCs for - // simulcast streams. - std::list new_rtp_modules; - for (; removed_rtp_rtcp_.size() > 0 && num_modules_to_add > 0; - --num_modules_to_add) { - new_rtp_modules.push_back(removed_rtp_rtcp_.front()); - removed_rtp_rtcp_.pop_front(); - } + // Disable inactive modules. + for (RtpRtcp* rtp_rtcp : deregistered_modules) { + rtp_rtcp->SetSendingStatus(false); + rtp_rtcp->SetSendingMediaStatus(false); + } - for (int i = 0; i < num_modules_to_add; ++i) - new_rtp_modules.push_back(CreateRtpRtcpModule()); - - // Initialize newly added modules. - for (std::list::iterator it = new_rtp_modules.begin(); - it != new_rtp_modules.end(); ++it) { - RtpRtcp* rtp_rtcp = *it; - - rtp_rtcp->SetRTCPStatus(rtp_rtcp_->RTCP()); - - if (rtp_rtcp_->StorePackets()) { - rtp_rtcp->SetStorePacketsStatus(true, nack_history_size_sender_); - } else if (paced_sender_) { - rtp_rtcp->SetStorePacketsStatus(true, nack_history_size_sender_); - } - - if (fec_enabled) { - rtp_rtcp->SetGenericFECStatus(fec_enabled, payload_type_red, - payload_type_fec); - } - rtp_rtcp->SetSendingStatus(rtp_rtcp_->Sending()); - rtp_rtcp->SetSendingMediaStatus(rtp_rtcp_->SendingMedia()); - std::pair payload_type_value = - rtp_rtcp_->RtxSendPayloadType(); - rtp_rtcp->SetRtxSendPayloadType(payload_type_value.first, - payload_type_value.second); - rtp_rtcp->SetRtxSendStatus(rtp_rtcp_->RtxSendStatus()); - simulcast_rtp_rtcp_.push_back(rtp_rtcp); - - // Silently ignore error. - registered_modules.push_back(rtp_rtcp); - } - - // Remove last in list if we have too many. - for (size_t j = simulcast_rtp_rtcp_.size(); - j > static_cast(video_codec.numberOfSimulcastStreams - 1); - j--) { - RtpRtcp* rtp_rtcp = simulcast_rtp_rtcp_.back(); - deregistered_modules.push_back(rtp_rtcp); - rtp_rtcp->SetSendingStatus(false); - rtp_rtcp->SetSendingMediaStatus(false); - rtp_rtcp->RegisterRtcpStatisticsCallback(NULL); - rtp_rtcp->RegisterSendChannelRtpStatisticsCallback(NULL); - simulcast_rtp_rtcp_.pop_back(); - removed_rtp_rtcp_.push_front(rtp_rtcp); - } - uint8_t idx = 0; - // Configure all simulcast modules. - for (std::list::iterator it = simulcast_rtp_rtcp_.begin(); - it != simulcast_rtp_rtcp_.end(); it++) { - idx++; - RtpRtcp* rtp_rtcp = *it; - rtp_rtcp->DeRegisterSendPayload(video_codec.plType); - if (rtp_rtcp->RegisterSendPayload(video_codec) != 0) { - return -1; - } - if (mtu_ != 0) { - rtp_rtcp->SetMaxTransferUnit(mtu_); - } - if (restart_rtp) { - rtp_rtcp->SetSendingStatus(true); - rtp_rtcp->SetSendingMediaStatus(true); - } - if (send_timestamp_extension_id_ != kInvalidRtpExtensionId) { - // Deregister in case the extension was previously enabled. - rtp_rtcp->DeregisterSendRtpHeaderExtension( - kRtpExtensionTransmissionTimeOffset); - if (rtp_rtcp->RegisterSendRtpHeaderExtension( - kRtpExtensionTransmissionTimeOffset, - send_timestamp_extension_id_) != 0) { - LOG(LS_WARNING) << "Register Transmission Time Offset failed"; - } - } else { - rtp_rtcp->DeregisterSendRtpHeaderExtension( - kRtpExtensionTransmissionTimeOffset); - } - if (absolute_send_time_extension_id_ != kInvalidRtpExtensionId) { - // Deregister in case the extension was previously enabled. - rtp_rtcp->DeregisterSendRtpHeaderExtension( - kRtpExtensionAbsoluteSendTime); - if (rtp_rtcp->RegisterSendRtpHeaderExtension( - kRtpExtensionAbsoluteSendTime, - absolute_send_time_extension_id_) != 0) { - LOG(LS_WARNING) << "Register Absolute Send Time failed"; - } - } else { - rtp_rtcp->DeregisterSendRtpHeaderExtension( - kRtpExtensionAbsoluteSendTime); - } - if (video_rotation_extension_id_ != kInvalidRtpExtensionId) { - // Deregister in case the extension was previously enabled. - rtp_rtcp->DeregisterSendRtpHeaderExtension( - kRtpExtensionVideoRotation); - if (rtp_rtcp->RegisterSendRtpHeaderExtension( - kRtpExtensionVideoRotation, video_rotation_extension_id_) != - 0) { - LOG(LS_WARNING) << "Register VideoRotation extension failed"; - } - } else { - rtp_rtcp->DeregisterSendRtpHeaderExtension( - kRtpExtensionVideoRotation); - } - rtp_rtcp->RegisterRtcpStatisticsCallback( - rtp_rtcp_->GetRtcpStatisticsCallback()); - rtp_rtcp->RegisterSendChannelRtpStatisticsCallback( - rtp_rtcp_->GetSendChannelRtpStatisticsCallback()); - } - // |RegisterSimulcastRtpRtcpModules| resets all old weak pointers and old - // modules can be deleted after this step. - vie_receiver_.RegisterSimulcastRtpRtcpModules(simulcast_rtp_rtcp_); - } else { - while (!simulcast_rtp_rtcp_.empty()) { - RtpRtcp* rtp_rtcp = simulcast_rtp_rtcp_.back(); - deregistered_modules.push_back(rtp_rtcp); - rtp_rtcp->SetSendingStatus(false); - rtp_rtcp->SetSendingMediaStatus(false); - rtp_rtcp->RegisterRtcpStatisticsCallback(NULL); - rtp_rtcp->RegisterSendChannelRtpStatisticsCallback(NULL); - simulcast_rtp_rtcp_.pop_back(); - removed_rtp_rtcp_.push_front(rtp_rtcp); - } - // Clear any previous modules. - vie_receiver_.RegisterSimulcastRtpRtcpModules(simulcast_rtp_rtcp_); - } - - // Don't log this error, no way to check in advance if this pl_type is - // registered or not... - rtp_rtcp_->DeRegisterSendPayload(video_codec.plType); - if (rtp_rtcp_->RegisterSendPayload(video_codec) != 0) { + // Configure active modules. + for (RtpRtcp* rtp_rtcp : registered_modules) { + rtp_rtcp->DeRegisterSendPayload(video_codec.plType); + if (rtp_rtcp->RegisterSendPayload(video_codec) != 0) { return -1; } - if (restart_rtp) { - rtp_rtcp_->SetSendingStatus(true); - for (std::list::iterator it = simulcast_rtp_rtcp_.begin(); - it != simulcast_rtp_rtcp_.end(); ++it) { - (*it)->SetSendingStatus(true); - (*it)->SetSendingMediaStatus(true); - } - } - // Update the packet and payload routers with the sending RTP RTCP modules. - packet_router_->AddRtpModule(rtp_rtcp_.get()); - for (RtpRtcp* module : simulcast_rtp_rtcp_) - packet_router_->AddRtpModule(module); - - std::list active_send_modules; - active_send_modules.push_back(rtp_rtcp_.get()); - for (std::list::const_iterator cit = simulcast_rtp_rtcp_.begin(); - cit != simulcast_rtp_rtcp_.end(); ++cit) { - active_send_modules.push_back(*cit); - } - send_payload_router_->SetSendingRtpModules(active_send_modules); - if (router_was_active) - send_payload_router_->set_active(true); + rtp_rtcp->SetSendingStatus(is_sending); + rtp_rtcp->SetSendingMediaStatus(is_sending); } - for (RtpRtcp* rtp_rtcp : registered_modules) - module_process_thread_.RegisterModule(rtp_rtcp); - for (RtpRtcp* rtp_rtcp : deregistered_modules) - module_process_thread_.DeRegisterModule(rtp_rtcp); + + // |RegisterSimulcastRtpRtcpModules| resets all old weak pointers and old + // modules can be deleted after this step. + vie_receiver_.RegisterRtpRtcpModules(registered_modules); + + // Update the packet and payload routers with the sending RtpRtcp modules. + std::list active_send_modules; + for (RtpRtcp* rtp_rtcp : registered_modules) { + packet_router_->AddRtpModule(rtp_rtcp); + active_send_modules.push_back(rtp_rtcp); + } + send_payload_router_->SetSendingRtpModules(active_send_modules); + + if (router_was_active) + send_payload_router_->set_active(true); + + // Deregister previously registered modules. + for (size_t i = num_active_modules; i < num_prev_active_modules; ++i) + module_process_thread_->DeRegisterModule(rtp_rtcp_modules_[i]); + // Register new active modules. + for (size_t i = num_prev_active_modules; i < num_active_modules; ++i) + module_process_thread_->RegisterModule(rtp_rtcp_modules_[i]); return 0; } @@ -575,8 +429,8 @@ int32_t ViEChannel::SetReceiveCodec(const VideoCodec& video_codec) { if (video_codec.codecType != kVideoCodecRED && video_codec.codecType != kVideoCodecULPFEC) { // Register codec type with VCM, but do not register RED or ULPFEC. - if (vcm_->RegisterReceiveCodec(&video_codec, number_of_cores_, - wait_for_key_frame_) != VCM_OK) { + if (vcm_->RegisterReceiveCodec(&video_codec, number_of_cores_, false) != + VCM_OK) { return -1; } } @@ -584,7 +438,7 @@ int32_t ViEChannel::SetReceiveCodec(const VideoCodec& video_codec) { } int32_t ViEChannel::RegisterCodecObserver(ViEDecoderObserver* observer) { - CriticalSectionScoped cs(callback_cs_.get()); + CriticalSectionScoped cs(crit_.get()); if (observer) { if (codec_observer_) { LOG_F(LS_ERROR) << "Observer already registered."; @@ -620,15 +474,15 @@ int32_t ViEChannel::DeRegisterExternalDecoder(const uint8_t pl_type) { } if (result == 0 && current_receive_codec.plType == pl_type) { - result = vcm_->RegisterReceiveCodec( - ¤t_receive_codec, number_of_cores_, wait_for_key_frame_); + result = vcm_->RegisterReceiveCodec(¤t_receive_codec, + number_of_cores_, false); } return result; } int32_t ViEChannel::ReceiveCodecStatistics(uint32_t* num_key_frames, uint32_t* num_delta_frames) { - CriticalSectionScoped cs(callback_cs_.get()); + CriticalSectionScoped cs(crit_.get()); *num_key_frames = receive_frame_counts_.key_frames; *num_delta_frames = receive_frame_counts_.delta_frames; return 0; @@ -642,11 +496,6 @@ int ViEChannel::ReceiveDelay() const { return vcm_->Delay(); } -int32_t ViEChannel::WaitForKeyFrame(bool wait) { - wait_for_key_frame_ = wait; - return 0; -} - int32_t ViEChannel::SetSignalPacketLossStatus(bool enable, bool only_key_frames) { if (enable) { @@ -669,14 +518,8 @@ int32_t ViEChannel::SetSignalPacketLossStatus(bool enable, } void ViEChannel::SetRTCPMode(const RTCPMethod rtcp_mode) { - CriticalSectionScoped cs(rtp_rtcp_cs_.get()); - for (std::list::iterator it = simulcast_rtp_rtcp_.begin(); - it != simulcast_rtp_rtcp_.end(); - it++) { - RtpRtcp* rtp_rtcp = *it; + for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) rtp_rtcp->SetRTCPStatus(rtcp_mode); - } - rtp_rtcp_->SetRTCPStatus(rtcp_mode); } int32_t ViEChannel::SetNACKStatus(const bool enable) { @@ -698,36 +541,22 @@ int32_t ViEChannel::SetNACKStatus(const bool enable) { int32_t ViEChannel::ProcessNACKRequest(const bool enable) { if (enable) { // Turn on NACK. - if (rtp_rtcp_->RTCP() == kRtcpOff) { + if (rtp_rtcp_modules_[0]->RTCP() == kRtcpOff) { return -1; } vie_receiver_.SetNackStatus(true, max_nack_reordering_threshold_); - rtp_rtcp_->SetStorePacketsStatus(true, nack_history_size_sender_); - vcm_->RegisterPacketRequestCallback(this); - CriticalSectionScoped cs(rtp_rtcp_cs_.get()); - - for (std::list::iterator it = simulcast_rtp_rtcp_.begin(); - it != simulcast_rtp_rtcp_.end(); - it++) { - RtpRtcp* rtp_rtcp = *it; + for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) rtp_rtcp->SetStorePacketsStatus(true, nack_history_size_sender_); - } + + vcm_->RegisterPacketRequestCallback(this); // Don't introduce errors when NACK is enabled. vcm_->SetDecodeErrorMode(kNoErrors); } else { - CriticalSectionScoped cs(rtp_rtcp_cs_.get()); - for (std::list::iterator it = simulcast_rtp_rtcp_.begin(); - it != simulcast_rtp_rtcp_.end(); - it++) { - RtpRtcp* rtp_rtcp = *it; - if (paced_sender_ == NULL) { - rtp_rtcp->SetStorePacketsStatus(false, 0); - } - } vcm_->RegisterPacketRequestCallback(NULL); - if (paced_sender_ == NULL) { - rtp_rtcp_->SetStorePacketsStatus(false, 0); + if (paced_sender_ == nullptr) { + for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) + rtp_rtcp->SetStorePacketsStatus(false, 0); } vie_receiver_.SetNackStatus(false, max_nack_reordering_threshold_); // When NACK is off, allow decoding with errors. Otherwise, the video @@ -752,13 +581,9 @@ bool ViEChannel::IsSendingFecEnabled() { bool fec_enabled = false; uint8_t pltype_red = 0; uint8_t pltype_fec = 0; - rtp_rtcp_->GenericFECStatus(fec_enabled, pltype_red, pltype_fec); - if (fec_enabled) - return true; - CriticalSectionScoped cs(rtp_rtcp_cs_.get()); - for (auto* module : simulcast_rtp_rtcp_) { - module->GenericFECStatus(fec_enabled, pltype_red, pltype_fec); + for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { + rtp_rtcp->GenericFECStatus(fec_enabled, pltype_red, pltype_fec); if (fec_enabled) return true; } @@ -769,17 +594,8 @@ int32_t ViEChannel::ProcessFECRequest( const bool enable, const unsigned char payload_typeRED, const unsigned char payload_typeFEC) { - if (rtp_rtcp_->SetGenericFECStatus(enable, payload_typeRED, - payload_typeFEC) != 0) { - return -1; - } - CriticalSectionScoped cs(rtp_rtcp_cs_.get()); - for (std::list::iterator it = simulcast_rtp_rtcp_.begin(); - it != simulcast_rtp_rtcp_.end(); - it++) { - RtpRtcp* rtp_rtcp = *it; + for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) rtp_rtcp->SetGenericFECStatus(enable, payload_typeRED, payload_typeFEC); - } return 0; } @@ -814,7 +630,8 @@ int ViEChannel::SetSenderBufferingMode(int target_delay_ms) { nack_history_size_sender_ = kSendSidePacketHistorySize; } } - rtp_rtcp_->SetStorePacketsStatus(true, nack_history_size_sender_); + for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) + rtp_rtcp->SetStorePacketsStatus(true, nack_history_size_sender_); return 0; } @@ -854,40 +671,26 @@ int ViEChannel::GetRequiredNackListSize(int target_delay_ms) { int32_t ViEChannel::SetKeyFrameRequestMethod( const KeyFrameRequestMethod method) { - return rtp_rtcp_->SetKeyFrameRequestMethod(method); + return rtp_rtcp_modules_[0]->SetKeyFrameRequestMethod(method); } void ViEChannel::EnableRemb(bool enable) { - rtp_rtcp_->SetREMBStatus(enable); + rtp_rtcp_modules_[0]->SetREMBStatus(enable); } int ViEChannel::SetSendTimestampOffsetStatus(bool enable, int id) { - CriticalSectionScoped cs(rtp_rtcp_cs_.get()); + // Disable any previous registrations of this extension to avoid errors. + for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { + rtp_rtcp->DeregisterSendRtpHeaderExtension( + kRtpExtensionTransmissionTimeOffset); + } + if (!enable) + return 0; + // Enable the extension. int error = 0; - if (enable) { - // Enable the extension, but disable possible old id to avoid errors. - send_timestamp_extension_id_ = id; - rtp_rtcp_->DeregisterSendRtpHeaderExtension( - kRtpExtensionTransmissionTimeOffset); - error = rtp_rtcp_->RegisterSendRtpHeaderExtension( + for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { + error |= rtp_rtcp->RegisterSendRtpHeaderExtension( kRtpExtensionTransmissionTimeOffset, id); - for (std::list::iterator it = simulcast_rtp_rtcp_.begin(); - it != simulcast_rtp_rtcp_.end(); it++) { - (*it)->DeregisterSendRtpHeaderExtension( - kRtpExtensionTransmissionTimeOffset); - error |= (*it)->RegisterSendRtpHeaderExtension( - kRtpExtensionTransmissionTimeOffset, id); - } - } else { - // Disable the extension. - send_timestamp_extension_id_ = kInvalidRtpExtensionId; - rtp_rtcp_->DeregisterSendRtpHeaderExtension( - kRtpExtensionTransmissionTimeOffset); - for (std::list::iterator it = simulcast_rtp_rtcp_.begin(); - it != simulcast_rtp_rtcp_.end(); it++) { - (*it)->DeregisterSendRtpHeaderExtension( - kRtpExtensionTransmissionTimeOffset); - } } return error; } @@ -897,32 +700,16 @@ int ViEChannel::SetReceiveTimestampOffsetStatus(bool enable, int id) { } int ViEChannel::SetSendAbsoluteSendTimeStatus(bool enable, int id) { - CriticalSectionScoped cs(rtp_rtcp_cs_.get()); + // Disable any previous registrations of this extension to avoid errors. + for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) + rtp_rtcp->DeregisterSendRtpHeaderExtension(kRtpExtensionAbsoluteSendTime); + if (!enable) + return 0; + // Enable the extension. int error = 0; - if (enable) { - // Enable the extension, but disable possible old id to avoid errors. - absolute_send_time_extension_id_ = id; - rtp_rtcp_->DeregisterSendRtpHeaderExtension( - kRtpExtensionAbsoluteSendTime); - error = rtp_rtcp_->RegisterSendRtpHeaderExtension( + for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { + error |= rtp_rtcp->RegisterSendRtpHeaderExtension( kRtpExtensionAbsoluteSendTime, id); - for (std::list::iterator it = simulcast_rtp_rtcp_.begin(); - it != simulcast_rtp_rtcp_.end(); it++) { - (*it)->DeregisterSendRtpHeaderExtension( - kRtpExtensionAbsoluteSendTime); - error |= (*it)->RegisterSendRtpHeaderExtension( - kRtpExtensionAbsoluteSendTime, id); - } - } else { - // Disable the extension. - absolute_send_time_extension_id_ = kInvalidRtpExtensionId; - rtp_rtcp_->DeregisterSendRtpHeaderExtension( - kRtpExtensionAbsoluteSendTime); - for (std::list::iterator it = simulcast_rtp_rtcp_.begin(); - it != simulcast_rtp_rtcp_.end(); it++) { - (*it)->DeregisterSendRtpHeaderExtension( - kRtpExtensionAbsoluteSendTime); - } } return error; } @@ -932,28 +719,16 @@ int ViEChannel::SetReceiveAbsoluteSendTimeStatus(bool enable, int id) { } int ViEChannel::SetSendVideoRotationStatus(bool enable, int id) { - CriticalSectionScoped cs(rtp_rtcp_cs_.get()); + // Disable any previous registrations of this extension to avoid errors. + for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) + rtp_rtcp->DeregisterSendRtpHeaderExtension(kRtpExtensionVideoRotation); + if (!enable) + return 0; + // Enable the extension. int error = 0; - if (enable) { - // Enable the extension, but disable possible old id to avoid errors. - video_rotation_extension_id_ = id; - rtp_rtcp_->DeregisterSendRtpHeaderExtension(kRtpExtensionVideoRotation); - error = rtp_rtcp_->RegisterSendRtpHeaderExtension( + for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { + error |= rtp_rtcp->RegisterSendRtpHeaderExtension( kRtpExtensionVideoRotation, id); - for (std::list::iterator it = simulcast_rtp_rtcp_.begin(); - it != simulcast_rtp_rtcp_.end(); it++) { - (*it)->DeregisterSendRtpHeaderExtension(kRtpExtensionVideoRotation); - error |= - (*it)->RegisterSendRtpHeaderExtension(kRtpExtensionVideoRotation, id); - } - } else { - // Disable the extension. - video_rotation_extension_id_ = kInvalidRtpExtensionId; - rtp_rtcp_->DeregisterSendRtpHeaderExtension(kRtpExtensionVideoRotation); - for (std::list::iterator it = simulcast_rtp_rtcp_.begin(); - it != simulcast_rtp_rtcp_.end(); it++) { - (*it)->DeregisterSendRtpHeaderExtension(kRtpExtensionVideoRotation); - } } return error; } @@ -963,37 +738,22 @@ int ViEChannel::SetReceiveVideoRotationStatus(bool enable, int id) { } void ViEChannel::SetRtcpXrRrtrStatus(bool enable) { - CriticalSectionScoped cs(rtp_rtcp_cs_.get()); - rtp_rtcp_->SetRtcpXrRrtrStatus(enable); + rtp_rtcp_modules_[0]->SetRtcpXrRrtrStatus(enable); } void ViEChannel::SetTransmissionSmoothingStatus(bool enable) { - assert(paced_sender_ && "No paced sender registered."); + DCHECK(paced_sender_ && "No paced sender registered."); paced_sender_->SetStatus(enable); } void ViEChannel::EnableTMMBR(bool enable) { - rtp_rtcp_->SetTMMBRStatus(enable); -} - -int32_t ViEChannel::EnableKeyFrameRequestCallback(const bool enable) { - CriticalSectionScoped cs(callback_cs_.get()); - if (enable && !codec_observer_) { - LOG(LS_ERROR) << "No ViECodecObserver set."; - return -1; - } - do_key_frame_callbackRequest_ = enable; - return 0; + rtp_rtcp_modules_[0]->SetTMMBRStatus(enable); } int32_t ViEChannel::SetSSRC(const uint32_t SSRC, const StreamType usage, const uint8_t simulcast_idx) { - CriticalSectionScoped cs(rtp_rtcp_cs_.get()); - ReserveRtpRtcpModules(simulcast_idx + 1); - RtpRtcp* rtp_rtcp = GetRtpRtcpModule(simulcast_idx); - if (rtp_rtcp == NULL) - return -1; + RtpRtcp* rtp_rtcp = rtp_rtcp_modules_[simulcast_idx]; if (usage == kViEStreamTypeRtx) { rtp_rtcp->SetRtxSsrc(SSRC); } else { @@ -1009,11 +769,8 @@ int32_t ViEChannel::SetRemoteSSRCType(const StreamType usage, } int32_t ViEChannel::GetLocalSSRC(uint8_t idx, unsigned int* ssrc) { - CriticalSectionScoped cs(rtp_rtcp_cs_.get()); - RtpRtcp* rtp_rtcp = GetRtpRtcpModule(idx); - if (rtp_rtcp == NULL) - return -1; - *ssrc = rtp_rtcp->SSRC(); + DCHECK_LE(idx, rtp_rtcp_modules_.size()); + *ssrc = rtp_rtcp_modules_[idx]->SSRC(); return 0; } @@ -1024,12 +781,8 @@ int32_t ViEChannel::GetRemoteSSRC(uint32_t* ssrc) { int ViEChannel::SetRtxSendPayloadType(int payload_type, int associated_payload_type) { - rtp_rtcp_->SetRtxSendPayloadType(payload_type, associated_payload_type); - CriticalSectionScoped cs(rtp_rtcp_cs_.get()); - for (std::list::iterator it = simulcast_rtp_rtcp_.begin(); - it != simulcast_rtp_rtcp_.end(); it++) { - (*it)->SetRtxSendPayloadType(payload_type, associated_payload_type); - } + for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) + rtp_rtcp->SetRtxSendPayloadType(payload_type, associated_payload_type); SetRtxSendStatus(true); return 0; } @@ -1037,12 +790,8 @@ int ViEChannel::SetRtxSendPayloadType(int payload_type, void ViEChannel::SetRtxSendStatus(bool enable) { int rtx_settings = enable ? kRtxRetransmitted | kRtxRedundantPayloads : kRtxOff; - rtp_rtcp_->SetRtxSendStatus(rtx_settings); - CriticalSectionScoped cs(rtp_rtcp_cs_.get()); - for (std::list::iterator it = simulcast_rtp_rtcp_.begin(); - it != simulcast_rtp_rtcp_.end(); it++) { - (*it)->SetRtxSendStatus(rtx_settings); - } + for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) + rtp_rtcp->SetRtxSendStatus(rtx_settings); } void ViEChannel::SetRtxReceivePayloadType(int payload_type, @@ -1050,88 +799,34 @@ void ViEChannel::SetRtxReceivePayloadType(int payload_type, vie_receiver_.SetRtxPayloadType(payload_type, associated_payload_type); } -int32_t ViEChannel::SetStartSequenceNumber(uint16_t sequence_number) { - if (rtp_rtcp_->Sending()) { - return -1; - } - rtp_rtcp_->SetSequenceNumber(sequence_number); - return 0; -} - void ViEChannel::SetRtpStateForSsrc(uint32_t ssrc, const RtpState& rtp_state) { - assert(!rtp_rtcp_->Sending()); - if (rtp_rtcp_->SetRtpStateForSsrc(ssrc, rtp_state)) - return; - CriticalSectionScoped cs(rtp_rtcp_cs_.get()); - for (auto* module : simulcast_rtp_rtcp_) { - if (module->SetRtpStateForSsrc(ssrc, rtp_state)) - return; - } - for (auto* module : removed_rtp_rtcp_) { - if (module->SetRtpStateForSsrc(ssrc, rtp_state)) + DCHECK(!rtp_rtcp_modules_[0]->Sending()); + for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { + if (rtp_rtcp->SetRtpStateForSsrc(ssrc, rtp_state)) return; } } RtpState ViEChannel::GetRtpStateForSsrc(uint32_t ssrc) { - assert(!rtp_rtcp_->Sending()); - + DCHECK(!rtp_rtcp_modules_[0]->Sending()); RtpState rtp_state; - if (rtp_rtcp_->GetRtpStateForSsrc(ssrc, &rtp_state)) - return rtp_state; - - CriticalSectionScoped cs(rtp_rtcp_cs_.get()); - for (auto* module : simulcast_rtp_rtcp_) { - if (module->GetRtpStateForSsrc(ssrc, &rtp_state)) - return rtp_state; - } - for (auto* module : removed_rtp_rtcp_) { - if (module->GetRtpStateForSsrc(ssrc, &rtp_state)) + for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { + if (rtp_rtcp->GetRtpStateForSsrc(ssrc, &rtp_state)) return rtp_state; } LOG(LS_ERROR) << "Couldn't get RTP state for ssrc: " << ssrc; return rtp_state; } +// TODO(pbos): Set CNAME on all modules. int32_t ViEChannel::SetRTCPCName(const char* rtcp_cname) { - if (rtp_rtcp_->Sending()) { - return -1; - } - return rtp_rtcp_->SetCNAME(rtcp_cname); + DCHECK(!rtp_rtcp_modules_[0]->Sending()); + return rtp_rtcp_modules_[0]->SetCNAME(rtcp_cname); } int32_t ViEChannel::GetRemoteRTCPCName(char rtcp_cname[]) { uint32_t remoteSSRC = vie_receiver_.GetRemoteSsrc(); - return rtp_rtcp_->RemoteCNAME(remoteSSRC, rtcp_cname); -} - -int32_t ViEChannel::SendApplicationDefinedRTCPPacket( - const uint8_t sub_type, - uint32_t name, - const uint8_t* data, - uint16_t data_length_in_bytes) { - if (!rtp_rtcp_->Sending()) { - return -1; - } - if (!data) { - LOG_F(LS_ERROR) << "Invalid input."; - return -1; - } - if (data_length_in_bytes % 4 != 0) { - LOG(LS_ERROR) << "Invalid input length."; - return -1; - } - RTCPMethod rtcp_method = rtp_rtcp_->RTCP(); - if (rtcp_method == kRtcpOff) { - LOG_F(LS_ERROR) << "RTCP not enable."; - return -1; - } - // Create and send packet. - if (rtp_rtcp_->SetRTCPApplicationSpecificData(sub_type, name, data, - data_length_in_bytes) != 0) { - return -1; - } - return 0; + return rtp_rtcp_modules_[0]->RemoteCNAME(remoteSSRC, rtcp_cname); } int32_t ViEChannel::GetSendRtcpStatistics(uint16_t* fraction_lost, @@ -1141,15 +836,8 @@ int32_t ViEChannel::GetSendRtcpStatistics(uint16_t* fraction_lost, int64_t* rtt_ms) { // Aggregate the report blocks associated with streams sent on this channel. std::vector report_blocks; - rtp_rtcp_->RemoteRTCPStat(&report_blocks); - { - CriticalSectionScoped lock(rtp_rtcp_cs_.get()); - for (std::list::iterator it = simulcast_rtp_rtcp_.begin(); - it != simulcast_rtp_rtcp_.end(); - ++it) { - (*it)->RemoteRTCPStat(&report_blocks); - } - } + for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) + rtp_rtcp->RemoteRTCPStat(&report_blocks); if (report_blocks.empty()) return -1; @@ -1180,7 +868,8 @@ int32_t ViEChannel::GetSendRtcpStatistics(uint16_t* fraction_lost, int64_t dummy; int64_t rtt = 0; - if (rtp_rtcp_->RTT(remote_ssrc, &rtt, &dummy, &dummy, &dummy) != 0) { + if (rtp_rtcp_modules_[0]->RTT(remote_ssrc, &rtt, &dummy, &dummy, &dummy) != + 0) { return -1; } *rtt_ms = rtt; @@ -1189,20 +878,15 @@ int32_t ViEChannel::GetSendRtcpStatistics(uint16_t* fraction_lost, void ViEChannel::RegisterSendChannelRtcpStatisticsCallback( RtcpStatisticsCallback* callback) { - rtp_rtcp_->RegisterRtcpStatisticsCallback(callback); - CriticalSectionScoped cs(rtp_rtcp_cs_.get()); - for (std::list::const_iterator it = simulcast_rtp_rtcp_.begin(); - it != simulcast_rtp_rtcp_.end(); - ++it) { - (*it)->RegisterRtcpStatisticsCallback(callback); - } + for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) + rtp_rtcp->RegisterRtcpStatisticsCallback(callback); } void ViEChannel::RegisterReceiveChannelRtcpStatisticsCallback( RtcpStatisticsCallback* callback) { vie_receiver_.GetReceiveStatistics()->RegisterRtcpStatisticsCallback( callback); - rtp_rtcp_->RegisterRtcpStatisticsCallback(callback); + rtp_rtcp_modules_[0]->RegisterRtcpStatisticsCallback(callback); } void ViEChannel::RegisterRtcpPacketTypeCounterObserver( @@ -1213,22 +897,12 @@ void ViEChannel::RegisterRtcpPacketTypeCounterObserver( void ViEChannel::GetSendStreamDataCounters( StreamDataCounters* rtp_counters, StreamDataCounters* rtx_counters) const { - rtp_rtcp_->GetSendStreamDataCounters(rtp_counters, rtx_counters); - CriticalSectionScoped cs(rtp_rtcp_cs_.get()); - for (std::list::const_iterator it = simulcast_rtp_rtcp_.begin(); - it != simulcast_rtp_rtcp_.end(); - it++) { + *rtp_counters = StreamDataCounters(); + *rtx_counters = StreamDataCounters(); + for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { StreamDataCounters rtp_data; StreamDataCounters rtx_data; - (*it)->GetSendStreamDataCounters(&rtp_data, &rtx_data); - rtp_counters->Add(rtp_data); - rtx_counters->Add(rtx_data); - } - for (std::list::const_iterator it = removed_rtp_rtcp_.begin(); - it != removed_rtp_rtcp_.end(); ++it) { - StreamDataCounters rtp_data; - StreamDataCounters rtx_data; - (*it)->GetSendStreamDataCounters(&rtp_data, &rtx_data); + rtp_rtcp->GetSendStreamDataCounters(&rtp_data, &rtx_data); rtp_counters->Add(rtp_data); rtx_counters->Add(rtx_data); } @@ -1254,15 +928,8 @@ void ViEChannel::GetReceiveStreamDataCounters( void ViEChannel::RegisterSendChannelRtpStatisticsCallback( StreamDataCountersCallback* callback) { - rtp_rtcp_->RegisterSendChannelRtpStatisticsCallback(callback); - { - CriticalSectionScoped cs(rtp_rtcp_cs_.get()); - for (std::list::iterator it = simulcast_rtp_rtcp_.begin(); - it != simulcast_rtp_rtcp_.end(); - it++) { - (*it)->RegisterSendChannelRtpStatisticsCallback(callback); - } - } + for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) + rtp_rtcp->RegisterSendChannelRtpStatisticsCallback(callback); } void ViEChannel::RegisterReceiveChannelRtpStatisticsCallback( @@ -1276,17 +943,8 @@ void ViEChannel::GetSendRtcpPacketTypeCounter( rtcp_packet_type_counter_observer_.GetPacketTypeCounterMap(); RtcpPacketTypeCounter counter; - counter.Add(counter_map[rtp_rtcp_->SSRC()]); - - CriticalSectionScoped cs(rtp_rtcp_cs_.get()); - for (std::list::const_iterator it = simulcast_rtp_rtcp_.begin(); - it != simulcast_rtp_rtcp_.end(); ++it) { - counter.Add(counter_map[(*it)->SSRC()]); - } - for (std::list::const_iterator it = removed_rtp_rtcp_.begin(); - it != removed_rtp_rtcp_.end(); ++it) { - counter.Add(counter_map[(*it)->SSRC()]); - } + for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) + counter.Add(counter_map[rtp_rtcp->SSRC()]); *packet_counter = counter; } @@ -1312,20 +970,13 @@ void ViEChannel::RegisterSendBitrateObserver( } int32_t ViEChannel::StartSend() { - CriticalSectionScoped cs(callback_cs_.get()); - rtp_rtcp_->SetSendingMediaStatus(true); + CriticalSectionScoped cs(crit_.get()); - if (rtp_rtcp_->Sending()) { + if (rtp_rtcp_modules_[0]->Sending()) return -1; - } - if (rtp_rtcp_->SetSendingStatus(true) != 0) { - return -1; - } - CriticalSectionScoped cs_rtp(rtp_rtcp_cs_.get()); - for (std::list::const_iterator it = simulcast_rtp_rtcp_.begin(); - it != simulcast_rtp_rtcp_.end(); - it++) { - RtpRtcp* rtp_rtcp = *it; + + for (size_t i = 0; i < num_active_rtp_rtcp_modules_; ++i) { + RtpRtcp* rtp_rtcp = rtp_rtcp_modules_[i]; rtp_rtcp->SetSendingMediaStatus(true); rtp_rtcp->SetSendingStatus(true); } @@ -1335,32 +986,21 @@ int32_t ViEChannel::StartSend() { int32_t ViEChannel::StopSend() { send_payload_router_->set_active(false); - CriticalSectionScoped cs(rtp_rtcp_cs_.get()); - rtp_rtcp_->SetSendingMediaStatus(false); - for (std::list::iterator it = simulcast_rtp_rtcp_.begin(); - it != simulcast_rtp_rtcp_.end(); - it++) { - RtpRtcp* rtp_rtcp = *it; + for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) rtp_rtcp->SetSendingMediaStatus(false); - } - if (!rtp_rtcp_->Sending()) { + + if (!rtp_rtcp_modules_[0]->Sending()) { return -1; } - if (rtp_rtcp_->SetSendingStatus(false) != 0) { - return -1; - } - for (std::list::iterator it = simulcast_rtp_rtcp_.begin(); - it != simulcast_rtp_rtcp_.end(); - it++) { - RtpRtcp* rtp_rtcp = *it; + for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { rtp_rtcp->SetSendingStatus(false); } return 0; } bool ViEChannel::Sending() { - return rtp_rtcp_->Sending(); + return rtp_rtcp_modules_[0]->Sending(); } void ViEChannel::StartReceive() { @@ -1390,26 +1030,13 @@ int32_t ViEChannel::ReceivedRTCPPacket(const void* rtcp_packet, } int32_t ViEChannel::SetMTU(uint16_t mtu) { - if (rtp_rtcp_->SetMaxTransferUnit(mtu) != 0) { - return -1; - } - CriticalSectionScoped cs(rtp_rtcp_cs_.get()); - for (std::list::iterator it = simulcast_rtp_rtcp_.begin(); - it != simulcast_rtp_rtcp_.end(); - it++) { - RtpRtcp* rtp_rtcp = *it; + for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) rtp_rtcp->SetMaxTransferUnit(mtu); - } - mtu_ = mtu; return 0; } -uint16_t ViEChannel::MaxDataPayloadLength() const { - return rtp_rtcp_->MaxDataPayloadLength(); -} - RtpRtcp* ViEChannel::rtp_rtcp() { - return rtp_rtcp_.get(); + return rtp_rtcp_modules_[0]; } rtc::scoped_refptr ViEChannel::send_payload_router() { @@ -1429,7 +1056,7 @@ CallStatsObserver* ViEChannel::GetStatsObserver() { // held the lock when calling VideoDecoder::Decode, Reset, or Release. Acquiring // the same lock in the path of decode callback can deadlock. int32_t ViEChannel::FrameToRender(VideoFrame& video_frame) { // NOLINT - CriticalSectionScoped cs(callback_cs_.get()); + CriticalSectionScoped cs(crit_.get()); if (decoder_reset_) { // Trigger a callback to the user if the incoming codec has changed. @@ -1452,28 +1079,28 @@ int32_t ViEChannel::FrameToRender(VideoFrame& video_frame) { // NOLINT int32_t ViEChannel::ReceivedDecodedReferenceFrame( const uint64_t picture_id) { - return rtp_rtcp_->SendRTCPReferencePictureSelection(picture_id); + return rtp_rtcp_modules_[0]->SendRTCPReferencePictureSelection(picture_id); } void ViEChannel::IncomingCodecChanged(const VideoCodec& codec) { - CriticalSectionScoped cs(callback_cs_.get()); + CriticalSectionScoped cs(crit_.get()); receive_codec_ = codec; } void ViEChannel::OnReceiveRatesUpdated(uint32_t bit_rate, uint32_t frame_rate) { - CriticalSectionScoped cs(callback_cs_.get()); + CriticalSectionScoped cs(crit_.get()); if (codec_observer_) codec_observer_->IncomingRate(channel_id_, frame_rate, bit_rate); } void ViEChannel::OnDiscardedPacketsUpdated(int discarded_packets) { - CriticalSectionScoped cs(callback_cs_.get()); + CriticalSectionScoped cs(crit_.get()); if (vcm_receive_stats_callback_ != NULL) vcm_receive_stats_callback_->OnDiscardedPacketsUpdated(discarded_packets); } void ViEChannel::OnFrameCountsUpdated(const FrameCounts& frame_counts) { - CriticalSectionScoped cs(callback_cs_.get()); + CriticalSectionScoped cs(crit_.get()); receive_frame_counts_ = frame_counts; if (vcm_receive_stats_callback_ != NULL) vcm_receive_stats_callback_->OnFrameCountsUpdated(frame_counts); @@ -1486,7 +1113,7 @@ void ViEChannel::OnDecoderTiming(int decode_ms, int jitter_buffer_ms, int min_playout_delay_ms, int render_delay_ms) { - CriticalSectionScoped cs(callback_cs_.get()); + CriticalSectionScoped cs(crit_.get()); if (!codec_observer_) return; codec_observer_->DecoderTiming(decode_ms, @@ -1499,23 +1126,18 @@ void ViEChannel::OnDecoderTiming(int decode_ms, } int32_t ViEChannel::RequestKeyFrame() { - { - CriticalSectionScoped cs(callback_cs_.get()); - if (codec_observer_ && do_key_frame_callbackRequest_) { - codec_observer_->RequestNewKeyFrame(channel_id_); - } - } - return rtp_rtcp_->RequestKeyFrame(); + return rtp_rtcp_modules_[0]->RequestKeyFrame(); } int32_t ViEChannel::SliceLossIndicationRequest( const uint64_t picture_id) { - return rtp_rtcp_->SendRTCPSliceLossIndication((uint8_t) picture_id); + return rtp_rtcp_modules_[0]->SendRTCPSliceLossIndication( + static_cast(picture_id)); } int32_t ViEChannel::ResendPackets(const uint16_t* sequence_numbers, - uint16_t length) { - return rtp_rtcp_->SendNACK(sequence_numbers, length); + uint16_t length) { + return rtp_rtcp_modules_[0]->SendNACK(sequence_numbers, length); } bool ViEChannel::ChannelDecodeThreadFunction(void* obj) { @@ -1536,87 +1158,70 @@ int ViEChannel::ProtectionRequest(const FecProtectionParams* delta_fec_params, uint32_t* video_rate_bps, uint32_t* nack_rate_bps, uint32_t* fec_rate_bps) { - uint32_t not_used = 0; - rtp_rtcp_->SetFecParameters(delta_fec_params, key_fec_params); - rtp_rtcp_->BitrateSent(¬_used, video_rate_bps, fec_rate_bps, - nack_rate_bps); - CriticalSectionScoped cs(rtp_rtcp_cs_.get()); - for (auto* module : simulcast_rtp_rtcp_) { - uint32_t child_video_rate = 0; - uint32_t child_fec_rate = 0; - uint32_t child_nack_rate = 0; - module->SetFecParameters(delta_fec_params, key_fec_params); - module->BitrateSent(¬_used, &child_video_rate, &child_fec_rate, - &child_nack_rate); - *video_rate_bps += child_video_rate; - *nack_rate_bps += child_nack_rate; - *fec_rate_bps += child_fec_rate; + *video_rate_bps = 0; + *nack_rate_bps = 0; + *fec_rate_bps = 0; + for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { + uint32_t not_used = 0; + uint32_t module_video_rate = 0; + uint32_t module_fec_rate = 0; + uint32_t module_nack_rate = 0; + rtp_rtcp->SetFecParameters(delta_fec_params, key_fec_params); + rtp_rtcp->BitrateSent(¬_used, &module_video_rate, &module_fec_rate, + &module_nack_rate); + *video_rate_bps += module_video_rate; + *nack_rate_bps += module_nack_rate; + *fec_rate_bps += module_fec_rate; } return 0; } -void ViEChannel::ReserveRtpRtcpModules(size_t num_modules) { - for (size_t total_modules = - 1 + simulcast_rtp_rtcp_.size() + removed_rtp_rtcp_.size(); - total_modules < num_modules; - ++total_modules) { - RtpRtcp* rtp_rtcp = CreateRtpRtcpModule(); +std::vector ViEChannel::CreateRtpRtcpModules( + int32_t id, + bool receiver_only, + ReceiveStatistics* receive_statistics, + Transport* outgoing_transport, + RtcpIntraFrameObserver* intra_frame_callback, + RtcpBandwidthObserver* bandwidth_callback, + RtcpRttStats* rtt_stats, + RtcpPacketTypeCounterObserver* rtcp_packet_type_counter_observer, + RemoteBitrateEstimator* remote_bitrate_estimator, + PacedSender* paced_sender, + BitrateStatisticsObserver* send_bitrate_observer, + FrameCountObserver* send_frame_count_observer, + SendSideDelayObserver* send_side_delay_observer, + size_t num_modules) { + DCHECK_GT(num_modules, 0u); + RtpRtcp::Configuration configuration; + ReceiveStatistics* null_receive_statistics = configuration.receive_statistics; + configuration.id = id; + configuration.audio = false; + configuration.receiver_only = receiver_only; + configuration.receive_statistics = receive_statistics; + configuration.outgoing_transport = outgoing_transport; + configuration.intra_frame_callback = intra_frame_callback; + configuration.rtt_stats = rtt_stats; + configuration.rtcp_packet_type_counter_observer = + rtcp_packet_type_counter_observer; + configuration.paced_sender = paced_sender; + configuration.send_bitrate_observer = send_bitrate_observer; + configuration.send_frame_count_observer = send_frame_count_observer; + configuration.send_side_delay_observer = send_side_delay_observer; + configuration.bandwidth_callback = bandwidth_callback; + + std::vector modules; + for (size_t i = 0; i < num_modules; ++i) { + RtpRtcp* rtp_rtcp = RtpRtcp::CreateRtpRtcp(configuration); rtp_rtcp->SetSendingStatus(false); rtp_rtcp->SetSendingMediaStatus(false); - rtp_rtcp->RegisterRtcpStatisticsCallback(NULL); - rtp_rtcp->RegisterSendChannelRtpStatisticsCallback(NULL); - removed_rtp_rtcp_.push_back(rtp_rtcp); + rtp_rtcp->SetRTCPStatus(kRtcpCompound); + modules.push_back(rtp_rtcp); + // Receive statistics and remote bitrate estimator should only be set for + // the primary (first) module. + configuration.receive_statistics = null_receive_statistics; + configuration.remote_bitrate_estimator = nullptr; } -} - -RtpRtcp* ViEChannel::GetRtpRtcpModule(size_t index) const { - if (index == 0) - return rtp_rtcp_.get(); - if (index <= simulcast_rtp_rtcp_.size()) { - std::list::const_iterator it = simulcast_rtp_rtcp_.begin(); - for (size_t i = 1; i < index; ++i) { - ++it; - } - return *it; - } - - // If the requested module exists it must be in the removed list. Index - // translation to this list must remove the default module as well as all - // active simulcast modules. - size_t removed_idx = index - simulcast_rtp_rtcp_.size() - 1; - if (removed_idx >= removed_rtp_rtcp_.size()) - return NULL; - - std::list::const_iterator it = removed_rtp_rtcp_.begin(); - while (removed_idx-- > 0) - ++it; - - return *it; -} - -RtpRtcp::Configuration ViEChannel::CreateRtpRtcpConfiguration() { - RtpRtcp::Configuration configuration; - configuration.id = ViEModuleId(engine_id_, channel_id_); - configuration.audio = false; - configuration.receiver_only = !sender_; - configuration.outgoing_transport = transport_; - if (sender_) - configuration.intra_frame_callback = intra_frame_observer_; - configuration.rtt_stats = rtt_stats_; - configuration.rtcp_packet_type_counter_observer = - &rtcp_packet_type_counter_observer_; - configuration.paced_sender = paced_sender_; - configuration.send_bitrate_observer = &send_bitrate_observer_; - configuration.send_frame_count_observer = &send_frame_count_observer_; - configuration.send_side_delay_observer = &send_side_delay_observer_; - if (sender_) - configuration.bandwidth_callback = bandwidth_observer_.get(); - - return configuration; -} - -RtpRtcp* ViEChannel::CreateRtpRtcpModule() { - return RtpRtcp::CreateRtpRtcp(CreateRtpRtcpConfiguration()); + return modules; } void ViEChannel::StartDecodeThread() { @@ -1642,9 +1247,8 @@ void ViEChannel::StopDecodeThread() { int32_t ViEChannel::SetVoiceChannel(int32_t ve_channel_id, VoEVideoSync* ve_sync_interface) { - return vie_sync_.ConfigureSync(ve_channel_id, - ve_sync_interface, - rtp_rtcp_.get(), + return vie_sync_.ConfigureSync(ve_channel_id, ve_sync_interface, + rtp_rtcp_modules_[0], vie_receiver_.GetRtpReceiver()); } @@ -1654,7 +1258,7 @@ int32_t ViEChannel::VoiceChannel() { void ViEChannel::RegisterPreRenderCallback( I420FrameCallback* pre_render_callback) { - CriticalSectionScoped cs(callback_cs_.get()); + CriticalSectionScoped cs(crit_.get()); pre_render_callback_ = pre_render_callback; } @@ -1674,22 +1278,21 @@ int32_t ViEChannel::OnInitializeDecoder( << " " << payload_name; vcm_->ResetDecoder(); - CriticalSectionScoped cs(callback_cs_.get()); + CriticalSectionScoped cs(crit_.get()); decoder_reset_ = true; return 0; } void ViEChannel::OnIncomingSSRCChanged(const int32_t id, const uint32_t ssrc) { - assert(channel_id_ == ChannelId(id)); - rtp_rtcp_->SetRemoteSSRC(ssrc); - + DCHECK_EQ(channel_id_, ChannelId(id)); + rtp_rtcp_modules_[0]->SetRemoteSSRC(ssrc); } void ViEChannel::OnIncomingCSRCChanged(const int32_t id, const uint32_t CSRC, const bool added) { - assert(channel_id_ == ChannelId(id)); - CriticalSectionScoped cs(callback_cs_.get()); + DCHECK_EQ(channel_id_, ChannelId(id)); + CriticalSectionScoped cs(crit_.get()); } void ViEChannel::RegisterSendFrameCountObserver( @@ -1699,13 +1302,13 @@ void ViEChannel::RegisterSendFrameCountObserver( void ViEChannel::RegisterReceiveStatisticsProxy( ReceiveStatisticsProxy* receive_statistics_proxy) { - CriticalSectionScoped cs(callback_cs_.get()); + CriticalSectionScoped cs(crit_.get()); vcm_receive_stats_callback_ = receive_statistics_proxy; } void ViEChannel::SetIncomingVideoStream( IncomingVideoStream* incoming_video_stream) { - CriticalSectionScoped cs(callback_cs_.get()); + CriticalSectionScoped cs(crit_.get()); incoming_video_stream_ = incoming_video_stream; } } // namespace webrtc diff --git a/webrtc/video_engine/vie_channel.h b/webrtc/video_engine/vie_channel.h index 426cc3a700..0f8477d4ef 100644 --- a/webrtc/video_engine/vie_channel.h +++ b/webrtc/video_engine/vie_channel.h @@ -83,10 +83,6 @@ class ViEDecoderObserver { int min_playout_delay_ms, int render_delay_ms) = 0; - // This method is called when the decoder needs a new key frame from encoder - // on the sender. - virtual void RequestNewKeyFrame(const int video_channel) = 0; - protected: virtual ~ViEDecoderObserver() {} }; @@ -105,13 +101,14 @@ class ViEChannel : public VCMFrameTypeCallback, uint32_t number_of_cores, const Config& config, Transport* transport, - ProcessThread& module_process_thread, + ProcessThread* module_process_thread, RtcpIntraFrameObserver* intra_frame_observer, RtcpBandwidthObserver* bandwidth_observer, RemoteBitrateEstimator* remote_bitrate_estimator, RtcpRttStats* rtt_stats, PacedSender* paced_sender, PacketRouter* packet_router, + size_t max_rtp_streams, bool sender, bool disable_default_encoder); ~ViEChannel(); @@ -139,9 +136,6 @@ class ViEChannel : public VCMFrameTypeCallback, // Returns the estimated delay in milliseconds. int ReceiveDelay() const; - // Only affects calls to SetReceiveCodec done after this call. - int32_t WaitForKeyFrame(bool wait); - // If enabled, a key frame request will be sent as soon as there are lost // packets. If |only_key_frames| are set, requests are only sent for loss in // key frames. @@ -169,7 +163,6 @@ class ViEChannel : public VCMFrameTypeCallback, void SetRtcpXrRrtrStatus(bool enable); void SetTransmissionSmoothingStatus(bool enable); void EnableTMMBR(bool enable); - int32_t EnableKeyFrameRequestCallback(const bool enable); // Sets SSRC for outgoing stream. int32_t SetSSRC(const uint32_t SSRC, @@ -185,9 +178,6 @@ class ViEChannel : public VCMFrameTypeCallback, int SetRtxSendPayloadType(int payload_type, int associated_payload_type); void SetRtxReceivePayloadType(int payload_type, int associated_payload_type); - // Sets the starting sequence number, must be called before StartSend. - int32_t SetStartSequenceNumber(uint16_t sequence_number); - void SetRtpStateForSsrc(uint32_t ssrc, const RtpState& rtp_state); RtpState GetRtpStateForSsrc(uint32_t ssrc); @@ -196,11 +186,6 @@ class ViEChannel : public VCMFrameTypeCallback, // Gets the CName of the incoming stream. int32_t GetRemoteRTCPCName(char rtcp_cname[]); - int32_t SendApplicationDefinedRTCPPacket( - const uint8_t sub_type, - uint32_t name, - const uint8_t* data, - uint16_t data_length_in_bytes); // Returns statistics reported by the remote client in an RTCP packet. // TODO(pbos): Remove this along with VideoSendStream::GetRtt(). @@ -277,12 +262,6 @@ class ViEChannel : public VCMFrameTypeCallback, // IP, UDP and RTP headers. int32_t SetMTU(uint16_t mtu); - // Returns maximum allowed payload size, i.e. the maximum allowed size of - // encoded data in each packet. - uint16_t MaxDataPayloadLength() const; - int32_t SetMaxPacketBurstSize(uint16_t max_number_of_packets); - int32_t SetPacketBurstSpreadState(bool enable, const uint16_t frame_periodMS); - // Gets the modules used by the channel. RtpRtcp* rtp_rtcp(); rtc::scoped_refptr send_payload_router(); @@ -323,8 +302,8 @@ class ViEChannel : public VCMFrameTypeCallback, const uint64_t picture_id); // Implements VideoPacketRequestCallback. - virtual int32_t ResendPackets(const uint16_t* sequence_numbers, - uint16_t length); + int32_t ResendPackets(const uint16_t* sequence_numbers, + uint16_t length) override; int32_t SetVoiceChannel(int32_t ve_channel_id, VoEVideoSync* ve_sync_interface); @@ -355,12 +334,22 @@ class ViEChannel : public VCMFrameTypeCallback, uint32_t* sent_fec_rate_bps); private: - void ReserveRtpRtcpModules(size_t total_modules) - EXCLUSIVE_LOCKS_REQUIRED(rtp_rtcp_cs_); - RtpRtcp* GetRtpRtcpModule(size_t simulcast_idx) const - EXCLUSIVE_LOCKS_REQUIRED(rtp_rtcp_cs_); - RtpRtcp::Configuration CreateRtpRtcpConfiguration(); - RtpRtcp* CreateRtpRtcpModule(); + static std::vector CreateRtpRtcpModules( + int32_t id, + bool receiver_only, + ReceiveStatistics* receive_statistics, + Transport* outgoing_transport, + RtcpIntraFrameObserver* intra_frame_callback, + RtcpBandwidthObserver* bandwidth_callback, + RtcpRttStats* rtt_stats, + RtcpPacketTypeCounterObserver* rtcp_packet_type_counter_observer, + RemoteBitrateEstimator* remote_bitrate_estimator, + PacedSender* paced_sender, + BitrateStatisticsObserver* send_bitrate_observer, + FrameCountObserver* send_frame_count_observer, + SendSideDelayObserver* send_side_delay_observer, + size_t num_modules); + // Assumed to be protected. void StartDecodeThread(); void StopDecodeThread(); @@ -461,19 +450,17 @@ class ViEChannel : public VCMFrameTypeCallback, GUARDED_BY(critsect_); } rtcp_packet_type_counter_observer_; - int32_t channel_id_; - int32_t engine_id_; - uint32_t number_of_cores_; - uint8_t num_socket_threads_; + const int32_t channel_id_; + const int32_t engine_id_; + const uint32_t number_of_cores_; + const bool sender_; + + ProcessThread* const module_process_thread_; // Used for all registered callbacks except rendering. - rtc::scoped_ptr callback_cs_; - rtc::scoped_ptr rtp_rtcp_cs_; + rtc::scoped_ptr crit_; // Owned modules/classes. - rtc::scoped_ptr rtp_rtcp_; - std::list simulcast_rtp_rtcp_; - std::list removed_rtp_rtcp_; rtc::scoped_refptr send_payload_router_; rtc::scoped_ptr vcm_protection_callback_; @@ -486,41 +473,34 @@ class ViEChannel : public VCMFrameTypeCallback, // Not owned. VCMReceiveStatisticsCallback* vcm_receive_stats_callback_ - GUARDED_BY(callback_cs_); - FrameCounts receive_frame_counts_ GUARDED_BY(callback_cs_); - IncomingVideoStream* incoming_video_stream_ GUARDED_BY(callback_cs_); - ProcessThread& module_process_thread_; - ViEDecoderObserver* codec_observer_; - bool do_key_frame_callbackRequest_; - RtcpIntraFrameObserver* intra_frame_observer_; - RtcpRttStats* rtt_stats_; - PacedSender* paced_sender_; - PacketRouter* packet_router_; + GUARDED_BY(crit_); + FrameCounts receive_frame_counts_ GUARDED_BY(crit_); + IncomingVideoStream* incoming_video_stream_ GUARDED_BY(crit_); + ViEDecoderObserver* codec_observer_ GUARDED_BY(crit_); + RtcpIntraFrameObserver* const intra_frame_observer_; + RtcpRttStats* const rtt_stats_; + PacedSender* const paced_sender_; + PacketRouter* const packet_router_; - rtc::scoped_ptr bandwidth_observer_; - int send_timestamp_extension_id_; - int absolute_send_time_extension_id_; - int video_rotation_extension_id_; + const rtc::scoped_ptr bandwidth_observer_; - Transport* const transport_; - - bool decoder_reset_; + bool decoder_reset_ GUARDED_BY(crit_); // Current receive codec used for codec change callback. - VideoCodec receive_codec_; - bool wait_for_key_frame_; + VideoCodec receive_codec_ GUARDED_BY(crit_); rtc::scoped_ptr decode_thread_; - // User set MTU, -1 if not set. - uint16_t mtu_; - const bool sender_; // Used to skip default encoder in the new API. const bool disable_default_encoder_; int nack_history_size_sender_; int max_nack_reordering_threshold_; - I420FrameCallback* pre_render_callback_; + I420FrameCallback* pre_render_callback_ GUARDED_BY(crit_); - rtc::scoped_ptr report_block_stats_sender_; + const rtc::scoped_ptr report_block_stats_sender_; + + // RtpRtcp modules, declared last as they use other members on construction. + const std::vector rtp_rtcp_modules_; + size_t num_active_rtp_rtcp_modules_ GUARDED_BY(crit_); }; } // namespace webrtc diff --git a/webrtc/video_engine/vie_channel_group.cc b/webrtc/video_engine/vie_channel_group.cc index b0923b30de..bf011373a2 100644 --- a/webrtc/video_engine/vie_channel_group.cc +++ b/webrtc/video_engine/vie_channel_group.cc @@ -193,7 +193,9 @@ bool ChannelGroup::CreateSendChannel(int channel_id, int engine_id, Transport* transport, int number_of_cores, + size_t max_rtp_streams, bool disable_default_encoder) { + DCHECK_GT(max_rtp_streams, 0u); rtc::scoped_ptr vie_encoder( new ViEEncoder(channel_id, number_of_cores, *config_.get(), *process_thread_, pacer_.get(), bitrate_allocator_.get(), @@ -203,7 +205,8 @@ bool ChannelGroup::CreateSendChannel(int channel_id, } ViEEncoder* encoder = vie_encoder.get(); if (!CreateChannel(channel_id, engine_id, transport, number_of_cores, - vie_encoder.release(), true, disable_default_encoder)) { + vie_encoder.release(), max_rtp_streams, true, + disable_default_encoder)) { return false; } ViEChannel* channel = channel_map_[channel_id]; @@ -230,7 +233,7 @@ bool ChannelGroup::CreateReceiveChannel(int channel_id, bool disable_default_encoder) { ViEEncoder* encoder = GetEncoder(base_channel_id); return CreateChannel(channel_id, engine_id, transport, number_of_cores, - encoder, false, disable_default_encoder); + encoder, 1, false, disable_default_encoder); } bool ChannelGroup::CreateChannel(int channel_id, @@ -238,16 +241,18 @@ bool ChannelGroup::CreateChannel(int channel_id, Transport* transport, int number_of_cores, ViEEncoder* vie_encoder, + size_t max_rtp_streams, bool sender, bool disable_default_encoder) { DCHECK(vie_encoder); rtc::scoped_ptr channel(new ViEChannel( channel_id, engine_id, number_of_cores, *config_.get(), transport, - *process_thread_, encoder_state_feedback_->GetRtcpIntraFrameObserver(), + process_thread_, encoder_state_feedback_->GetRtcpIntraFrameObserver(), bitrate_controller_->CreateRtcpBandwidthObserver(), remote_bitrate_estimator_.get(), call_stats_->rtcp_rtt_stats(), - pacer_.get(), packet_router_.get(), sender, disable_default_encoder)); + pacer_.get(), packet_router_.get(), max_rtp_streams, sender, + disable_default_encoder)); if (channel->Init() != 0) { return false; } diff --git a/webrtc/video_engine/vie_channel_group.h b/webrtc/video_engine/vie_channel_group.h index 094c121796..37064c8976 100644 --- a/webrtc/video_engine/vie_channel_group.h +++ b/webrtc/video_engine/vie_channel_group.h @@ -46,6 +46,7 @@ class ChannelGroup : public BitrateObserver { int engine_id, Transport* transport, int number_of_cores, + size_t max_rtp_streams, bool disable_default_encoder); bool CreateReceiveChannel(int channel_id, int engine_id, @@ -89,6 +90,7 @@ class ChannelGroup : public BitrateObserver { Transport* transport, int number_of_cores, ViEEncoder* vie_encoder, + size_t max_rtp_streams, bool sender, bool disable_default_encoder); ViEChannel* PopChannel(int channel_id); diff --git a/webrtc/video_engine/vie_receiver.cc b/webrtc/video_engine/vie_receiver.cc index 18b6e347ac..9e25080052 100644 --- a/webrtc/video_engine/vie_receiver.cc +++ b/webrtc/video_engine/vie_receiver.cc @@ -147,16 +147,14 @@ RtpReceiver* ViEReceiver::GetRtpReceiver() const { return rtp_receiver_.get(); } -void ViEReceiver::RegisterSimulcastRtpRtcpModules( - const std::list& rtp_modules) { +void ViEReceiver::RegisterRtpRtcpModules( + const std::vector& rtp_modules) { CriticalSectionScoped cs(receive_cs_.get()); - rtp_rtcp_simulcast_.clear(); - - if (!rtp_modules.empty()) { - rtp_rtcp_simulcast_.insert(rtp_rtcp_simulcast_.begin(), - rtp_modules.begin(), - rtp_modules.end()); - } + // Only change the "simulcast" modules, the base module can be accessed + // without a lock whereas the simulcast modules require locking as they can be + // changed in runtime. + rtp_rtcp_simulcast_ = + std::vector(rtp_modules.begin() + 1, rtp_modules.end()); } bool ViEReceiver::SetReceiveTimestampOffsetStatus(bool enable, int id) { @@ -398,11 +396,8 @@ int ViEReceiver::InsertRTCPPacket(const uint8_t* rtcp_packet, return -1; } - std::list::iterator it = rtp_rtcp_simulcast_.begin(); - while (it != rtp_rtcp_simulcast_.end()) { - RtpRtcp* rtp_rtcp = *it++; + for (RtpRtcp* rtp_rtcp : rtp_rtcp_simulcast_) rtp_rtcp->IncomingRtcpPacket(rtcp_packet, rtcp_packet_length); - } } assert(rtp_rtcp_); // Should be set by owner at construction time. int ret = rtp_rtcp_->IncomingRtcpPacket(rtcp_packet, rtcp_packet_length); diff --git a/webrtc/video_engine/vie_receiver.h b/webrtc/video_engine/vie_receiver.h index 8c1506fca1..62fb225f80 100644 --- a/webrtc/video_engine/vie_receiver.h +++ b/webrtc/video_engine/vie_receiver.h @@ -58,7 +58,7 @@ class ViEReceiver : public RtpData { RtpReceiver* GetRtpReceiver() const; - void RegisterSimulcastRtpRtcpModules(const std::list& rtp_modules); + void RegisterRtpRtcpModules(const std::vector& rtp_modules); bool SetReceiveTimestampOffsetStatus(bool enable, int id); bool SetReceiveAbsoluteSendTimeStatus(bool enable, int id); @@ -102,10 +102,10 @@ class ViEReceiver : public RtpData { rtc::scoped_ptr rtp_header_parser_; rtc::scoped_ptr rtp_payload_registry_; rtc::scoped_ptr rtp_receiver_; - rtc::scoped_ptr rtp_receive_statistics_; + const rtc::scoped_ptr rtp_receive_statistics_; rtc::scoped_ptr fec_receiver_; RtpRtcp* rtp_rtcp_; - std::list rtp_rtcp_simulcast_; + std::vector rtp_rtcp_simulcast_; VideoCodingModule* vcm_; RemoteBitrateEstimator* remote_bitrate_estimator_;