| OLD | NEW |
| 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 21 matching lines...) Expand all Loading... |
| 32 #include "rtc_base/criticalsection.h" | 32 #include "rtc_base/criticalsection.h" |
| 33 #include "rtc_base/format_macros.h" | 33 #include "rtc_base/format_macros.h" |
| 34 #include "rtc_base/location.h" | 34 #include "rtc_base/location.h" |
| 35 #include "rtc_base/logging.h" | 35 #include "rtc_base/logging.h" |
| 36 #include "rtc_base/rate_limiter.h" | 36 #include "rtc_base/rate_limiter.h" |
| 37 #include "rtc_base/task_queue.h" | 37 #include "rtc_base/task_queue.h" |
| 38 #include "rtc_base/thread_checker.h" | 38 #include "rtc_base/thread_checker.h" |
| 39 #include "rtc_base/timeutils.h" | 39 #include "rtc_base/timeutils.h" |
| 40 #include "system_wrappers/include/field_trial.h" | 40 #include "system_wrappers/include/field_trial.h" |
| 41 #include "system_wrappers/include/trace.h" | 41 #include "system_wrappers/include/trace.h" |
| 42 #include "voice_engine/output_mixer.h" | |
| 43 #include "voice_engine/statistics.h" | 42 #include "voice_engine/statistics.h" |
| 44 #include "voice_engine/utility.h" | 43 #include "voice_engine/utility.h" |
| 45 | 44 |
| 46 namespace webrtc { | 45 namespace webrtc { |
| 47 namespace voe { | 46 namespace voe { |
| 48 | 47 |
| 49 namespace { | 48 namespace { |
| 50 | 49 |
| 51 constexpr double kAudioSampleDurationSeconds = 0.01; | 50 constexpr double kAudioSampleDurationSeconds = 0.01; |
| 52 constexpr int64_t kMaxRetransmissionWindowMs = 1000; | 51 constexpr int64_t kMaxRetransmissionWindowMs = 1000; |
| (...skipping 559 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 612 "IncomingPacket invalid RTP header"); | 611 "IncomingPacket invalid RTP header"); |
| 613 return false; | 612 return false; |
| 614 } | 613 } |
| 615 header.payload_type_frequency = | 614 header.payload_type_frequency = |
| 616 rtp_payload_registry_->GetPayloadTypeFrequency(header.payloadType); | 615 rtp_payload_registry_->GetPayloadTypeFrequency(header.payloadType); |
| 617 if (header.payload_type_frequency < 0) | 616 if (header.payload_type_frequency < 0) |
| 618 return false; | 617 return false; |
| 619 return ReceivePacket(rtp_packet, rtp_packet_length, header, false); | 618 return ReceivePacket(rtp_packet, rtp_packet_length, header, false); |
| 620 } | 619 } |
| 621 | 620 |
| 622 MixerParticipant::AudioFrameInfo Channel::GetAudioFrameWithMuted( | 621 AudioMixer::Source::AudioFrameInfo Channel::GetAudioFrameWithInfo( |
| 623 int32_t id, | 622 int sample_rate_hz, |
| 624 AudioFrame* audioFrame) { | 623 AudioFrame* audio_frame) { |
| 624 audio_frame->sample_rate_hz_ = sample_rate_hz; |
| 625 |
| 625 unsigned int ssrc; | 626 unsigned int ssrc; |
| 626 RTC_CHECK_EQ(GetRemoteSSRC(ssrc), 0); | 627 RTC_CHECK_EQ(GetRemoteSSRC(ssrc), 0); |
| 627 event_log_proxy_->LogAudioPlayout(ssrc); | 628 event_log_proxy_->LogAudioPlayout(ssrc); |
| 628 // Get 10ms raw PCM data from the ACM (mixer limits output frequency) | 629 // Get 10ms raw PCM data from the ACM (mixer limits output frequency) |
| 629 bool muted; | 630 bool muted; |
| 630 if (audio_coding_->PlayoutData10Ms(audioFrame->sample_rate_hz_, audioFrame, | 631 if (audio_coding_->PlayoutData10Ms(audio_frame->sample_rate_hz_, audio_frame, |
| 631 &muted) == -1) { | 632 &muted) == -1) { |
| 632 WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId, _channelId), | 633 WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId, _channelId), |
| 633 "Channel::GetAudioFrame() PlayoutData10Ms() failed!"); | 634 "Channel::GetAudioFrame() PlayoutData10Ms() failed!"); |
| 634 // In all likelihood, the audio in this frame is garbage. We return an | 635 // In all likelihood, the audio in this frame is garbage. We return an |
| 635 // error so that the audio mixer module doesn't add it to the mix. As | 636 // error so that the audio mixer module doesn't add it to the mix. As |
| 636 // a result, it won't be played out and the actions skipped here are | 637 // a result, it won't be played out and the actions skipped here are |
| 637 // irrelevant. | 638 // irrelevant. |
| 638 return MixerParticipant::AudioFrameInfo::kError; | 639 return AudioMixer::Source::AudioFrameInfo::kError; |
| 639 } | 640 } |
| 640 | 641 |
| 641 if (muted) { | 642 if (muted) { |
| 642 // TODO(henrik.lundin): We should be able to do better than this. But we | 643 // TODO(henrik.lundin): We should be able to do better than this. But we |
| 643 // will have to go through all the cases below where the audio samples may | 644 // will have to go through all the cases below where the audio samples may |
| 644 // be used, and handle the muted case in some way. | 645 // be used, and handle the muted case in some way. |
| 645 AudioFrameOperations::Mute(audioFrame); | 646 AudioFrameOperations::Mute(audio_frame); |
| 646 } | 647 } |
| 647 | 648 |
| 648 // Convert module ID to internal VoE channel ID | 649 // Convert module ID to internal VoE channel ID |
| 649 audioFrame->id_ = VoEChannelId(audioFrame->id_); | 650 audio_frame->id_ = VoEChannelId(audio_frame->id_); |
| 650 // Store speech type for dead-or-alive detection | 651 // Store speech type for dead-or-alive detection |
| 651 _outputSpeechType = audioFrame->speech_type_; | 652 _outputSpeechType = audio_frame->speech_type_; |
| 652 | 653 |
| 653 { | 654 { |
| 654 // Pass the audio buffers to an optional sink callback, before applying | 655 // Pass the audio buffers to an optional sink callback, before applying |
| 655 // scaling/panning, as that applies to the mix operation. | 656 // scaling/panning, as that applies to the mix operation. |
| 656 // External recipients of the audio (e.g. via AudioTrack), will do their | 657 // External recipients of the audio (e.g. via AudioTrack), will do their |
| 657 // own mixing/dynamic processing. | 658 // own mixing/dynamic processing. |
| 658 rtc::CritScope cs(&_callbackCritSect); | 659 rtc::CritScope cs(&_callbackCritSect); |
| 659 if (audio_sink_) { | 660 if (audio_sink_) { |
| 660 AudioSinkInterface::Data data( | 661 AudioSinkInterface::Data data( |
| 661 audioFrame->data(), audioFrame->samples_per_channel_, | 662 audio_frame->data(), audio_frame->samples_per_channel_, |
| 662 audioFrame->sample_rate_hz_, audioFrame->num_channels_, | 663 audio_frame->sample_rate_hz_, audio_frame->num_channels_, |
| 663 audioFrame->timestamp_); | 664 audio_frame->timestamp_); |
| 664 audio_sink_->OnData(data); | 665 audio_sink_->OnData(data); |
| 665 } | 666 } |
| 666 } | 667 } |
| 667 | 668 |
| 668 float output_gain = 1.0f; | 669 float output_gain = 1.0f; |
| 669 { | 670 { |
| 670 rtc::CritScope cs(&volume_settings_critsect_); | 671 rtc::CritScope cs(&volume_settings_critsect_); |
| 671 output_gain = _outputGain; | 672 output_gain = _outputGain; |
| 672 } | 673 } |
| 673 | 674 |
| 674 // Output volume scaling | 675 // Output volume scaling |
| 675 if (output_gain < 0.99f || output_gain > 1.01f) { | 676 if (output_gain < 0.99f || output_gain > 1.01f) { |
| 676 // TODO(solenberg): Combine with mute state - this can cause clicks! | 677 // TODO(solenberg): Combine with mute state - this can cause clicks! |
| 677 AudioFrameOperations::ScaleWithSat(output_gain, audioFrame); | 678 AudioFrameOperations::ScaleWithSat(output_gain, audio_frame); |
| 678 } | 679 } |
| 679 | 680 |
| 680 // Measure audio level (0-9) | 681 // Measure audio level (0-9) |
| 681 // TODO(henrik.lundin) Use the |muted| information here too. | 682 // TODO(henrik.lundin) Use the |muted| information here too. |
| 682 // TODO(deadbeef): Use RmsLevel for |_outputAudioLevel| (see | 683 // TODO(deadbeef): Use RmsLevel for |_outputAudioLevel| (see |
| 683 // https://crbug.com/webrtc/7517). | 684 // https://crbug.com/webrtc/7517). |
| 684 _outputAudioLevel.ComputeLevel(*audioFrame, kAudioSampleDurationSeconds); | 685 _outputAudioLevel.ComputeLevel(*audio_frame, kAudioSampleDurationSeconds); |
| 685 | 686 |
| 686 if (capture_start_rtp_time_stamp_ < 0 && audioFrame->timestamp_ != 0) { | 687 if (capture_start_rtp_time_stamp_ < 0 && audio_frame->timestamp_ != 0) { |
| 687 // The first frame with a valid rtp timestamp. | 688 // The first frame with a valid rtp timestamp. |
| 688 capture_start_rtp_time_stamp_ = audioFrame->timestamp_; | 689 capture_start_rtp_time_stamp_ = audio_frame->timestamp_; |
| 689 } | 690 } |
| 690 | 691 |
| 691 if (capture_start_rtp_time_stamp_ >= 0) { | 692 if (capture_start_rtp_time_stamp_ >= 0) { |
| 692 // audioFrame.timestamp_ should be valid from now on. | 693 // audio_frame.timestamp_ should be valid from now on. |
| 693 | 694 |
| 694 // Compute elapsed time. | 695 // Compute elapsed time. |
| 695 int64_t unwrap_timestamp = | 696 int64_t unwrap_timestamp = |
| 696 rtp_ts_wraparound_handler_->Unwrap(audioFrame->timestamp_); | 697 rtp_ts_wraparound_handler_->Unwrap(audio_frame->timestamp_); |
| 697 audioFrame->elapsed_time_ms_ = | 698 audio_frame->elapsed_time_ms_ = |
| 698 (unwrap_timestamp - capture_start_rtp_time_stamp_) / | 699 (unwrap_timestamp - capture_start_rtp_time_stamp_) / |
| 699 (GetRtpTimestampRateHz() / 1000); | 700 (GetRtpTimestampRateHz() / 1000); |
| 700 | 701 |
| 701 { | 702 { |
| 702 rtc::CritScope lock(&ts_stats_lock_); | 703 rtc::CritScope lock(&ts_stats_lock_); |
| 703 // Compute ntp time. | 704 // Compute ntp time. |
| 704 audioFrame->ntp_time_ms_ = | 705 audio_frame->ntp_time_ms_ = |
| 705 ntp_estimator_.Estimate(audioFrame->timestamp_); | 706 ntp_estimator_.Estimate(audio_frame->timestamp_); |
| 706 // |ntp_time_ms_| won't be valid until at least 2 RTCP SRs are received. | 707 // |ntp_time_ms_| won't be valid until at least 2 RTCP SRs are received. |
| 707 if (audioFrame->ntp_time_ms_ > 0) { | 708 if (audio_frame->ntp_time_ms_ > 0) { |
| 708 // Compute |capture_start_ntp_time_ms_| so that | 709 // Compute |capture_start_ntp_time_ms_| so that |
| 709 // |capture_start_ntp_time_ms_| + |elapsed_time_ms_| == |ntp_time_ms_| | 710 // |capture_start_ntp_time_ms_| + |elapsed_time_ms_| == |ntp_time_ms_| |
| 710 capture_start_ntp_time_ms_ = | 711 capture_start_ntp_time_ms_ = |
| 711 audioFrame->ntp_time_ms_ - audioFrame->elapsed_time_ms_; | 712 audio_frame->ntp_time_ms_ - audio_frame->elapsed_time_ms_; |
| 712 } | 713 } |
| 713 } | 714 } |
| 714 } | 715 } |
| 715 | 716 |
| 716 return muted ? MixerParticipant::AudioFrameInfo::kMuted | 717 return muted ? AudioMixer::Source::AudioFrameInfo::kMuted |
| 717 : MixerParticipant::AudioFrameInfo::kNormal; | 718 : AudioMixer::Source::AudioFrameInfo::kNormal; |
| 718 } | 719 } |
| 719 | 720 |
| 720 AudioMixer::Source::AudioFrameInfo Channel::GetAudioFrameWithInfo( | 721 int Channel::PreferredSampleRate() const { |
| 721 int sample_rate_hz, | |
| 722 AudioFrame* audio_frame) { | |
| 723 audio_frame->sample_rate_hz_ = sample_rate_hz; | |
| 724 | |
| 725 const auto frame_info = GetAudioFrameWithMuted(-1, audio_frame); | |
| 726 | |
| 727 using FrameInfo = AudioMixer::Source::AudioFrameInfo; | |
| 728 FrameInfo new_audio_frame_info = FrameInfo::kError; | |
| 729 switch (frame_info) { | |
| 730 case MixerParticipant::AudioFrameInfo::kNormal: | |
| 731 new_audio_frame_info = FrameInfo::kNormal; | |
| 732 break; | |
| 733 case MixerParticipant::AudioFrameInfo::kMuted: | |
| 734 new_audio_frame_info = FrameInfo::kMuted; | |
| 735 break; | |
| 736 case MixerParticipant::AudioFrameInfo::kError: | |
| 737 new_audio_frame_info = FrameInfo::kError; | |
| 738 break; | |
| 739 } | |
| 740 return new_audio_frame_info; | |
| 741 } | |
| 742 | |
| 743 int32_t Channel::NeededFrequency(int32_t id) const { | |
| 744 WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, _channelId), | |
| 745 "Channel::NeededFrequency(id=%d)", id); | |
| 746 | |
| 747 int highestNeeded = 0; | |
| 748 | |
| 749 // Determine highest needed receive frequency | |
| 750 int32_t receiveFrequency = audio_coding_->ReceiveFrequency(); | |
| 751 | |
| 752 // Return the bigger of playout and receive frequency in the ACM. | 722 // Return the bigger of playout and receive frequency in the ACM. |
| 753 if (audio_coding_->PlayoutFrequency() > receiveFrequency) { | 723 return std::max(audio_coding_->ReceiveFrequency(), |
| 754 highestNeeded = audio_coding_->PlayoutFrequency(); | 724 audio_coding_->PlayoutFrequency()); |
| 755 } else { | |
| 756 highestNeeded = receiveFrequency; | |
| 757 } | |
| 758 | |
| 759 return highestNeeded; | |
| 760 } | 725 } |
| 761 | 726 |
| 762 int32_t Channel::CreateChannel(Channel*& channel, | 727 int32_t Channel::CreateChannel(Channel*& channel, |
| 763 int32_t channelId, | 728 int32_t channelId, |
| 764 uint32_t instanceId, | 729 uint32_t instanceId, |
| 765 const VoEBase::ChannelConfig& config) { | 730 const VoEBase::ChannelConfig& config) { |
| 766 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(instanceId, channelId), | 731 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(instanceId, channelId), |
| 767 "Channel::CreateChannel(channelId=%d, instanceId=%d)", channelId, | 732 "Channel::CreateChannel(channelId=%d, instanceId=%d)", channelId, |
| 768 instanceId); | 733 instanceId); |
| 769 | 734 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 799 _timeStamp(0), // This is just an offset, RTP module will add it's own | 764 _timeStamp(0), // This is just an offset, RTP module will add it's own |
| 800 // random offset | 765 // random offset |
| 801 ntp_estimator_(Clock::GetRealTimeClock()), | 766 ntp_estimator_(Clock::GetRealTimeClock()), |
| 802 playout_timestamp_rtp_(0), | 767 playout_timestamp_rtp_(0), |
| 803 playout_delay_ms_(0), | 768 playout_delay_ms_(0), |
| 804 send_sequence_number_(0), | 769 send_sequence_number_(0), |
| 805 rtp_ts_wraparound_handler_(new rtc::TimestampWrapAroundHandler()), | 770 rtp_ts_wraparound_handler_(new rtc::TimestampWrapAroundHandler()), |
| 806 capture_start_rtp_time_stamp_(-1), | 771 capture_start_rtp_time_stamp_(-1), |
| 807 capture_start_ntp_time_ms_(-1), | 772 capture_start_ntp_time_ms_(-1), |
| 808 _engineStatisticsPtr(NULL), | 773 _engineStatisticsPtr(NULL), |
| 809 _outputMixerPtr(NULL), | |
| 810 _moduleProcessThreadPtr(NULL), | 774 _moduleProcessThreadPtr(NULL), |
| 811 _audioDeviceModulePtr(NULL), | 775 _audioDeviceModulePtr(NULL), |
| 812 _voiceEngineObserverPtr(NULL), | 776 _voiceEngineObserverPtr(NULL), |
| 813 _callbackCritSectPtr(NULL), | 777 _callbackCritSectPtr(NULL), |
| 814 _transportPtr(NULL), | 778 _transportPtr(NULL), |
| 815 input_mute_(false), | 779 input_mute_(false), |
| 816 previous_frame_muted_(false), | 780 previous_frame_muted_(false), |
| 817 _outputGain(1.0f), | 781 _outputGain(1.0f), |
| 818 _includeAudioLevelIndication(false), | 782 _includeAudioLevelIndication(false), |
| 819 transport_overhead_per_packet_(0), | 783 transport_overhead_per_packet_(0), |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 976 } | 940 } |
| 977 | 941 |
| 978 // De-register modules in process thread | 942 // De-register modules in process thread |
| 979 if (_moduleProcessThreadPtr) | 943 if (_moduleProcessThreadPtr) |
| 980 _moduleProcessThreadPtr->DeRegisterModule(_rtpRtcpModule.get()); | 944 _moduleProcessThreadPtr->DeRegisterModule(_rtpRtcpModule.get()); |
| 981 | 945 |
| 982 // End of modules shutdown | 946 // End of modules shutdown |
| 983 } | 947 } |
| 984 | 948 |
| 985 int32_t Channel::SetEngineInformation(Statistics& engineStatistics, | 949 int32_t Channel::SetEngineInformation(Statistics& engineStatistics, |
| 986 OutputMixer& outputMixer, | |
| 987 ProcessThread& moduleProcessThread, | 950 ProcessThread& moduleProcessThread, |
| 988 AudioDeviceModule& audioDeviceModule, | 951 AudioDeviceModule& audioDeviceModule, |
| 989 VoiceEngineObserver* voiceEngineObserver, | 952 VoiceEngineObserver* voiceEngineObserver, |
| 990 rtc::CriticalSection* callbackCritSect, | 953 rtc::CriticalSection* callbackCritSect, |
| 991 rtc::TaskQueue* encoder_queue) { | 954 rtc::TaskQueue* encoder_queue) { |
| 992 RTC_DCHECK(encoder_queue); | 955 RTC_DCHECK(encoder_queue); |
| 993 RTC_DCHECK(!encoder_queue_); | 956 RTC_DCHECK(!encoder_queue_); |
| 994 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), | 957 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), |
| 995 "Channel::SetEngineInformation()"); | 958 "Channel::SetEngineInformation()"); |
| 996 _engineStatisticsPtr = &engineStatistics; | 959 _engineStatisticsPtr = &engineStatistics; |
| 997 _outputMixerPtr = &outputMixer; | |
| 998 _moduleProcessThreadPtr = &moduleProcessThread; | 960 _moduleProcessThreadPtr = &moduleProcessThread; |
| 999 _audioDeviceModulePtr = &audioDeviceModule; | 961 _audioDeviceModulePtr = &audioDeviceModule; |
| 1000 _voiceEngineObserverPtr = voiceEngineObserver; | 962 _voiceEngineObserverPtr = voiceEngineObserver; |
| 1001 _callbackCritSectPtr = callbackCritSect; | 963 _callbackCritSectPtr = callbackCritSect; |
| 1002 encoder_queue_ = encoder_queue; | 964 encoder_queue_ = encoder_queue; |
| 1003 return 0; | 965 return 0; |
| 1004 } | 966 } |
| 1005 | 967 |
| 1006 void Channel::SetSink(std::unique_ptr<AudioSinkInterface> sink) { | 968 void Channel::SetSink(std::unique_ptr<AudioSinkInterface> sink) { |
| 1007 rtc::CritScope cs(&_callbackCritSect); | 969 rtc::CritScope cs(&_callbackCritSect); |
| 1008 audio_sink_ = std::move(sink); | 970 audio_sink_ = std::move(sink); |
| 1009 } | 971 } |
| 1010 | 972 |
| 1011 const rtc::scoped_refptr<AudioDecoderFactory>& | 973 const rtc::scoped_refptr<AudioDecoderFactory>& |
| 1012 Channel::GetAudioDecoderFactory() const { | 974 Channel::GetAudioDecoderFactory() const { |
| 1013 return decoder_factory_; | 975 return decoder_factory_; |
| 1014 } | 976 } |
| 1015 | 977 |
| 1016 int32_t Channel::StartPlayout() { | 978 int32_t Channel::StartPlayout() { |
| 1017 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), | 979 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), |
| 1018 "Channel::StartPlayout()"); | 980 "Channel::StartPlayout()"); |
| 1019 if (channel_state_.Get().playing) { | 981 if (channel_state_.Get().playing) { |
| 1020 return 0; | 982 return 0; |
| 1021 } | 983 } |
| 1022 | 984 |
| 1023 // Add participant as candidates for mixing. | |
| 1024 if (_outputMixerPtr->SetMixabilityStatus(*this, true) != 0) { | |
| 1025 _engineStatisticsPtr->SetLastError( | |
| 1026 VE_AUDIO_CONF_MIX_MODULE_ERROR, kTraceError, | |
| 1027 "StartPlayout() failed to add participant to mixer"); | |
| 1028 return -1; | |
| 1029 } | |
| 1030 | |
| 1031 channel_state_.SetPlaying(true); | 985 channel_state_.SetPlaying(true); |
| 1032 | 986 |
| 1033 return 0; | 987 return 0; |
| 1034 } | 988 } |
| 1035 | 989 |
| 1036 int32_t Channel::StopPlayout() { | 990 int32_t Channel::StopPlayout() { |
| 1037 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), | 991 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), |
| 1038 "Channel::StopPlayout()"); | 992 "Channel::StopPlayout()"); |
| 1039 if (!channel_state_.Get().playing) { | 993 if (!channel_state_.Get().playing) { |
| 1040 return 0; | 994 return 0; |
| 1041 } | 995 } |
| 1042 | 996 |
| 1043 // Remove participant as candidates for mixing | |
| 1044 if (_outputMixerPtr->SetMixabilityStatus(*this, false) != 0) { | |
| 1045 _engineStatisticsPtr->SetLastError( | |
| 1046 VE_AUDIO_CONF_MIX_MODULE_ERROR, kTraceError, | |
| 1047 "StopPlayout() failed to remove participant from mixer"); | |
| 1048 return -1; | |
| 1049 } | |
| 1050 | |
| 1051 channel_state_.SetPlaying(false); | 997 channel_state_.SetPlaying(false); |
| 1052 _outputAudioLevel.Clear(); | 998 _outputAudioLevel.Clear(); |
| 1053 | 999 |
| 1054 return 0; | 1000 return 0; |
| 1055 } | 1001 } |
| 1056 | 1002 |
| 1057 int32_t Channel::StartSend() { | 1003 int32_t Channel::StartSend() { |
| 1058 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), | 1004 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), |
| 1059 "Channel::StartSend()"); | 1005 "Channel::StartSend()"); |
| 1060 if (channel_state_.Get().sending) { | 1006 if (channel_state_.Get().sending) { |
| (...skipping 1022 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2083 int64_t min_rtt = 0; | 2029 int64_t min_rtt = 0; |
| 2084 if (_rtpRtcpModule->RTT(remoteSSRC, &rtt, &avg_rtt, &min_rtt, &max_rtt) != | 2030 if (_rtpRtcpModule->RTT(remoteSSRC, &rtt, &avg_rtt, &min_rtt, &max_rtt) != |
| 2085 0) { | 2031 0) { |
| 2086 return 0; | 2032 return 0; |
| 2087 } | 2033 } |
| 2088 return rtt; | 2034 return rtt; |
| 2089 } | 2035 } |
| 2090 | 2036 |
| 2091 } // namespace voe | 2037 } // namespace voe |
| 2092 } // namespace webrtc | 2038 } // namespace webrtc |
| OLD | NEW |