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

Side by Side Diff: webrtc/audio/audio_receive_stream.cc

Issue 1390753002: Implement AudioReceiveStream::GetStats(). (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: rebase Created 5 years, 2 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
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2015 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/audio/audio_receive_stream.h" 11 #include "webrtc/audio/audio_receive_stream.h"
12 12
13 #include <string> 13 #include <string>
14 14
15 #include "webrtc/base/checks.h" 15 #include "webrtc/base/checks.h"
16 #include "webrtc/base/logging.h" 16 #include "webrtc/base/logging.h"
17 #include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimat or.h" 17 #include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimat or.h"
18 #include "webrtc/system_wrappers/interface/tick_util.h" 18 #include "webrtc/system_wrappers/interface/tick_util.h"
19 #include "webrtc/voice_engine/include/voe_base.h"
20 #include "webrtc/voice_engine/include/voe_codec.h"
21 #include "webrtc/voice_engine/include/voe_neteq_stats.h"
22 #include "webrtc/voice_engine/include/voe_rtp_rtcp.h"
23 #include "webrtc/voice_engine/include/voe_video_sync.h"
24 #include "webrtc/voice_engine/include/voe_volume_control.h"
25
26 namespace {
27 template<class T> class scoped_voe_interface {
tommi 2015/10/19 12:36:24 nit: ScopedVoEInterface (I know you're following t
the sun 2015/10/19 14:25:02 Done.
28 public:
29 explicit scoped_voe_interface(webrtc::VoiceEngine* e) : ptr(nullptr) {
30 RTC_DCHECK(e);
31 ptr = T::GetInterface(e);
tommi 2015/10/19 12:36:24 call T::GetInterface(e) in the initializer list
the sun 2015/10/19 14:25:02 Done.
32 }
33 ~scoped_voe_interface() {
34 if (ptr) ptr->Release();
tommi 2015/10/19 12:36:24 nit: two lines
the sun 2015/10/19 14:25:02 Done.
35 }
36 T* operator->() {
37 RTC_DCHECK(ptr);
38 return ptr;
39 }
40 private:
41 T* ptr;
tommi 2015/10/19 12:36:24 ptr_
the sun 2015/10/19 14:25:02 Done.
42 };
43 } // namespace {
19 44
20 namespace webrtc { 45 namespace webrtc {
21 std::string AudioReceiveStream::Config::Rtp::ToString() const { 46 std::string AudioReceiveStream::Config::Rtp::ToString() const {
22 std::stringstream ss; 47 std::stringstream ss;
23 ss << "{remote_ssrc: " << remote_ssrc; 48 ss << "{remote_ssrc: " << remote_ssrc;
24 ss << ", extensions: ["; 49 ss << ", extensions: [";
25 for (size_t i = 0; i < extensions.size(); ++i) { 50 for (size_t i = 0; i < extensions.size(); ++i) {
26 ss << extensions[i].ToString(); 51 ss << extensions[i].ToString();
27 if (i != extensions.size() - 1) 52 if (i != extensions.size() - 1)
28 ss << ", "; 53 ss << ", ";
29 } 54 }
30 ss << ']'; 55 ss << ']';
31 ss << '}'; 56 ss << '}';
32 return ss.str(); 57 return ss.str();
33 } 58 }
34 59
35 std::string AudioReceiveStream::Config::ToString() const { 60 std::string AudioReceiveStream::Config::ToString() const {
36 std::stringstream ss; 61 std::stringstream ss;
37 ss << "{rtp: " << rtp.ToString(); 62 ss << "{rtp: " << rtp.ToString();
38 ss << ", voe_channel_id: " << voe_channel_id; 63 ss << ", voe_channel_id: " << voe_channel_id;
39 if (!sync_group.empty()) 64 if (!sync_group.empty())
40 ss << ", sync_group: " << sync_group; 65 ss << ", sync_group: " << sync_group;
41 ss << '}'; 66 ss << '}';
42 return ss.str(); 67 return ss.str();
43 } 68 }
44 69
45 namespace internal { 70 namespace internal {
46 AudioReceiveStream::AudioReceiveStream( 71 AudioReceiveStream::AudioReceiveStream(
47 RemoteBitrateEstimator* remote_bitrate_estimator, 72 RemoteBitrateEstimator* remote_bitrate_estimator,
48 const webrtc::AudioReceiveStream::Config& config) 73 const webrtc::AudioReceiveStream::Config& config,
74 VoiceEngine* voice_engine)
49 : remote_bitrate_estimator_(remote_bitrate_estimator), 75 : remote_bitrate_estimator_(remote_bitrate_estimator),
50 config_(config), 76 config_(config),
77 voice_engine_(voice_engine),
51 rtp_header_parser_(RtpHeaderParser::Create()) { 78 rtp_header_parser_(RtpHeaderParser::Create()) {
52 LOG(LS_INFO) << "AudioReceiveStream: " << config_.ToString(); 79 LOG(LS_INFO) << "AudioReceiveStream: " << config_.ToString();
53 RTC_DCHECK(config.voe_channel_id != -1); 80 RTC_DCHECK(config.voe_channel_id != -1);
54 RTC_DCHECK(remote_bitrate_estimator_ != nullptr); 81 RTC_DCHECK(remote_bitrate_estimator_ != nullptr);
82 RTC_DCHECK(voice_engine_ != nullptr);
55 RTC_DCHECK(rtp_header_parser_ != nullptr); 83 RTC_DCHECK(rtp_header_parser_ != nullptr);
56 for (const auto& ext : config.rtp.extensions) { 84 for (const auto& ext : config.rtp.extensions) {
57 // One-byte-extension local identifiers are in the range 1-14 inclusive. 85 // One-byte-extension local identifiers are in the range 1-14 inclusive.
58 RTC_DCHECK_GE(ext.id, 1); 86 RTC_DCHECK_GE(ext.id, 1);
59 RTC_DCHECK_LE(ext.id, 14); 87 RTC_DCHECK_LE(ext.id, 14);
60 if (ext.name == RtpExtension::kAudioLevel) { 88 if (ext.name == RtpExtension::kAudioLevel) {
61 RTC_CHECK(rtp_header_parser_->RegisterRtpHeaderExtension( 89 RTC_CHECK(rtp_header_parser_->RegisterRtpHeaderExtension(
62 kRtpExtensionAudioLevel, ext.id)); 90 kRtpExtensionAudioLevel, ext.id));
63 } else if (ext.name == RtpExtension::kAbsSendTime) { 91 } else if (ext.name == RtpExtension::kAbsSendTime) {
64 RTC_CHECK(rtp_header_parser_->RegisterRtpHeaderExtension( 92 RTC_CHECK(rtp_header_parser_->RegisterRtpHeaderExtension(
65 kRtpExtensionAbsoluteSendTime, ext.id)); 93 kRtpExtensionAbsoluteSendTime, ext.id));
66 } else if (ext.name == RtpExtension::kTransportSequenceNumber) { 94 } else if (ext.name == RtpExtension::kTransportSequenceNumber) {
67 RTC_CHECK(rtp_header_parser_->RegisterRtpHeaderExtension( 95 RTC_CHECK(rtp_header_parser_->RegisterRtpHeaderExtension(
68 kRtpExtensionTransportSequenceNumber, ext.id)); 96 kRtpExtensionTransportSequenceNumber, ext.id));
69 } else { 97 } else {
70 RTC_NOTREACHED() << "Unsupported RTP extension."; 98 RTC_NOTREACHED() << "Unsupported RTP extension.";
71 } 99 }
72 } 100 }
73 } 101 }
74 102
75 AudioReceiveStream::~AudioReceiveStream() { 103 AudioReceiveStream::~AudioReceiveStream() {
76 LOG(LS_INFO) << "~AudioReceiveStream: " << config_.ToString(); 104 LOG(LS_INFO) << "~AudioReceiveStream: " << config_.ToString();
77 } 105 }
78 106
79 webrtc::AudioReceiveStream::Stats AudioReceiveStream::GetStats() const { 107 webrtc::AudioReceiveStream::Stats AudioReceiveStream::GetStats() const {
tommi 2015/10/19 12:36:24 Thread check?
the sun 2015/10/19 14:25:02 Done.
80 return webrtc::AudioReceiveStream::Stats(); 108 webrtc::AudioReceiveStream::Stats stats;
109 stats.remote_ssrc = config_.rtp.remote_ssrc;
110 scoped_voe_interface<VoECodec> codec(voice_engine_);
111 scoped_voe_interface<VoENetEqStats> neteq(voice_engine_);
112 scoped_voe_interface<VoERTP_RTCP> rtp(voice_engine_);
113 scoped_voe_interface<VoEVideoSync> sync(voice_engine_);
114 scoped_voe_interface<VoEVolumeControl> volume(voice_engine_);
115 unsigned int ssrc = 0;
tommi 2015/10/19 12:36:24 do we always use unsigned int for ssrc? do you kn
the sun 2015/10/19 14:25:02 We're pretty consistent with uint32_t for ssrcs. T
116 webrtc::CallStatistics cs = {0};
117 webrtc::CodecInst ci = {0};
118 // Only collect stats if we have seen some traffic with the SSRC.
119 if (rtp->GetRemoteSSRC(config_.voe_channel_id, ssrc) != -1 &&
120 rtp->GetRTCPStatistics(config_.voe_channel_id, cs) != -1 &&
121 codec->GetRecCodec(config_.voe_channel_id, ci) != -1) {
tommi 2015/10/19 12:36:24 nit: could we convert this to an early return inst
the sun 2015/10/19 14:25:02 Done.
122 stats.bytes_rcvd = cs.bytesReceived;
123 stats.packets_rcvd = cs.packetsReceived;
124 stats.packets_lost = cs.cumulativeLost;
125 stats.fraction_lost = static_cast<float>(cs.fractionLost) / (1 << 8);
126 if (ci.pltype != -1) {
tommi 2015/10/19 12:36:24 no {} (and below for single line if()s)
the sun 2015/10/19 14:25:02 please, point me to the style guide if I've missed
tommi 2015/10/19 14:55:44 Consistency. All I did was go up a few lines to se
the sun 2015/10/20 08:31:29 Oops, touché. Fixed that. Blaming sloppy copy+past
127 stats.codec_name = ci.plname;
128 }
129
130 stats.ext_seqnum = cs.extendedMax;
131 if (ci.plfreq / 1000 > 0) {
132 stats.jitter_ms = cs.jitterSamples / (ci.plfreq / 1000);
133 }
134 {
135 int jitter_buffer_delay_ms = 0;
136 int playout_buffer_delay_ms = 0;
137 sync->GetDelayEstimate(config_.voe_channel_id, &jitter_buffer_delay_ms,
138 &playout_buffer_delay_ms);
139 stats.delay_estimate_ms =
140 jitter_buffer_delay_ms + playout_buffer_delay_ms;
141 }
142 {
143 unsigned int level = 0;
tommi 2015/10/19 12:36:24 in some places we use uint32_t for this, but appar
the sun 2015/10/19 14:25:02 Yes, I consistently use the types specified in the
144 if (volume->GetSpeechOutputLevelFullRange(config_.voe_channel_id, level)
145 != -1) {
146 stats.audio_level = level;
tommi 2015/10/19 12:36:24 I wonder which type audio_level is
the sun 2015/10/19 14:25:02 Done.
147 };
tommi 2015/10/19 12:36:24 no ;
the sun 2015/10/19 14:25:02 thx
148 }
149
150 webrtc::NetworkStatistics ns = {0};
151 if (neteq->GetNetworkStatistics(config_.voe_channel_id, ns) != -1) {
152 // Get jitter buffer and total delay (alg + jitter + playout) stats.
153 stats.jitter_buffer_ms = ns.currentBufferSize;
154 stats.jitter_buffer_preferred_ms = ns.preferredBufferSize;
155 stats.expand_rate =
156 static_cast<float>(ns.currentExpandRate) / (1 << 14);
tommi 2015/10/19 12:36:24 can you add a note why we divide all the rates by
the sun 2015/10/19 14:25:02 Sure: https://code.google.com/p/chromium/codesearc
157 stats.speech_expand_rate =
158 static_cast<float>(ns.currentSpeechExpandRate) / (1 << 14);
159 stats.secondary_decoded_rate =
160 static_cast<float>(ns.currentSecondaryDecodedRate) / (1 << 14);
161 stats.accelerate_rate =
162 static_cast<float>(ns.currentAccelerateRate) / (1 << 14);
163 stats.preemptive_expand_rate =
164 static_cast<float>(ns.currentPreemptiveRate) / (1 << 14);
165 }
166
167 webrtc::AudioDecodingCallStats ds;
168 if (neteq->GetDecodingCallStatistics(config_.voe_channel_id, &ds) != -1) {
169 stats.decoding_calls_to_silence_generator =
170 ds.calls_to_silence_generator;
171 stats.decoding_calls_to_neteq = ds.calls_to_neteq;
172 stats.decoding_normal = ds.decoded_normal;
173 stats.decoding_plc = ds.decoded_plc;
174 stats.decoding_cng = ds.decoded_cng;
175 stats.decoding_plc_cng = ds.decoded_plc_cng;
176 }
177
178 stats.capture_start_ntp_time_ms = cs.capture_start_ntp_time_ms_;
179 }
180 return stats;
81 } 181 }
82 182
83 const webrtc::AudioReceiveStream::Config& AudioReceiveStream::config() const { 183 const webrtc::AudioReceiveStream::Config& AudioReceiveStream::config() const {
84 return config_; 184 return config_;
85 } 185 }
86 186
87 void AudioReceiveStream::Start() { 187 void AudioReceiveStream::Start() {
88 } 188 }
89 189
90 void AudioReceiveStream::Stop() { 190 void AudioReceiveStream::Stop() {
(...skipping 23 matching lines...) Expand all
114 if (packet_time.timestamp >= 0) 214 if (packet_time.timestamp >= 0)
115 arrival_time_ms = (packet_time.timestamp + 500) / 1000; 215 arrival_time_ms = (packet_time.timestamp + 500) / 1000;
116 size_t payload_size = length - header.headerLength; 216 size_t payload_size = length - header.headerLength;
117 remote_bitrate_estimator_->IncomingPacket(arrival_time_ms, payload_size, 217 remote_bitrate_estimator_->IncomingPacket(arrival_time_ms, payload_size,
118 header, false); 218 header, false);
119 } 219 }
120 return true; 220 return true;
121 } 221 }
122 } // namespace internal 222 } // namespace internal
123 } // namespace webrtc 223 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698