Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(223)

Side by Side Diff: webrtc/voice_engine/channel.cc

Issue 1263223002: Adding locking to webrtc::voe::Channel to fix race conditions (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Moved LeastRequiredDelayMs definition to cc file Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/voice_engine/channel.h ('k') | webrtc/voice_engine/voe_video_sync_impl.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 762 matching lines...) Expand 10 before | Expand all | Expand 10 after
773 _mute(false), 773 _mute(false),
774 _panLeft(1.0f), 774 _panLeft(1.0f),
775 _panRight(1.0f), 775 _panRight(1.0f),
776 _outputGain(1.0f), 776 _outputGain(1.0f),
777 _playOutbandDtmfEvent(false), 777 _playOutbandDtmfEvent(false),
778 _playInbandDtmfEvent(false), 778 _playInbandDtmfEvent(false),
779 _lastLocalTimeStamp(0), 779 _lastLocalTimeStamp(0),
780 _lastPayloadType(0), 780 _lastPayloadType(0),
781 _includeAudioLevelIndication(false), 781 _includeAudioLevelIndication(false),
782 _outputSpeechType(AudioFrame::kNormalSpeech), 782 _outputSpeechType(AudioFrame::kNormalSpeech),
783 video_sync_lock_(CriticalSectionWrapper::CreateCriticalSection()),
783 _average_jitter_buffer_delay_us(0), 784 _average_jitter_buffer_delay_us(0),
784 least_required_delay_ms_(0),
785 _previousTimestamp(0), 785 _previousTimestamp(0),
786 _recPacketDelayMs(20), 786 _recPacketDelayMs(20),
787 _RxVadDetection(false), 787 _RxVadDetection(false),
788 _rxAgcIsEnabled(false), 788 _rxAgcIsEnabled(false),
789 _rxNsIsEnabled(false), 789 _rxNsIsEnabled(false),
790 restored_packet_in_use_(false), 790 restored_packet_in_use_(false),
791 rtcp_observer_(new VoERtcpObserver(this)), 791 rtcp_observer_(new VoERtcpObserver(this)),
792 network_predictor_(new NetworkPredictor(Clock::GetRealTimeClock())), 792 network_predictor_(new NetworkPredictor(Clock::GetRealTimeClock())),
793 assoc_send_channel_lock_(CriticalSectionWrapper::CreateCriticalSection()), 793 assoc_send_channel_lock_(CriticalSectionWrapper::CreateCriticalSection()),
794 associate_send_channel_(ChannelOwner(nullptr)) 794 associate_send_channel_(ChannelOwner(nullptr))
(...skipping 2759 matching lines...) Expand 10 before | Expand all | Expand 10 after
3554 "Channel::GetNetworkStatistics()"); 3554 "Channel::GetNetworkStatistics()");
3555 return audio_coding_->GetNetworkStatistics(&stats); 3555 return audio_coding_->GetNetworkStatistics(&stats);
3556 } 3556 }
3557 3557
3558 void Channel::GetDecodingCallStatistics(AudioDecodingCallStats* stats) const { 3558 void Channel::GetDecodingCallStatistics(AudioDecodingCallStats* stats) const {
3559 audio_coding_->GetDecodingCallStatistics(stats); 3559 audio_coding_->GetDecodingCallStatistics(stats);
3560 } 3560 }
3561 3561
3562 bool Channel::GetDelayEstimate(int* jitter_buffer_delay_ms, 3562 bool Channel::GetDelayEstimate(int* jitter_buffer_delay_ms,
3563 int* playout_buffer_delay_ms) const { 3563 int* playout_buffer_delay_ms) const {
3564 CriticalSectionScoped cs(video_sync_lock_.get());
3564 if (_average_jitter_buffer_delay_us == 0) { 3565 if (_average_jitter_buffer_delay_us == 0) {
3565 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3566 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
3566 "Channel::GetDelayEstimate() no valid estimate."); 3567 "Channel::GetDelayEstimate() no valid estimate.");
3567 return false; 3568 return false;
3568 } 3569 }
3569 *jitter_buffer_delay_ms = (_average_jitter_buffer_delay_us + 500) / 1000 + 3570 *jitter_buffer_delay_ms = (_average_jitter_buffer_delay_us + 500) / 1000 +
3570 _recPacketDelayMs; 3571 _recPacketDelayMs;
3571 *playout_buffer_delay_ms = playout_delay_ms_; 3572 *playout_buffer_delay_ms = playout_delay_ms_;
3572 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3573 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
3573 "Channel::GetDelayEstimate()"); 3574 "Channel::GetDelayEstimate()");
3574 return true; 3575 return true;
3575 } 3576 }
3576 3577
3578 int Channel::LeastRequiredDelayMs() const {
3579 return audio_coding_->LeastRequiredDelayMs();
3580 }
3581
3577 int Channel::SetInitialPlayoutDelay(int delay_ms) 3582 int Channel::SetInitialPlayoutDelay(int delay_ms)
3578 { 3583 {
3579 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3584 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
3580 "Channel::SetInitialPlayoutDelay()"); 3585 "Channel::SetInitialPlayoutDelay()");
3581 if ((delay_ms < kVoiceEngineMinMinPlayoutDelayMs) || 3586 if ((delay_ms < kVoiceEngineMinMinPlayoutDelayMs) ||
3582 (delay_ms > kVoiceEngineMaxMinPlayoutDelayMs)) 3587 (delay_ms > kVoiceEngineMaxMinPlayoutDelayMs))
3583 { 3588 {
3584 _engineStatisticsPtr->SetLastError( 3589 _engineStatisticsPtr->SetLastError(
3585 VE_INVALID_ARGUMENT, kTraceError, 3590 VE_INVALID_ARGUMENT, kTraceError,
3586 "SetInitialPlayoutDelay() invalid min delay"); 3591 "SetInitialPlayoutDelay() invalid min delay");
(...skipping 26 matching lines...) Expand all
3613 if (audio_coding_->SetMinimumPlayoutDelay(delayMs) != 0) 3618 if (audio_coding_->SetMinimumPlayoutDelay(delayMs) != 0)
3614 { 3619 {
3615 _engineStatisticsPtr->SetLastError( 3620 _engineStatisticsPtr->SetLastError(
3616 VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 3621 VE_AUDIO_CODING_MODULE_ERROR, kTraceError,
3617 "SetMinimumPlayoutDelay() failed to set min playout delay"); 3622 "SetMinimumPlayoutDelay() failed to set min playout delay");
3618 return -1; 3623 return -1;
3619 } 3624 }
3620 return 0; 3625 return 0;
3621 } 3626 }
3622 3627
3623 void Channel::UpdatePlayoutTimestamp(bool rtcp) {
3624 uint32_t playout_timestamp = 0;
3625
3626 if (audio_coding_->PlayoutTimestamp(&playout_timestamp) == -1) {
3627 // This can happen if this channel has not been received any RTP packet. In
3628 // this case, NetEq is not capable of computing playout timestamp.
3629 return;
3630 }
3631
3632 uint16_t delay_ms = 0;
3633 if (_audioDeviceModulePtr->PlayoutDelay(&delay_ms) == -1) {
3634 WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId),
3635 "Channel::UpdatePlayoutTimestamp() failed to read playout"
3636 " delay from the ADM");
3637 _engineStatisticsPtr->SetLastError(
3638 VE_CANNOT_RETRIEVE_VALUE, kTraceError,
3639 "UpdatePlayoutTimestamp() failed to retrieve playout delay");
3640 return;
3641 }
3642
3643 jitter_buffer_playout_timestamp_ = playout_timestamp;
3644
3645 // Remove the playout delay.
3646 playout_timestamp -= (delay_ms * (GetPlayoutFrequency() / 1000));
3647
3648 WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId),
3649 "Channel::UpdatePlayoutTimestamp() => playoutTimestamp = %lu",
3650 playout_timestamp);
3651
3652 if (rtcp) {
3653 playout_timestamp_rtcp_ = playout_timestamp;
3654 } else {
3655 playout_timestamp_rtp_ = playout_timestamp;
3656 }
3657 playout_delay_ms_ = delay_ms;
3658 }
3659
3660 int Channel::GetPlayoutTimestamp(unsigned int& timestamp) { 3628 int Channel::GetPlayoutTimestamp(unsigned int& timestamp) {
3661 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3629 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
3662 "Channel::GetPlayoutTimestamp()"); 3630 "Channel::GetPlayoutTimestamp()");
3663 if (playout_timestamp_rtp_ == 0) { 3631 uint32_t playout_timestamp_rtp = 0;
3632 {
3633 CriticalSectionScoped cs(video_sync_lock_.get());
3634 playout_timestamp_rtp = playout_timestamp_rtp_;
3635 }
3636 if (playout_timestamp_rtp == 0) {
3664 _engineStatisticsPtr->SetLastError( 3637 _engineStatisticsPtr->SetLastError(
3665 VE_CANNOT_RETRIEVE_VALUE, kTraceError, 3638 VE_CANNOT_RETRIEVE_VALUE, kTraceError,
3666 "GetPlayoutTimestamp() failed to retrieve timestamp"); 3639 "GetPlayoutTimestamp() failed to retrieve timestamp");
3667 return -1; 3640 return -1;
3668 } 3641 }
3669 timestamp = playout_timestamp_rtp_; 3642 timestamp = playout_timestamp_rtp;
3670 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 3643 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice,
3671 VoEId(_instanceId,_channelId), 3644 VoEId(_instanceId,_channelId),
3672 "GetPlayoutTimestamp() => timestamp=%u", timestamp); 3645 "GetPlayoutTimestamp() => timestamp=%u", timestamp);
3673 return 0; 3646 return 0;
3674 } 3647 }
3675 3648
3676 int Channel::SetInitTimestamp(unsigned int timestamp) { 3649 int Channel::SetInitTimestamp(unsigned int timestamp) {
3677 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 3650 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
3678 "Channel::SetInitTimestamp()"); 3651 "Channel::SetInitTimestamp()");
3679 if (channel_state_.Get().sending) { 3652 if (channel_state_.Get().sending) {
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
3915 if (!RTCP) 3888 if (!RTCP)
3916 { 3889 {
3917 return _transportPtr->SendPacket(_channelId, data, len); 3890 return _transportPtr->SendPacket(_channelId, data, len);
3918 } 3891 }
3919 else 3892 else
3920 { 3893 {
3921 return _transportPtr->SendRTCPPacket(_channelId, data, len); 3894 return _transportPtr->SendRTCPPacket(_channelId, data, len);
3922 } 3895 }
3923 } 3896 }
3924 3897
3898 void Channel::UpdatePlayoutTimestamp(bool rtcp) {
3899 uint32_t playout_timestamp = 0;
3900
3901 if (audio_coding_->PlayoutTimestamp(&playout_timestamp) == -1) {
3902 // This can happen if this channel has not been received any RTP packet. In
3903 // this case, NetEq is not capable of computing playout timestamp.
3904 return;
3905 }
3906
3907 uint16_t delay_ms = 0;
3908 if (_audioDeviceModulePtr->PlayoutDelay(&delay_ms) == -1) {
3909 WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId),
3910 "Channel::UpdatePlayoutTimestamp() failed to read playout"
3911 " delay from the ADM");
3912 _engineStatisticsPtr->SetLastError(
3913 VE_CANNOT_RETRIEVE_VALUE, kTraceError,
3914 "UpdatePlayoutTimestamp() failed to retrieve playout delay");
3915 return;
3916 }
3917
3918 jitter_buffer_playout_timestamp_ = playout_timestamp;
3919
3920 // Remove the playout delay.
3921 playout_timestamp -= (delay_ms * (GetPlayoutFrequency() / 1000));
3922
3923 WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId),
3924 "Channel::UpdatePlayoutTimestamp() => playoutTimestamp = %lu",
3925 playout_timestamp);
3926
3927 {
3928 CriticalSectionScoped cs(video_sync_lock_.get());
3929 if (rtcp) {
3930 playout_timestamp_rtcp_ = playout_timestamp;
3931 } else {
3932 playout_timestamp_rtp_ = playout_timestamp;
3933 }
3934 playout_delay_ms_ = delay_ms;
3935 }
3936 }
3937
3925 // Called for incoming RTP packets after successful RTP header parsing. 3938 // Called for incoming RTP packets after successful RTP header parsing.
3926 void Channel::UpdatePacketDelay(uint32_t rtp_timestamp, 3939 void Channel::UpdatePacketDelay(uint32_t rtp_timestamp,
3927 uint16_t sequence_number) { 3940 uint16_t sequence_number) {
3928 WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 3941 WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId),
3929 "Channel::UpdatePacketDelay(timestamp=%lu, sequenceNumber=%u)", 3942 "Channel::UpdatePacketDelay(timestamp=%lu, sequenceNumber=%u)",
3930 rtp_timestamp, sequence_number); 3943 rtp_timestamp, sequence_number);
3931 3944
3932 // Get frequency of last received payload 3945 // Get frequency of last received payload
3933 int rtp_receive_frequency = GetPlayoutFrequency(); 3946 int rtp_receive_frequency = GetPlayoutFrequency();
3934 3947
3935 // Update the least required delay.
3936 least_required_delay_ms_ = audio_coding_->LeastRequiredDelayMs();
3937
3938 // |jitter_buffer_playout_timestamp_| updated in UpdatePlayoutTimestamp for 3948 // |jitter_buffer_playout_timestamp_| updated in UpdatePlayoutTimestamp for
3939 // every incoming packet. 3949 // every incoming packet.
3940 uint32_t timestamp_diff_ms = (rtp_timestamp - 3950 uint32_t timestamp_diff_ms = (rtp_timestamp -
3941 jitter_buffer_playout_timestamp_) / (rtp_receive_frequency / 1000); 3951 jitter_buffer_playout_timestamp_) / (rtp_receive_frequency / 1000);
3942 if (!IsNewerTimestamp(rtp_timestamp, jitter_buffer_playout_timestamp_) || 3952 if (!IsNewerTimestamp(rtp_timestamp, jitter_buffer_playout_timestamp_) ||
3943 timestamp_diff_ms > (2 * kVoiceEngineMaxMinPlayoutDelayMs)) { 3953 timestamp_diff_ms > (2 * kVoiceEngineMaxMinPlayoutDelayMs)) {
3944 // If |jitter_buffer_playout_timestamp_| is newer than the incoming RTP 3954 // If |jitter_buffer_playout_timestamp_| is newer than the incoming RTP
3945 // timestamp, the resulting difference is negative, but is set to zero. 3955 // timestamp, the resulting difference is negative, but is set to zero.
3946 // This can happen when a network glitch causes a packet to arrive late, 3956 // This can happen when a network glitch causes a packet to arrive late,
3947 // and during long comfort noise periods with clock drift. 3957 // and during long comfort noise periods with clock drift.
3948 timestamp_diff_ms = 0; 3958 timestamp_diff_ms = 0;
3949 } 3959 }
3950 3960
3951 uint16_t packet_delay_ms = (rtp_timestamp - _previousTimestamp) / 3961 uint16_t packet_delay_ms = (rtp_timestamp - _previousTimestamp) /
3952 (rtp_receive_frequency / 1000); 3962 (rtp_receive_frequency / 1000);
3953 3963
3954 _previousTimestamp = rtp_timestamp; 3964 _previousTimestamp = rtp_timestamp;
3955 3965
3956 if (timestamp_diff_ms == 0) return; 3966 if (timestamp_diff_ms == 0) return;
3957 3967
3958 if (packet_delay_ms >= 10 && packet_delay_ms <= 60) { 3968 {
3959 _recPacketDelayMs = packet_delay_ms; 3969 CriticalSectionScoped cs(video_sync_lock_.get());
3970
3971 if (packet_delay_ms >= 10 && packet_delay_ms <= 60) {
3972 _recPacketDelayMs = packet_delay_ms;
3973 }
3974
3975 if (_average_jitter_buffer_delay_us == 0) {
3976 _average_jitter_buffer_delay_us = timestamp_diff_ms * 1000;
3977 return;
3978 }
3979
3980 // Filter average delay value using exponential filter (alpha is
3981 // 7/8). We derive 1000 *_average_jitter_buffer_delay_us here (reduces
3982 // risk of rounding error) and compensate for it in GetDelayEstimate()
3983 // later.
3984 _average_jitter_buffer_delay_us = (_average_jitter_buffer_delay_us * 7 +
3985 1000 * timestamp_diff_ms + 500) / 8;
3960 } 3986 }
3961
3962 if (_average_jitter_buffer_delay_us == 0) {
3963 _average_jitter_buffer_delay_us = timestamp_diff_ms * 1000;
3964 return;
3965 }
3966
3967 // Filter average delay value using exponential filter (alpha is
3968 // 7/8). We derive 1000 *_average_jitter_buffer_delay_us here (reduces
3969 // risk of rounding error) and compensate for it in GetDelayEstimate()
3970 // later.
3971 _average_jitter_buffer_delay_us = (_average_jitter_buffer_delay_us * 7 +
3972 1000 * timestamp_diff_ms + 500) / 8;
3973 } 3987 }
3974 3988
3975 void 3989 void
3976 Channel::RegisterReceiveCodecsToRTPModule() 3990 Channel::RegisterReceiveCodecsToRTPModule()
3977 { 3991 {
3978 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3992 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
3979 "Channel::RegisterReceiveCodecsToRTPModule()"); 3993 "Channel::RegisterReceiveCodecsToRTPModule()");
3980 3994
3981 3995
3982 CodecInst codec; 3996 CodecInst codec;
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
4131 int64_t min_rtt = 0; 4145 int64_t min_rtt = 0;
4132 if (_rtpRtcpModule->RTT(remoteSSRC, &rtt, &avg_rtt, &min_rtt, &max_rtt) 4146 if (_rtpRtcpModule->RTT(remoteSSRC, &rtt, &avg_rtt, &min_rtt, &max_rtt)
4133 != 0) { 4147 != 0) {
4134 return 0; 4148 return 0;
4135 } 4149 }
4136 return rtt; 4150 return rtt;
4137 } 4151 }
4138 4152
4139 } // namespace voe 4153 } // namespace voe
4140 } // namespace webrtc 4154 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/voice_engine/channel.h ('k') | webrtc/voice_engine/voe_video_sync_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698