Register RTP/RTCP modules outside rtp_rtcp_cs_.
Prevents deadlock between the process thread and SetSendCodec calls. BUG=4542 R=mflodman@webrtc.org, stefan@webrtc.org Review URL: https://webrtc-codereview.appspot.com/45179004 Cr-Commit-Position: refs/heads/master@{#9018}
This commit is contained in:
parent
382c58d127
commit
fb98c40915
@ -382,177 +382,184 @@ int32_t ViEChannel::SetSendCodec(const VideoCodec& video_codec,
|
||||
uint8_t payload_type_fec;
|
||||
rtp_rtcp_->GenericFECStatus(fec_enabled, payload_type_red, payload_type_fec);
|
||||
|
||||
CriticalSectionScoped cs(rtp_rtcp_cs_.get());
|
||||
std::vector<RtpRtcp*> registered_modules;
|
||||
std::vector<RtpRtcp*> deregistered_modules;
|
||||
{
|
||||
CriticalSectionScoped cs(rtp_rtcp_cs_.get());
|
||||
|
||||
if (video_codec.numberOfSimulcastStreams > 0) {
|
||||
// Set correct bitrate to base layer.
|
||||
// Create our simulcast RTP modules.
|
||||
int num_modules_to_add = video_codec.numberOfSimulcastStreams -
|
||||
simulcast_rtp_rtcp_.size() - 1;
|
||||
if (num_modules_to_add < 0) {
|
||||
num_modules_to_add = 0;
|
||||
}
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
for (int i = 0; i < num_modules_to_add; ++i)
|
||||
new_rtp_modules.push_back(CreateRtpRtcpModule());
|
||||
|
||||
// Initialize newly added modules.
|
||||
for (std::list<RtpRtcp*>::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 (video_codec.numberOfSimulcastStreams > 0) {
|
||||
// Set correct bitrate to base layer.
|
||||
// Create our simulcast RTP modules.
|
||||
int num_modules_to_add =
|
||||
video_codec.numberOfSimulcastStreams - simulcast_rtp_rtcp_.size() - 1;
|
||||
if (num_modules_to_add < 0) {
|
||||
num_modules_to_add = 0;
|
||||
}
|
||||
|
||||
if (fec_enabled) {
|
||||
rtp_rtcp->SetGenericFECStatus(
|
||||
fec_enabled, payload_type_red, payload_type_fec);
|
||||
// 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();
|
||||
}
|
||||
rtp_rtcp->SetSendingStatus(rtp_rtcp_->Sending());
|
||||
rtp_rtcp->SetSendingMediaStatus(rtp_rtcp_->SendingMedia());
|
||||
rtp_rtcp->SetRtxSendPayloadType(rtp_rtcp_->RtxSendPayloadType());
|
||||
rtp_rtcp->SetRtxSendStatus(rtp_rtcp_->RtxSendStatus());
|
||||
simulcast_rtp_rtcp_.push_back(rtp_rtcp);
|
||||
|
||||
// Silently ignore error.
|
||||
module_process_thread_.RegisterModule(rtp_rtcp);
|
||||
}
|
||||
for (int i = 0; i < num_modules_to_add; ++i)
|
||||
new_rtp_modules.push_back(CreateRtpRtcpModule());
|
||||
|
||||
// Remove last in list if we have too many.
|
||||
for (int j = simulcast_rtp_rtcp_.size();
|
||||
j > (video_codec.numberOfSimulcastStreams - 1);
|
||||
j--) {
|
||||
RtpRtcp* rtp_rtcp = simulcast_rtp_rtcp_.back();
|
||||
module_process_thread_.DeRegisterModule(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<RtpRtcp*>::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";
|
||||
// Initialize newly added modules.
|
||||
for (std::list<RtpRtcp*>::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_);
|
||||
}
|
||||
} 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();
|
||||
module_process_thread_.DeRegisterModule(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) {
|
||||
return -1;
|
||||
}
|
||||
if (restart_rtp) {
|
||||
rtp_rtcp_->SetSendingStatus(true);
|
||||
for (std::list<RtpRtcp*>::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);
|
||||
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());
|
||||
rtp_rtcp->SetRtxSendPayloadType(rtp_rtcp_->RtxSendPayloadType());
|
||||
rtp_rtcp->SetRtxSendStatus(rtp_rtcp_->RtxSendStatus());
|
||||
simulcast_rtp_rtcp_.push_back(rtp_rtcp);
|
||||
|
||||
std::list<RtpRtcp*> active_send_modules;
|
||||
active_send_modules.push_back(rtp_rtcp_.get());
|
||||
for (std::list<RtpRtcp*>::const_iterator cit = simulcast_rtp_rtcp_.begin();
|
||||
cit != simulcast_rtp_rtcp_.end(); ++cit) {
|
||||
active_send_modules.push_back(*cit);
|
||||
// Silently ignore error.
|
||||
registered_modules.push_back(rtp_rtcp);
|
||||
}
|
||||
|
||||
// Remove last in list if we have too many.
|
||||
for (int j = simulcast_rtp_rtcp_.size();
|
||||
j > (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<RtpRtcp*>::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) {
|
||||
return -1;
|
||||
}
|
||||
if (restart_rtp) {
|
||||
rtp_rtcp_->SetSendingStatus(true);
|
||||
for (std::list<RtpRtcp*>::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<RtpRtcp*> active_send_modules;
|
||||
active_send_modules.push_back(rtp_rtcp_.get());
|
||||
for (std::list<RtpRtcp*>::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);
|
||||
}
|
||||
send_payload_router_->SetSendingRtpModules(active_send_modules);
|
||||
if (router_was_active)
|
||||
send_payload_router_->set_active(true);
|
||||
for (RtpRtcp* rtp_rtcp : registered_modules)
|
||||
module_process_thread_.RegisterModule(rtp_rtcp);
|
||||
for (RtpRtcp* rtp_rtcp : deregistered_modules)
|
||||
module_process_thread_.DeRegisterModule(rtp_rtcp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user