diff options
author | pbos@webrtc.org <pbos@webrtc.org@4adac7df-926f-26a2-2b94-8c16560cd09d> | 2014-06-30 13:19:09 +0000 |
---|---|---|
committer | pbos@webrtc.org <pbos@webrtc.org@4adac7df-926f-26a2-2b94-8c16560cd09d> | 2014-06-30 13:19:09 +0000 |
commit | 88b558febb8e8f42df6c7482efe76795c3fed399 (patch) | |
tree | 29ea16ff45efb548143dc2df08dd3ebc6830bea0 /video_engine | |
parent | b9cd54f49f17ea1ddc4cf3f13d54f5d942d4d56f (diff) | |
download | webrtc-88b558febb8e8f42df6c7482efe76795c3fed399.tar.gz |
Reserve RTP/RTCP modules in SetSSRC.
Allows setting SSRCs for future simulcast layers even though no set send
codec uses them.
Also re-enabling CanSwitchToUseAllSsrcs as an end-to-end test, required
for bitrate ramp-up, instead of send-side only (resolving issue 3078).
This test was used to verify reserved modules' SSRCs are preserved
correctly.
To enable a multiple-stream end-to-end test test::CallTest was modified
to work on a vector of receive streams instead of just one.
BUG=3078
R=kjellander@webrtc.org, stefan@webrtc.org
Review URL: https://webrtc-codereview.appspot.com/15859005
git-svn-id: http://webrtc.googlecode.com/svn/trunk/webrtc@6565 4adac7df-926f-26a2-2b94-8c16560cd09d
Diffstat (limited to 'video_engine')
-rw-r--r-- | video_engine/vie_channel.cc | 140 | ||||
-rw-r--r-- | video_engine/vie_channel.h | 5 |
2 files changed, 90 insertions, 55 deletions
diff --git a/video_engine/vie_channel.cc b/video_engine/vie_channel.cc index 62bb0959..80d3065b 100644 --- a/video_engine/vie_channel.cc +++ b/video_engine/vie_channel.cc @@ -244,31 +244,25 @@ int32_t ViEChannel::SetSendCodec(const VideoCodec& video_codec, num_modules_to_add = 0; } - while (removed_rtp_rtcp_.size() > 0 && num_modules_to_add > 0) { - RtpRtcp* rtp_rtcp = removed_rtp_rtcp_.front(); + // 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<RtpRtcp*> 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(); - simulcast_rtp_rtcp_.push_back(rtp_rtcp); - rtp_rtcp->SetSendingStatus(rtp_rtcp_->Sending()); - rtp_rtcp->SetSendingMediaStatus(rtp_rtcp_->SendingMedia()); - module_process_thread_.RegisterModule(rtp_rtcp); - --num_modules_to_add; } - for (int i = 0; i < num_modules_to_add; ++i) { - RtpRtcp::Configuration configuration; - configuration.id = ViEModuleId(engine_id_, channel_id_); - configuration.audio = false; // Video. - configuration.default_module = default_rtp_rtcp_; - configuration.outgoing_transport = &vie_sender_; - configuration.intra_frame_callback = intra_frame_observer_; - configuration.bandwidth_callback = bandwidth_observer_.get(); - configuration.rtt_stats = rtt_stats_; - configuration.paced_sender = paced_sender_; + for (int i = 0; i < num_modules_to_add; ++i) + new_rtp_modules.push_back(CreateRtpRtcpModule()); - RtpRtcp* rtp_rtcp = RtpRtcp::CreateRtpRtcp(configuration); + // Initialize newly added modules. + for (std::list<RtpRtcp*>::iterator it = new_rtp_modules.begin(); + it != new_rtp_modules.end(); + ++it) { + RtpRtcp* rtp_rtcp = *it; - // Silently ignore error. - module_process_thread_.RegisterModule(rtp_rtcp); rtp_rtcp->SetRTCPStatus(rtp_rtcp_->RTCP()); if (rtp_rtcp_->StorePackets()) { @@ -278,13 +272,18 @@ int32_t ViEChannel::SetSendCodec(const VideoCodec& video_codec, } if (fec_enabled) { - rtp_rtcp->SetGenericFECStatus(fec_enabled, payload_type_red, - payload_type_fec); + rtp_rtcp->SetGenericFECStatus( + fec_enabled, payload_type_red, payload_type_fec); } rtp_rtcp->SetSendingStatus(rtp_rtcp_->Sending()); rtp_rtcp->SetSendingMediaStatus(rtp_rtcp_->SendingMedia()); + simulcast_rtp_rtcp_.push_back(rtp_rtcp); + + // Silently ignore error. + module_process_thread_.RegisterModule(rtp_rtcp); } + // Remove last in list if we have too many. for (int j = simulcast_rtp_rtcp_.size(); j > (video_codec.numberOfSimulcastStreams - 1); @@ -792,29 +791,15 @@ int32_t ViEChannel::EnableKeyFrameRequestCallback(const bool enable) { int32_t ViEChannel::SetSSRC(const uint32_t SSRC, const StreamType usage, const uint8_t simulcast_idx) { - if (simulcast_idx == 0) { - if (usage == kViEStreamTypeRtx) { - rtp_rtcp_->SetRtxSsrc(SSRC); - } else { - rtp_rtcp_->SetSSRC(SSRC); - } - return 0; - } CriticalSectionScoped cs(rtp_rtcp_cs_.get()); - if (simulcast_idx > simulcast_rtp_rtcp_.size()) { - return -1; - } - std::list<RtpRtcp*>::const_iterator it = simulcast_rtp_rtcp_.begin(); - for (int i = 1; i < simulcast_idx; ++i, ++it) { - if (it == simulcast_rtp_rtcp_.end()) { - return -1; - } - } - RtpRtcp* rtp_rtcp_module = *it; + ReserveRtpRtcpModules(simulcast_idx + 1); + RtpRtcp* rtp_rtcp = GetRtpRtcpModule(simulcast_idx); + if (rtp_rtcp == NULL) + return -1; if (usage == kViEStreamTypeRtx) { - rtp_rtcp_module->SetRtxSsrc(SSRC); + rtp_rtcp->SetRtxSsrc(SSRC); } else { - rtp_rtcp_module->SetSSRC(SSRC); + rtp_rtcp->SetSSRC(SSRC); } return 0; } @@ -826,21 +811,11 @@ int32_t ViEChannel::SetRemoteSSRCType(const StreamType usage, } int32_t ViEChannel::GetLocalSSRC(uint8_t idx, unsigned int* ssrc) { - if (idx == 0) { - *ssrc = rtp_rtcp_->SSRC(); - return 0; - } CriticalSectionScoped cs(rtp_rtcp_cs_.get()); - if (idx > simulcast_rtp_rtcp_.size()) { + RtpRtcp* rtp_rtcp = GetRtpRtcpModule(idx); + if (rtp_rtcp == NULL) return -1; - } - std::list<RtpRtcp*>::const_iterator it = simulcast_rtp_rtcp_.begin(); - for (int i = 1; i < idx; ++i, ++it) { - if (it == simulcast_rtp_rtcp_.end()) { - return -1; - } - } - *ssrc = (*it)->SSRC(); + *ssrc = rtp_rtcp->SSRC(); return 0; } @@ -1530,6 +1505,61 @@ void ViEChannel::OnRttUpdate(uint32_t rtt) { vcm_->SetReceiveChannelParameters(rtt); } +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(); + rtp_rtcp->SetSendingStatus(false); + rtp_rtcp->SetSendingMediaStatus(false); + rtp_rtcp->RegisterSendFrameCountObserver(NULL); + rtp_rtcp->RegisterSendChannelRtcpStatisticsCallback(NULL); + rtp_rtcp->RegisterSendChannelRtpStatisticsCallback(NULL); + rtp_rtcp->RegisterVideoBitrateObserver(NULL); + removed_rtp_rtcp_.push_back(rtp_rtcp); + } +} + +RtpRtcp* ViEChannel::GetRtpRtcpModule(size_t index) const { + if (index == 0) + return rtp_rtcp_.get(); + if (index <= simulcast_rtp_rtcp_.size()) { + std::list<RtpRtcp*>::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<RtpRtcp*>::const_iterator it = removed_rtp_rtcp_.begin(); + while (removed_idx-- > 0) + ++it; + + return *it; +} + +RtpRtcp* ViEChannel::CreateRtpRtcpModule() { + RtpRtcp::Configuration configuration; + configuration.id = ViEModuleId(engine_id_, channel_id_); + configuration.audio = false; // Video. + configuration.default_module = default_rtp_rtcp_; + configuration.outgoing_transport = &vie_sender_; + configuration.intra_frame_callback = intra_frame_observer_; + configuration.bandwidth_callback = bandwidth_observer_.get(); + configuration.rtt_stats = rtt_stats_; + configuration.paced_sender = paced_sender_; + + return RtpRtcp::CreateRtpRtcp(configuration); +} + int32_t ViEChannel::StartDecodeThread() { // Start the decode thread if (decode_thread_) { diff --git a/video_engine/vie_channel.h b/video_engine/vie_channel.h index 23b7e5e5..c76d1298 100644 --- a/video_engine/vie_channel.h +++ b/video_engine/vie_channel.h @@ -362,6 +362,11 @@ class ViEChannel void OnRttUpdate(uint32_t rtt); 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* CreateRtpRtcpModule(); // Assumed to be protected. int32_t StartDecodeThread(); int32_t StopDecodeThread(); |