Added method for getting default module state and protect agains a

read/write race for child_modules_.

BUG=2731
TEST=tsan
R=stefan@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/5919005

git-svn-id: http://webrtc.googlecode.com/svn/trunk@5306 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
mflodman@webrtc.org 2013-12-17 08:30:40 +00:00
parent 9df6674b26
commit e6b871bb29
2 changed files with 21 additions and 95 deletions

View File

@ -191,13 +191,7 @@ int32_t ModuleRtpRtcpImpl::Process() {
last_bitrate_process_time_ = now;
}
bool default_instance = false;
{
CriticalSectionScoped cs(critical_section_module_ptrs_.get());
if (!child_modules_.empty())
default_instance = true;
}
if (!default_instance) {
if (!IsDefaultModule()) {
bool process_rtt = now >= last_rtt_process_time_ + kRtpRtcpRttProcessTimeMs;
if (rtcp_sender_.Sending()) {
// Process RTT if we have received a receiver report and we haven't
@ -454,9 +448,7 @@ int32_t ModuleRtpRtcpImpl::SetCSRCs(
"SetCSRCs(arr_length:%d)",
arr_length);
const bool default_instance(child_modules_.empty() ? false : true);
if (default_instance) {
if (IsDefaultModule()) {
// For default we need to update all child modules too.
CriticalSectionScoped lock(critical_section_module_ptrs_.get());
@ -481,20 +473,17 @@ int32_t ModuleRtpRtcpImpl::SetCSRCs(
uint32_t ModuleRtpRtcpImpl::PacketCountSent() const {
WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_, "PacketCountSent()");
return rtp_sender_.Packets();
}
uint32_t ModuleRtpRtcpImpl::ByteCountSent() const {
WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_, "ByteCountSent()");
return rtp_sender_.Bytes();
}
int ModuleRtpRtcpImpl::CurrentSendFrequencyHz() const {
WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_,
"CurrentSendFrequencyHz()");
return rtp_sender_.SendPayloadFrequency();
}
@ -537,7 +526,6 @@ int32_t ModuleRtpRtcpImpl::SetSendingStatus(const bool sending) {
bool ModuleRtpRtcpImpl::Sending() const {
WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_, "Sending()");
return rtcp_sender_.Sending();
}
@ -556,8 +544,7 @@ int32_t ModuleRtpRtcpImpl::SetSendingMediaStatus(const bool sending) {
bool ModuleRtpRtcpImpl::SendingMedia() const {
WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_, "Sending()");
const bool have_child_modules(child_modules_.empty() ? false : true);
if (!have_child_modules) {
if (!IsDefaultModule()) {
return rtp_sender_.SendingMedia();
}
@ -591,8 +578,7 @@ int32_t ModuleRtpRtcpImpl::SendOutgoingData(
rtcp_sender_.SetLastRtpTime(time_stamp, capture_time_ms);
const bool have_child_modules(child_modules_.empty() ? false : true);
if (!have_child_modules) {
if (!IsDefaultModule()) {
// Don't send RTCP from default module.
if (rtcp_sender_.TimeToSendRTCPReport(kVideoFrameKey == frame_type)) {
RTCPSender::FeedbackState feedback_state(this);
@ -677,12 +663,7 @@ bool ModuleRtpRtcpImpl::TimeToSendPacket(uint32_t ssrc,
"TimeToSendPacket(ssrc:0x%x sequence_number:%u capture_time_ms:%ll)",
ssrc, sequence_number, capture_time_ms);
bool no_child_modules = false;
{
CriticalSectionScoped lock(critical_section_module_ptrs_.get());
no_child_modules = child_modules_.empty();
}
if (no_child_modules) {
if (!IsDefaultModule()) {
// Don't send from default module.
if (SendingMedia() && ssrc == rtp_sender_.SSRC()) {
return rtp_sender_.TimeToSendPacket(sequence_number, capture_time_ms,
@ -708,12 +689,7 @@ int ModuleRtpRtcpImpl::TimeToSendPadding(int bytes) {
WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, id_, "TimeToSendPadding(bytes: %d)",
bytes);
bool no_child_modules = false;
{
CriticalSectionScoped lock(critical_section_module_ptrs_.get());
no_child_modules = child_modules_.empty();
}
if (no_child_modules) {
if (!IsDefaultModule()) {
// Don't send from default module.
if (SendingMedia()) {
return rtp_sender_.TimeToSendPadding(bytes);
@ -737,7 +713,7 @@ bool ModuleRtpRtcpImpl::GetSendSideDelay(int* avg_send_delay_ms,
assert(avg_send_delay_ms);
assert(max_send_delay_ms);
if (!child_modules_.empty()) {
if (IsDefaultModule()) {
// This API is only supported for child modules.
return false;
}
@ -746,7 +722,6 @@ bool ModuleRtpRtcpImpl::GetSendSideDelay(int* avg_send_delay_ms,
uint16_t ModuleRtpRtcpImpl::MaxPayloadLength() const {
WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_, "MaxPayloadLength()");
return rtp_sender_.MaxPayloadLength();
}
@ -759,8 +734,7 @@ uint16_t ModuleRtpRtcpImpl::MaxDataPayloadLength() const {
// Assuming IP/UDP.
uint16_t min_data_payload_length = IP_PACKET_SIZE - 28;
const bool default_instance(child_modules_.empty() ? false : true);
if (default_instance) {
if (IsDefaultModule()) {
// For default we need to update all child modules too.
CriticalSectionScoped lock(critical_section_module_ptrs_.get());
std::list<ModuleRtpRtcpImpl*>::const_iterator it =
@ -829,7 +803,6 @@ int32_t ModuleRtpRtcpImpl::SetTransportOverhead(
int32_t ModuleRtpRtcpImpl::SetMaxTransferUnit(const uint16_t mtu) {
WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_, "SetMaxTransferUnit(%u)",
mtu);
if (mtu > IP_PACKET_SIZE) {
WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, id_,
"Invalid in argument to SetMaxTransferUnit(%u)", mtu);
@ -841,7 +814,6 @@ int32_t ModuleRtpRtcpImpl::SetMaxTransferUnit(const uint16_t mtu) {
RTCPMethod ModuleRtpRtcpImpl::RTCP() const {
WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_, "RTCP()");
if (rtcp_sender_.Status() != kRtcpOff) {
return rtcp_receiver_.Status();
}
@ -852,7 +824,6 @@ RTCPMethod ModuleRtpRtcpImpl::RTCP() const {
int32_t ModuleRtpRtcpImpl::SetRTCPStatus(const RTCPMethod method) {
WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_, "SetRTCPStatus(%d)",
method);
if (rtcp_sender_.SetRTCPStatus(method) == 0) {
return rtcp_receiver_.SetRTCPStatus(method);
}
@ -880,7 +851,6 @@ int32_t ModuleRtpRtcpImpl::AddMixedCNAME(
const char c_name[RTCP_CNAME_SIZE]) {
WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_,
"AddMixedCNAME(SSRC:%u)", ssrc);
return rtcp_sender_.AddMixedCNAME(ssrc, c_name);
}
@ -895,7 +865,6 @@ int32_t ModuleRtpRtcpImpl::RemoteCNAME(
char c_name[RTCP_CNAME_SIZE]) const {
WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_,
"RemoteCNAME(SSRC:%u)", remote_ssrc);
return rtcp_receiver_.CNAME(remote_ssrc, c_name);
}
@ -906,7 +875,6 @@ int32_t ModuleRtpRtcpImpl::RemoteNTP(
uint32_t* rtcp_arrival_time_frac,
uint32_t* rtcp_timestamp) const {
WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_, "RemoteNTP()");
return rtcp_receiver_.NTP(received_ntpsecs,
received_ntpfrac,
rtcp_arrival_time_secs,
@ -921,7 +889,6 @@ int32_t ModuleRtpRtcpImpl::RTT(const uint32_t remote_ssrc,
uint16_t* min_rtt,
uint16_t* max_rtt) const {
WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_, "RTT()");
return rtcp_receiver_.RTT(remote_ssrc, rtt, avg_rtt, min_rtt, max_rtt);
}
@ -929,7 +896,6 @@ int32_t ModuleRtpRtcpImpl::RTT(const uint32_t remote_ssrc,
int32_t ModuleRtpRtcpImpl::ResetRTT(const uint32_t remote_ssrc) {
WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_, "ResetRTT(SSRC:%u)",
remote_ssrc);
return rtcp_receiver_.ResetRTT(remote_ssrc);
}
@ -937,7 +903,6 @@ int32_t ModuleRtpRtcpImpl::ResetRTT(const uint32_t remote_ssrc) {
int32_t ModuleRtpRtcpImpl::ResetSendDataCountersRTP() {
WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_,
"ResetSendDataCountersRTP()");
rtp_sender_.ResetDataCounters();
return 0; // TODO(pwestin): change to void.
}
@ -959,7 +924,6 @@ int32_t ModuleRtpRtcpImpl::SetRTCPApplicationSpecificData(
WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_,
"SetRTCPApplicationSpecificData(sub_type:%d name:0x%x)",
sub_type, name);
return rtcp_sender_.SetApplicationSpecificData(sub_type, name, data, length);
}
@ -985,7 +949,6 @@ int32_t ModuleRtpRtcpImpl::DataCountersRTP(
uint32_t* bytes_sent,
uint32_t* packets_sent) const {
WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, id_, "DataCountersRTP()");
if (bytes_sent) {
*bytes_sent = rtp_sender_.Bytes();
}
@ -997,7 +960,6 @@ int32_t ModuleRtpRtcpImpl::DataCountersRTP(
int32_t ModuleRtpRtcpImpl::RemoteRTCPStat(RTCPSenderInfo* sender_info) {
WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_, "RemoteRTCPStat()");
return rtcp_receiver_.SenderInfoReceived(sender_info);
}
@ -1005,7 +967,6 @@ int32_t ModuleRtpRtcpImpl::RemoteRTCPStat(RTCPSenderInfo* sender_info) {
int32_t ModuleRtpRtcpImpl::RemoteRTCPStat(
std::vector<RTCPReportBlock>* receive_blocks) const {
WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_, "RemoteRTCPStat()");
return rtcp_receiver_.StatisticsReceived(receive_blocks);
}
@ -1013,21 +974,18 @@ int32_t ModuleRtpRtcpImpl::AddRTCPReportBlock(
const uint32_t ssrc,
const RTCPReportBlock* report_block) {
WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_, "AddRTCPReportBlock()");
return rtcp_sender_.AddExternalReportBlock(ssrc, report_block);
}
int32_t ModuleRtpRtcpImpl::RemoveRTCPReportBlock(
const uint32_t ssrc) {
WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_, "RemoveRTCPReportBlock()");
return rtcp_sender_.RemoveExternalReportBlock(ssrc);
}
// (REMB) Receiver Estimated Max Bitrate.
bool ModuleRtpRtcpImpl::REMB() const {
WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_, "REMB()");
return rtcp_sender_.REMB();
}
@ -1057,7 +1015,6 @@ int32_t ModuleRtpRtcpImpl::SetREMBData(const uint32_t bitrate,
// (IJ) Extended jitter report.
bool ModuleRtpRtcpImpl::IJ() const {
WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_, "IJ()");
return rtcp_sender_.IJ();
}
@ -1066,7 +1023,6 @@ int32_t ModuleRtpRtcpImpl::SetIJStatus(const bool enable) {
kTraceRtpRtcp,
id_,
"SetIJStatus(%s)", enable ? "true" : "false");
return rtcp_sender_.SetIJStatus(enable);
}
@ -1084,7 +1040,6 @@ int32_t ModuleRtpRtcpImpl::DeregisterSendRtpHeaderExtension(
// (TMMBR) Temporary Max Media Bit Rate.
bool ModuleRtpRtcpImpl::TMMBR() const {
WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_, "TMMBR()");
return rtcp_sender_.TMMBR();
}
@ -1101,7 +1056,6 @@ int32_t ModuleRtpRtcpImpl::SetTMMBRStatus(const bool enable) {
int32_t ModuleRtpRtcpImpl::SetTMMBN(const TMMBRSet* bounding_set) {
WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_, "SetTMMBN()");
uint32_t max_bitrate_kbit =
rtp_sender_.MaxConfiguredBitrateVideo() / 1000;
return rtcp_sender_.SetTMMBN(bounding_set, max_bitrate_kbit);
@ -1222,7 +1176,6 @@ int32_t ModuleRtpRtcpImpl::SendTelephoneEventOutband(
WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_,
"SendTelephoneEventOutband(key:%u, time_ms:%u, level:%u)", key,
time_ms, level);
return rtp_sender_.SendTelephoneEvent(key, time_ms, level);
}
@ -1233,7 +1186,6 @@ bool ModuleRtpRtcpImpl::SendTelephoneEventActive(
kTraceRtpRtcp,
id_,
"SendTelephoneEventActive()");
return rtp_sender_.SendTelephoneEventActive(&telephone_event);
}
@ -1247,7 +1199,6 @@ int32_t ModuleRtpRtcpImpl::SetAudioPacketSize(
id_,
"SetAudioPacketSize(%u)",
packet_size_samples);
return rtp_sender_.SetAudioPacketSize(packet_size_samples);
}
@ -1261,14 +1212,12 @@ int32_t ModuleRtpRtcpImpl::SetRTPAudioLevelIndicationStatus(
"SetRTPAudioLevelIndicationStatus(enable=%d, ID=%u)",
enable,
id);
return rtp_sender_.SetAudioLevelIndicationStatus(enable, id);
}
int32_t ModuleRtpRtcpImpl::GetRTPAudioLevelIndicationStatus(
bool& enable,
uint8_t& id) const {
WEBRTC_TRACE(kTraceModuleCall,
kTraceRtpRtcp,
id_,
@ -1294,7 +1243,6 @@ int32_t ModuleRtpRtcpImpl::SetSendREDPayloadType(
id_,
"SetSendREDPayloadType(%d)",
payload_type);
return rtp_sender_.SetRED(payload_type);
}
@ -1302,7 +1250,6 @@ int32_t ModuleRtpRtcpImpl::SetSendREDPayloadType(
int32_t ModuleRtpRtcpImpl::SendREDPayloadType(
int8_t& payload_type) const {
WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_, "SendREDPayloadType()");
return rtp_sender_.RED(&payload_type);
}
@ -1314,9 +1261,7 @@ void ModuleRtpRtcpImpl::SetTargetSendBitrate(
const std::vector<uint32_t>& stream_bitrates) {
WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_,
"SetTargetSendBitrate: %ld streams", stream_bitrates.size());
const bool have_child_modules(child_modules_.empty() ? false : true);
if (have_child_modules) {
if (IsDefaultModule()) {
CriticalSectionScoped lock(critical_section_module_ptrs_.get());
if (simulcast_) {
std::list<ModuleRtpRtcpImpl*>::iterator it = child_modules_.begin();
@ -1349,7 +1294,6 @@ int32_t ModuleRtpRtcpImpl::SetKeyFrameRequestMethod(
id_,
"SetKeyFrameRequestMethod(method:%u)",
method);
key_frame_req_method_ = method;
return 0;
}
@ -1359,7 +1303,6 @@ int32_t ModuleRtpRtcpImpl::RequestKeyFrame() {
kTraceRtpRtcp,
id_,
"RequestKeyFrame");
switch (key_frame_req_method_) {
case kKeyFrameReqFirRtp:
return rtp_sender_.SendRTPIntraRequest();
@ -1378,7 +1321,6 @@ int32_t ModuleRtpRtcpImpl::SendRTCPSliceLossIndication(
id_,
"SendRTCPSliceLossIndication (picture_id:%d)",
picture_id);
RTCPSender::FeedbackState feedback_state(this);
return rtcp_sender_.SendRTCP(
feedback_state, kRtcpSli, 0, 0, false, picture_id);
@ -1390,11 +1332,8 @@ int32_t ModuleRtpRtcpImpl::SetCameraDelay(const int32_t delay_ms) {
id_,
"SetCameraDelay(%d)",
delay_ms);
const bool default_instance(child_modules_.empty() ? false : true);
if (default_instance) {
if (IsDefaultModule()) {
CriticalSectionScoped lock(critical_section_module_ptrs_.get());
std::list<ModuleRtpRtcpImpl*>::iterator it = child_modules_.begin();
while (it != child_modules_.end()) {
RtpRtcp* module = *it;
@ -1433,12 +1372,10 @@ int32_t ModuleRtpRtcpImpl::GenericFECStatus(
bool& enable,
uint8_t& payload_type_red,
uint8_t& payload_type_fec) {
WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_, "GenericFECStatus()");
bool child_enabled = false;
const bool default_instance(child_modules_.empty() ? false : true);
if (default_instance) {
if (IsDefaultModule()) {
// For default we need to check all child modules too.
CriticalSectionScoped lock(critical_section_module_ptrs_.get());
std::list<ModuleRtpRtcpImpl*>::iterator it = child_modules_.begin();
@ -1471,8 +1408,7 @@ int32_t ModuleRtpRtcpImpl::GenericFECStatus(
int32_t ModuleRtpRtcpImpl::SetFecParameters(
const FecProtectionParams* delta_params,
const FecProtectionParams* key_params) {
const bool default_instance(child_modules_.empty() ? false : true);
if (default_instance) {
if (IsDefaultModule()) {
// For default we need to update all child modules too.
CriticalSectionScoped lock(critical_section_module_ptrs_.get());
@ -1517,9 +1453,7 @@ void ModuleRtpRtcpImpl::BitrateSent(uint32_t* total_rate,
uint32_t* video_rate,
uint32_t* fec_rate,
uint32_t* nack_rate) const {
const bool default_instance(child_modules_.empty() ? false : true);
if (default_instance) {
if (IsDefaultModule()) {
// For default we need to update the send bitrate.
CriticalSectionScoped lock(critical_section_module_ptrs_feedback_.get());
@ -1570,21 +1504,7 @@ void ModuleRtpRtcpImpl::BitrateSent(uint32_t* total_rate,
void ModuleRtpRtcpImpl::RegisterVideoBitrateObserver(
BitrateStatisticsObserver* observer) {
{
CriticalSectionScoped cs(critical_section_module_ptrs_.get());
if (!child_modules_.empty()) {
for (std::list<ModuleRtpRtcpImpl*>::const_iterator it =
child_modules_.begin();
it != child_modules_.end();
++it) {
RtpRtcp* module = *it;
if (module)
module->RegisterVideoBitrateObserver(observer);
}
return;
}
}
assert(!IsDefaultModule());
rtp_sender_.RegisterBitrateObserver(observer);
}
@ -1592,7 +1512,6 @@ BitrateStatisticsObserver* ModuleRtpRtcpImpl::GetVideoBitrateObserver() const {
return rtp_sender_.GetBitrateObserver();
}
// Bad state of RTP receiver request a keyframe.
void ModuleRtpRtcpImpl::OnRequestIntraFrame() {
RequestKeyFrame();
}
@ -1716,4 +1635,9 @@ FrameCountObserver* ModuleRtpRtcpImpl::GetSendFrameCountObserver() const {
return rtp_sender_.GetFrameCountObserver();
}
bool ModuleRtpRtcpImpl::IsDefaultModule() const {
CriticalSectionScoped cs(critical_section_module_ptrs_.get());
return !child_modules_.empty();
}
} // Namespace webrtc

View File

@ -418,6 +418,8 @@ class ModuleRtpRtcpImpl : public RtpRtcp {
void set_rtt_ms(uint32_t rtt_ms);
uint32_t rtt_ms() const;
bool IsDefaultModule() const;
int32_t id_;
const bool audio_;
bool collision_detected_;