Chromium Code Reviews| 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 |
| 11 #include "webrtc/voice_engine/channel.h" | 11 #include "webrtc/voice_engine/channel.h" |
| 12 | 12 |
| 13 #include <algorithm> | 13 #include <algorithm> |
| 14 #include <utility> | 14 #include <utility> |
| 15 | 15 |
| 16 #include "webrtc/base/checks.h" | 16 #include "webrtc/base/checks.h" |
| 17 #include "webrtc/base/criticalsection.h" | 17 #include "webrtc/base/criticalsection.h" |
| 18 #include "webrtc/base/format_macros.h" | 18 #include "webrtc/base/format_macros.h" |
| 19 #include "webrtc/base/logging.h" | 19 #include "webrtc/base/logging.h" |
| 20 #include "webrtc/base/thread_checker.h" | 20 #include "webrtc/base/thread_checker.h" |
| 21 #include "webrtc/base/timeutils.h" | 21 #include "webrtc/base/timeutils.h" |
| 22 #include "webrtc/common.h" | 22 #include "webrtc/common.h" |
| 23 #include "webrtc/config.h" | 23 #include "webrtc/config.h" |
| 24 #include "webrtc/call/rtc_event_log.h" | |
| 24 #include "webrtc/modules/audio_device/include/audio_device.h" | 25 #include "webrtc/modules/audio_device/include/audio_device.h" |
| 25 #include "webrtc/modules/audio_processing/include/audio_processing.h" | 26 #include "webrtc/modules/audio_processing/include/audio_processing.h" |
| 26 #include "webrtc/modules/include/module_common_types.h" | 27 #include "webrtc/modules/include/module_common_types.h" |
| 27 #include "webrtc/modules/pacing/packet_router.h" | 28 #include "webrtc/modules/pacing/packet_router.h" |
| 28 #include "webrtc/modules/rtp_rtcp/include/receive_statistics.h" | 29 #include "webrtc/modules/rtp_rtcp/include/receive_statistics.h" |
| 29 #include "webrtc/modules/rtp_rtcp/include/rtp_payload_registry.h" | 30 #include "webrtc/modules/rtp_rtcp/include/rtp_payload_registry.h" |
| 30 #include "webrtc/modules/rtp_rtcp/include/rtp_receiver.h" | 31 #include "webrtc/modules/rtp_rtcp/include/rtp_receiver.h" |
| 31 #include "webrtc/modules/rtp_rtcp/source/rtp_receiver_strategy.h" | 32 #include "webrtc/modules/rtp_rtcp/source/rtp_receiver_strategy.h" |
| 32 #include "webrtc/modules/utility/include/audio_frame_operations.h" | 33 #include "webrtc/modules/utility/include/audio_frame_operations.h" |
| 33 #include "webrtc/modules/utility/include/process_thread.h" | 34 #include "webrtc/modules/utility/include/process_thread.h" |
| 34 #include "webrtc/system_wrappers/include/trace.h" | 35 #include "webrtc/system_wrappers/include/trace.h" |
| 35 #include "webrtc/voice_engine/include/voe_base.h" | 36 #include "webrtc/voice_engine/include/voe_base.h" |
| 36 #include "webrtc/voice_engine/include/voe_external_media.h" | 37 #include "webrtc/voice_engine/include/voe_external_media.h" |
| 37 #include "webrtc/voice_engine/include/voe_rtp_rtcp.h" | 38 #include "webrtc/voice_engine/include/voe_rtp_rtcp.h" |
| 38 #include "webrtc/voice_engine/output_mixer.h" | 39 #include "webrtc/voice_engine/output_mixer.h" |
| 39 #include "webrtc/voice_engine/statistics.h" | 40 #include "webrtc/voice_engine/statistics.h" |
| 40 #include "webrtc/voice_engine/transmit_mixer.h" | 41 #include "webrtc/voice_engine/transmit_mixer.h" |
| 41 #include "webrtc/voice_engine/utility.h" | 42 #include "webrtc/voice_engine/utility.h" |
| 42 | 43 |
| 43 #if defined(_WIN32) | 44 #if defined(_WIN32) |
| 44 #include <Qos.h> | 45 #include <Qos.h> |
| 45 #endif | 46 #endif |
| 46 | 47 |
| 47 namespace webrtc { | 48 namespace webrtc { |
| 48 namespace voe { | 49 namespace voe { |
| 49 | 50 |
| 51 class RtcEventLogProxy : public webrtc::RtcEventLog { | |
|
the sun
2016/03/21 13:03:09
final
ivoc
2016/03/22 13:44:55
Done.
| |
| 52 public: | |
| 53 RtcEventLogProxy() : event_log_(nullptr) {} | |
| 54 | |
| 55 void SetBufferDuration(int64_t buffer_duration_us) { | |
|
the sun
2016/03/21 13:03:09
"override" here and below
ivoc
2016/03/22 13:44:55
Done.
| |
| 56 rtc::CritScope lock(&crit_); | |
| 57 if (event_log_) { | |
| 58 event_log_->SetBufferDuration(buffer_duration_us); | |
| 59 } | |
| 60 } | |
| 61 | |
| 62 void StartLogging(const std::string& file_name, int duration_ms) { | |
|
the sun
2016/03/21 13:03:09
It seems to me this method will never be called on
ivoc
2016/03/22 13:44:55
You're correct, done.
| |
| 63 rtc::CritScope lock(&crit_); | |
| 64 if (event_log_) { | |
| 65 event_log_->StartLogging(file_name, duration_ms); | |
| 66 } | |
| 67 } | |
| 68 | |
| 69 bool StartLogging(rtc::PlatformFile log_file, int64_t max_size_bytes) { | |
| 70 rtc::CritScope lock(&crit_); | |
| 71 if (event_log_) { | |
| 72 return event_log_->StartLogging(log_file, max_size_bytes); | |
| 73 } | |
| 74 return false; | |
| 75 } | |
| 76 | |
| 77 bool StartLogging(rtc::PlatformFile log_file) { | |
| 78 rtc::CritScope lock(&crit_); | |
| 79 if (event_log_) { | |
| 80 return event_log_->StartLogging(log_file); | |
| 81 } | |
| 82 return false; | |
| 83 } | |
| 84 | |
| 85 void StopLogging() { | |
| 86 rtc::CritScope lock(&crit_); | |
| 87 if (event_log_) { | |
| 88 event_log_->StopLogging(); | |
| 89 } | |
| 90 } | |
| 91 | |
| 92 void LogVideoReceiveStreamConfig( | |
| 93 const webrtc::VideoReceiveStream::Config& config) { | |
| 94 rtc::CritScope lock(&crit_); | |
| 95 RTC_DCHECK(event_log_); | |
| 96 event_log_->LogVideoReceiveStreamConfig(config); | |
| 97 } | |
| 98 | |
| 99 void LogVideoSendStreamConfig(const webrtc::VideoSendStream::Config& config) { | |
| 100 rtc::CritScope lock(&crit_); | |
| 101 RTC_DCHECK(event_log_); | |
| 102 event_log_->LogVideoSendStreamConfig(config); | |
| 103 } | |
| 104 | |
| 105 void LogRtpHeader(webrtc::PacketDirection direction, | |
| 106 webrtc::MediaType media_type, | |
| 107 const uint8_t* header, | |
| 108 size_t packet_length) { | |
| 109 rtc::CritScope lock(&crit_); | |
| 110 RTC_DCHECK(event_log_); | |
|
the sun
2016/03/21 13:03:09
I don't see why you can DCHECK here but have to us
ivoc
2016/03/22 13:44:55
I was thinking about the lifetimes of the AudioRec
the sun
2016/03/23 10:26:44
Well, that, and we must also account for the scena
| |
| 111 event_log_->LogRtpHeader(direction, media_type, header, packet_length); | |
| 112 } | |
| 113 | |
| 114 void LogRtcpPacket(webrtc::PacketDirection direction, | |
| 115 webrtc::MediaType media_type, | |
| 116 const uint8_t* packet, | |
| 117 size_t length) { | |
| 118 rtc::CritScope lock(&crit_); | |
| 119 RTC_DCHECK(event_log_); | |
| 120 event_log_->LogRtcpPacket(direction, media_type, packet, length); | |
| 121 } | |
| 122 | |
| 123 void LogAudioPlayout(uint32_t ssrc) { | |
| 124 rtc::CritScope lock(&crit_); | |
| 125 if (event_log_) { | |
| 126 event_log_->LogAudioPlayout(ssrc); | |
| 127 } | |
| 128 } | |
| 129 | |
| 130 void LogBwePacketLossEvent(int32_t bitrate, | |
| 131 uint8_t fraction_loss, | |
| 132 int32_t total_packets) { | |
| 133 rtc::CritScope lock(&crit_); | |
| 134 RTC_DCHECK(event_log_); | |
| 135 event_log_->LogBwePacketLossEvent(bitrate, fraction_loss, total_packets); | |
| 136 } | |
| 137 | |
| 138 static bool ParseRtcEventLog(const std::string& file_name, | |
|
the sun
2016/03/21 13:03:09
Remove
ivoc
2016/03/22 13:44:55
Done.
| |
| 139 webrtc::rtclog::EventStream* result); | |
| 140 | |
| 141 void SetEventLog(RtcEventLog* event_log) { | |
| 142 rtc::CritScope lock(&crit_); | |
| 143 event_log_ = event_log; | |
| 144 } | |
| 145 | |
| 146 private: | |
| 147 rtc::CriticalSection crit_; | |
| 148 RtcEventLog* event_log_ GUARDED_BY(crit_); | |
|
the sun
2016/03/21 13:03:09
RTC_DISALLOW_COPY_AND_ASSIGN
ivoc
2016/03/22 13:44:55
Done.
| |
| 149 }; | |
| 150 | |
| 50 class TransportFeedbackProxy : public TransportFeedbackObserver { | 151 class TransportFeedbackProxy : public TransportFeedbackObserver { |
| 51 public: | 152 public: |
| 52 TransportFeedbackProxy() : feedback_observer_(nullptr) { | 153 TransportFeedbackProxy() : feedback_observer_(nullptr) { |
| 53 pacer_thread_.DetachFromThread(); | 154 pacer_thread_.DetachFromThread(); |
| 54 network_thread_.DetachFromThread(); | 155 network_thread_.DetachFromThread(); |
| 55 } | 156 } |
| 56 | 157 |
| 57 void SetTransportFeedbackObserver( | 158 void SetTransportFeedbackObserver( |
| 58 TransportFeedbackObserver* feedback_observer) { | 159 TransportFeedbackObserver* feedback_observer) { |
| 59 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 160 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| (...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 487 return false; | 588 return false; |
| 488 } | 589 } |
| 489 header.payload_type_frequency = | 590 header.payload_type_frequency = |
| 490 rtp_payload_registry_->GetPayloadTypeFrequency(header.payloadType); | 591 rtp_payload_registry_->GetPayloadTypeFrequency(header.payloadType); |
| 491 if (header.payload_type_frequency < 0) | 592 if (header.payload_type_frequency < 0) |
| 492 return false; | 593 return false; |
| 493 return ReceivePacket(rtp_packet, rtp_packet_length, header, false); | 594 return ReceivePacket(rtp_packet, rtp_packet_length, header, false); |
| 494 } | 595 } |
| 495 | 596 |
| 496 int32_t Channel::GetAudioFrame(int32_t id, AudioFrame* audioFrame) { | 597 int32_t Channel::GetAudioFrame(int32_t id, AudioFrame* audioFrame) { |
| 497 if (event_log_) { | 598 unsigned int ssrc; |
| 498 unsigned int ssrc; | 599 RTC_CHECK_EQ(GetLocalSSRC(ssrc), 0); |
| 499 RTC_CHECK_EQ(GetLocalSSRC(ssrc), 0); | 600 event_log_->LogAudioPlayout(ssrc); |
| 500 event_log_->LogAudioPlayout(ssrc); | |
| 501 } | |
| 502 // Get 10ms raw PCM data from the ACM (mixer limits output frequency) | 601 // Get 10ms raw PCM data from the ACM (mixer limits output frequency) |
| 503 if (audio_coding_->PlayoutData10Ms(audioFrame->sample_rate_hz_, audioFrame) == | 602 if (audio_coding_->PlayoutData10Ms(audioFrame->sample_rate_hz_, audioFrame) == |
| 504 -1) { | 603 -1) { |
| 505 WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId, _channelId), | 604 WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId, _channelId), |
| 506 "Channel::GetAudioFrame() PlayoutData10Ms() failed!"); | 605 "Channel::GetAudioFrame() PlayoutData10Ms() failed!"); |
| 507 // In all likelihood, the audio in this frame is garbage. We return an | 606 // In all likelihood, the audio in this frame is garbage. We return an |
| 508 // error so that the audio mixer module doesn't add it to the mix. As | 607 // error so that the audio mixer module doesn't add it to the mix. As |
| 509 // a result, it won't be played out and the actions skipped here are | 608 // a result, it won't be played out and the actions skipped here are |
| 510 // irrelevant. | 609 // irrelevant. |
| 511 return -1; | 610 return -1; |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 667 } | 766 } |
| 668 } | 767 } |
| 669 } | 768 } |
| 670 | 769 |
| 671 return (highestNeeded); | 770 return (highestNeeded); |
| 672 } | 771 } |
| 673 | 772 |
| 674 int32_t Channel::CreateChannel(Channel*& channel, | 773 int32_t Channel::CreateChannel(Channel*& channel, |
| 675 int32_t channelId, | 774 int32_t channelId, |
| 676 uint32_t instanceId, | 775 uint32_t instanceId, |
| 677 RtcEventLog* const event_log, | |
| 678 const Config& config) { | 776 const Config& config) { |
| 679 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(instanceId, channelId), | 777 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(instanceId, channelId), |
| 680 "Channel::CreateChannel(channelId=%d, instanceId=%d)", channelId, | 778 "Channel::CreateChannel(channelId=%d, instanceId=%d)", channelId, |
| 681 instanceId); | 779 instanceId); |
| 682 | 780 |
| 683 channel = new Channel(channelId, instanceId, event_log, config); | 781 channel = new Channel(channelId, instanceId, config); |
| 684 if (channel == NULL) { | 782 if (channel == NULL) { |
| 685 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(instanceId, channelId), | 783 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(instanceId, channelId), |
| 686 "Channel::CreateChannel() unable to allocate memory for" | 784 "Channel::CreateChannel() unable to allocate memory for" |
| 687 " channel"); | 785 " channel"); |
| 688 return -1; | 786 return -1; |
| 689 } | 787 } |
| 690 return 0; | 788 return 0; |
| 691 } | 789 } |
| 692 | 790 |
| 693 void Channel::PlayNotification(int32_t id, uint32_t durationMs) { | 791 void Channel::PlayNotification(int32_t id, uint32_t durationMs) { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 730 assert(id == _outputFileRecorderId); | 828 assert(id == _outputFileRecorderId); |
| 731 | 829 |
| 732 rtc::CritScope cs(&_fileCritSect); | 830 rtc::CritScope cs(&_fileCritSect); |
| 733 | 831 |
| 734 _outputFileRecording = false; | 832 _outputFileRecording = false; |
| 735 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId, _channelId), | 833 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId, _channelId), |
| 736 "Channel::RecordFileEnded() => output file recorder module is" | 834 "Channel::RecordFileEnded() => output file recorder module is" |
| 737 " shutdown"); | 835 " shutdown"); |
| 738 } | 836 } |
| 739 | 837 |
| 740 Channel::Channel(int32_t channelId, | 838 Channel::Channel(int32_t channelId, uint32_t instanceId, const Config& config) |
| 741 uint32_t instanceId, | |
| 742 RtcEventLog* const event_log, | |
| 743 const Config& config) | |
| 744 : _instanceId(instanceId), | 839 : _instanceId(instanceId), |
| 745 _channelId(channelId), | 840 _channelId(channelId), |
| 746 event_log_(event_log), | 841 event_log_(new RtcEventLogProxy()), |
| 747 rtp_header_parser_(RtpHeaderParser::Create()), | 842 rtp_header_parser_(RtpHeaderParser::Create()), |
| 748 rtp_payload_registry_( | 843 rtp_payload_registry_( |
| 749 new RTPPayloadRegistry(RTPPayloadStrategy::CreateStrategy(true))), | 844 new RTPPayloadRegistry(RTPPayloadStrategy::CreateStrategy(true))), |
| 750 rtp_receive_statistics_( | 845 rtp_receive_statistics_( |
| 751 ReceiveStatistics::Create(Clock::GetRealTimeClock())), | 846 ReceiveStatistics::Create(Clock::GetRealTimeClock())), |
| 752 rtp_receiver_( | 847 rtp_receiver_( |
| 753 RtpReceiver::CreateAudioReceiver(Clock::GetRealTimeClock(), | 848 RtpReceiver::CreateAudioReceiver(Clock::GetRealTimeClock(), |
| 754 this, | 849 this, |
| 755 this, | 850 this, |
| 756 this, | 851 this, |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 845 configuration.outgoing_transport = this; | 940 configuration.outgoing_transport = this; |
| 846 configuration.audio_messages = this; | 941 configuration.audio_messages = this; |
| 847 configuration.receive_statistics = rtp_receive_statistics_.get(); | 942 configuration.receive_statistics = rtp_receive_statistics_.get(); |
| 848 configuration.bandwidth_callback = rtcp_observer_.get(); | 943 configuration.bandwidth_callback = rtcp_observer_.get(); |
| 849 if (pacing_enabled_) { | 944 if (pacing_enabled_) { |
| 850 configuration.paced_sender = rtp_packet_sender_proxy_.get(); | 945 configuration.paced_sender = rtp_packet_sender_proxy_.get(); |
| 851 configuration.transport_sequence_number_allocator = | 946 configuration.transport_sequence_number_allocator = |
| 852 seq_num_allocator_proxy_.get(); | 947 seq_num_allocator_proxy_.get(); |
| 853 configuration.transport_feedback_callback = feedback_observer_proxy_.get(); | 948 configuration.transport_feedback_callback = feedback_observer_proxy_.get(); |
| 854 } | 949 } |
| 855 configuration.event_log = event_log; | 950 configuration.event_log = &*event_log_; |
|
the sun
2016/03/21 13:03:09
nit: add () around *event_log_ for clarity.
ivoc
2016/03/22 13:44:55
Done.
| |
| 856 | 951 |
| 857 _rtpRtcpModule.reset(RtpRtcp::CreateRtpRtcp(configuration)); | 952 _rtpRtcpModule.reset(RtpRtcp::CreateRtpRtcp(configuration)); |
| 858 | 953 |
| 859 statistics_proxy_.reset(new StatisticsProxy(_rtpRtcpModule->SSRC())); | 954 statistics_proxy_.reset(new StatisticsProxy(_rtpRtcpModule->SSRC())); |
| 860 rtp_receive_statistics_->RegisterRtcpStatisticsCallback( | 955 rtp_receive_statistics_->RegisterRtcpStatisticsCallback( |
| 861 statistics_proxy_.get()); | 956 statistics_proxy_.get()); |
| 862 | 957 |
| 863 Config audioproc_config; | 958 Config audioproc_config; |
| 864 audioproc_config.Set<ExperimentalAgc>(new ExperimentalAgc(false)); | 959 audioproc_config.Set<ExperimentalAgc>(new ExperimentalAgc(false)); |
| 865 rx_audioproc_.reset(AudioProcessing::Create(audioproc_config)); | 960 rx_audioproc_.reset(AudioProcessing::Create(audioproc_config)); |
| (...skipping 2213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3079 rtc::CritScope lock(&assoc_send_channel_lock_); | 3174 rtc::CritScope lock(&assoc_send_channel_lock_); |
| 3080 Channel* channel = associate_send_channel_.channel(); | 3175 Channel* channel = associate_send_channel_.channel(); |
| 3081 if (channel && channel->ChannelId() == channel_id) { | 3176 if (channel && channel->ChannelId() == channel_id) { |
| 3082 // If this channel is associated with a send channel of the specified | 3177 // If this channel is associated with a send channel of the specified |
| 3083 // Channel ID, disassociate with it. | 3178 // Channel ID, disassociate with it. |
| 3084 ChannelOwner ref(NULL); | 3179 ChannelOwner ref(NULL); |
| 3085 associate_send_channel_ = ref; | 3180 associate_send_channel_ = ref; |
| 3086 } | 3181 } |
| 3087 } | 3182 } |
| 3088 | 3183 |
| 3184 void Channel::SetRtcEventLog(RtcEventLog* event_log) { | |
| 3185 event_log_->SetEventLog(event_log); | |
| 3186 } | |
| 3187 | |
| 3089 int Channel::RegisterExternalMediaProcessing(ProcessingTypes type, | 3188 int Channel::RegisterExternalMediaProcessing(ProcessingTypes type, |
| 3090 VoEMediaProcess& processObject) { | 3189 VoEMediaProcess& processObject) { |
| 3091 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), | 3190 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), |
| 3092 "Channel::RegisterExternalMediaProcessing()"); | 3191 "Channel::RegisterExternalMediaProcessing()"); |
| 3093 | 3192 |
| 3094 rtc::CritScope cs(&_callbackCritSect); | 3193 rtc::CritScope cs(&_callbackCritSect); |
| 3095 | 3194 |
| 3096 if (kPlaybackPerChannel == type) { | 3195 if (kPlaybackPerChannel == type) { |
| 3097 if (_outputExternalMediaCallbackPtr) { | 3196 if (_outputExternalMediaCallbackPtr) { |
| 3098 _engineStatisticsPtr->SetLastError( | 3197 _engineStatisticsPtr->SetLastError( |
| (...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3650 int64_t min_rtt = 0; | 3749 int64_t min_rtt = 0; |
| 3651 if (_rtpRtcpModule->RTT(remoteSSRC, &rtt, &avg_rtt, &min_rtt, &max_rtt) != | 3750 if (_rtpRtcpModule->RTT(remoteSSRC, &rtt, &avg_rtt, &min_rtt, &max_rtt) != |
| 3652 0) { | 3751 0) { |
| 3653 return 0; | 3752 return 0; |
| 3654 } | 3753 } |
| 3655 return rtt; | 3754 return rtt; |
| 3656 } | 3755 } |
| 3657 | 3756 |
| 3658 } // namespace voe | 3757 } // namespace voe |
| 3659 } // namespace webrtc | 3758 } // namespace webrtc |
| OLD | NEW |