Adding NetEq lifetime stats to event log visualizer.

Bug: webrtc:9147
Change-Id: I798f8ac41192182d50df6fe98fbe56c8cb7f294c
Reviewed-on: https://webrtc-review.googlesource.com/85340
Commit-Queue: Minyue Li <minyue@webrtc.org>
Reviewed-by: Björn Terelius <terelius@webrtc.org>
Reviewed-by: Ivo Creusen <ivoc@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#23738}
This commit is contained in:
Minyue Li
2018-06-26 13:01:32 +02:00
committed by Commit Bot
parent 762289ed13
commit c9ac93fabb
5 changed files with 73 additions and 15 deletions

View File

@ -46,15 +46,17 @@ void NetEqStatsGetter::AfterGetAudio(int64_t time_now_ms,
NetEq* neteq) {
// TODO(minyue): Get stats should better not be called as a call back after
// get audio. It is called independently from get audio in practice.
const auto lifetime_stat = neteq->GetLifetimeStatistics();
if (last_stats_query_time_ms_ == 0 ||
rtc::TimeDiff(time_now_ms, last_stats_query_time_ms_) >=
stats_query_interval_ms_) {
NetEqNetworkStatistics stats;
RTC_CHECK_EQ(neteq->NetworkStatistics(&stats), 0);
stats_.push_back(std::make_pair(time_now_ms, stats));
lifetime_stats_.push_back(std::make_pair(time_now_ms, lifetime_stat));
last_stats_query_time_ms_ = time_now_ms;
}
const auto lifetime_stat = neteq->GetLifetimeStatistics();
if (current_concealment_event_ != lifetime_stat.concealment_events &&
voice_concealed_samples_until_last_event_ <
lifetime_stat.voice_concealed_samples) {

View File

@ -77,8 +77,13 @@ class NetEqStatsGetter : public NetEqGetAudioCallback {
return concealment_events_;
}
const std::vector<std::pair<int64_t, NetEqNetworkStatistics>>& stats() const {
return stats_;
const std::vector<std::pair<int64_t, NetEqNetworkStatistics>>* stats() const {
return &stats_;
}
const std::vector<std::pair<int64_t, NetEqLifetimeStatistics>>*
lifetime_stats() const {
return &lifetime_stats_;
}
Stats AverageStats() const;
@ -88,6 +93,7 @@ class NetEqStatsGetter : public NetEqGetAudioCallback {
int64_t stats_query_interval_ms_ = 1000;
int64_t last_stats_query_time_ms_ = 0;
std::vector<std::pair<int64_t, NetEqNetworkStatistics>> stats_;
std::vector<std::pair<int64_t, NetEqLifetimeStatistics>> lifetime_stats_;
size_t current_concealment_event_ = 1;
uint64_t voice_concealed_samples_until_last_event_ = 0;
std::vector<ConcealmentEvent> concealment_events_;

View File

@ -1844,20 +1844,23 @@ void EventLogAnalyzer::CreateAudioJitterBufferGraph(
plot->SetTitle("NetEq timing for " + GetStreamName(kIncomingPacket, ssrc));
}
void EventLogAnalyzer::CreateNetEqStatsGraph(
template <typename NetEqStatsType>
void EventLogAnalyzer::CreateNetEqStatsGraphInternal(
const NetEqStatsGetterMap& neteq_stats,
rtc::FunctionView<float(const NetEqNetworkStatistics&)> stats_extractor,
rtc::FunctionView<const std::vector<std::pair<int64_t, NetEqStatsType>>*(
const test::NetEqStatsGetter*)> data_extractor,
rtc::FunctionView<float(const NetEqStatsType&)> stats_extractor,
const std::string& plot_name,
Plot* plot) const {
std::map<uint32_t, TimeSeries> time_series;
for (const auto& st : neteq_stats) {
const uint32_t ssrc = st.first;
const auto& stats = st.second->stats();
for (size_t i = 0; i < stats.size(); ++i) {
const float time = ToCallTimeSec(stats[i].first * 1000); // ms to us.
const float value = stats_extractor(stats[i].second);
const std::vector<std::pair<int64_t, NetEqStatsType>>* data_vector =
data_extractor(st.second.get());
for (const auto& data : *data_vector) {
const float time = ToCallTimeSec(data.first * 1000); // ms to us.
const float value = stats_extractor(data.second);
time_series[ssrc].points.emplace_back(TimeSeriesPoint(time, value));
}
}
@ -1874,6 +1877,32 @@ void EventLogAnalyzer::CreateNetEqStatsGraph(
plot->SetTitle(plot_name);
}
void EventLogAnalyzer::CreateNetEqNetworkStatsGraph(
const NetEqStatsGetterMap& neteq_stats,
rtc::FunctionView<float(const NetEqNetworkStatistics&)> stats_extractor,
const std::string& plot_name,
Plot* plot) const {
CreateNetEqStatsGraphInternal<NetEqNetworkStatistics>(
neteq_stats,
[](const test::NetEqStatsGetter* stats_getter) {
return stats_getter->stats();
},
stats_extractor, plot_name, plot);
}
void EventLogAnalyzer::CreateNetEqLifetimeStatsGraph(
const NetEqStatsGetterMap& neteq_stats,
rtc::FunctionView<float(const NetEqLifetimeStatistics&)> stats_extractor,
const std::string& plot_name,
Plot* plot) const {
CreateNetEqStatsGraphInternal<NetEqLifetimeStatistics>(
neteq_stats,
[](const test::NetEqStatsGetter* stats_getter) {
return stats_getter->lifetime_stats();
},
stats_extractor, plot_name, plot);
}
void EventLogAnalyzer::CreateIceCandidatePairConfigGraph(Plot* plot) {
std::map<uint32_t, TimeSeries> configs_by_cp_id;
for (const auto& config : parsed_log_.ice_candidate_pair_configs()) {

View File

@ -76,14 +76,20 @@ class EventLogAnalyzer {
std::map<uint32_t, std::unique_ptr<test::NetEqStatsGetter>>;
NetEqStatsGetterMap SimulateNetEq(const std::string& replacement_file_name,
int file_sample_rate_hz) const;
void CreateAudioJitterBufferGraph(uint32_t ssrc,
const test::NetEqStatsGetter* stats_getter,
Plot* plot) const;
void CreateNetEqStatsGraph(
void CreateNetEqNetworkStatsGraph(
const NetEqStatsGetterMap& neteq_stats_getters,
rtc::FunctionView<float(const NetEqNetworkStatistics&)> stats_extractor,
const std::string& plot_name,
Plot* plot) const;
void CreateNetEqLifetimeStatsGraph(
const NetEqStatsGetterMap& neteq_stats_getters,
rtc::FunctionView<float(const NetEqLifetimeStatistics&)> stats_extractor,
const std::string& plot_name,
Plot* plot) const;
void CreateIceCandidatePairConfigGraph(Plot* plot);
void CreateIceConnectivityCheckGraph(Plot* plot);
@ -122,6 +128,15 @@ class EventLogAnalyzer {
}
}
template <typename NetEqStatsType>
void CreateNetEqStatsGraphInternal(
const NetEqStatsGetterMap& neteq_stats,
rtc::FunctionView<const std::vector<std::pair<int64_t, NetEqStatsType>>*(
const test::NetEqStatsGetter*)> data_extractor,
rtc::FunctionView<float(const NetEqStatsType&)> stats_extractor,
const std::string& plot_name,
Plot* plot) const;
template <typename IterableType>
void CreateAccumulatedPacketsTimeSeries(Plot* plot,
const IterableType& packets,

View File

@ -341,30 +341,36 @@ int main(int argc, char* argv[]) {
analyzer.CreateAudioJitterBufferGraph(it->first, it->second.get(),
collection->AppendNewPlot());
}
analyzer.CreateNetEqStatsGraph(
analyzer.CreateNetEqNetworkStatsGraph(
neteq_stats,
[](const webrtc::NetEqNetworkStatistics& stats) {
return stats.expand_rate / 16384.f;
},
"Expand rate", collection->AppendNewPlot());
analyzer.CreateNetEqStatsGraph(
analyzer.CreateNetEqNetworkStatsGraph(
neteq_stats,
[](const webrtc::NetEqNetworkStatistics& stats) {
return stats.speech_expand_rate / 16384.f;
},
"Speech expand rate", collection->AppendNewPlot());
analyzer.CreateNetEqStatsGraph(
analyzer.CreateNetEqNetworkStatsGraph(
neteq_stats,
[](const webrtc::NetEqNetworkStatistics& stats) {
return stats.accelerate_rate / 16384.f;
},
"Accelerate rate", collection->AppendNewPlot());
analyzer.CreateNetEqStatsGraph(
analyzer.CreateNetEqNetworkStatsGraph(
neteq_stats,
[](const webrtc::NetEqNetworkStatistics& stats) {
return stats.packet_loss_rate / 16384.f;
},
"Packet loss rate", collection->AppendNewPlot());
analyzer.CreateNetEqLifetimeStatsGraph(
neteq_stats,
[](const webrtc::NetEqLifetimeStatistics& stats) {
return static_cast<float>(stats.concealment_events);
},
"Concealment events", collection->AppendNewPlot());
}
if (FLAG_plot_ice_candidate_pair_config) {