OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. | |
3 * | |
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 | |
6 * tree. An additional intellectual property rights grant can be found | |
7 * in the file PATENTS. All contributing project authors may | |
8 * be found in the AUTHORS file in the root of the source tree. | |
9 */ | |
10 | |
11 #include "webrtc/modules/audio_coding/neteq/tools/neteq_delay_analyzer.h" | |
12 | |
13 #include <algorithm> | |
14 #include <limits> | |
15 #include <utility> | |
16 | |
17 namespace webrtc { | |
18 namespace test { | |
19 | |
20 void NetEqDelayAnalyzer::AfterInsertPacket( | |
21 const test::NetEqInput::PacketData& packet, | |
22 NetEq* neteq) { | |
23 data_.insert( | |
24 std::make_pair(packet.header.timestamp, | |
25 TimingData(packet.header.sequenceNumber, packet.time_ms))); | |
26 } | |
27 | |
28 void NetEqDelayAnalyzer::BeforeGetAudio(NetEq* neteq) { | |
29 last_sync_buffer_ms_ = neteq->SyncBufferSizeMs(); | |
30 } | |
31 | |
32 void NetEqDelayAnalyzer::AfterGetAudio(int64_t time_now_ms, | |
33 const AudioFrame& audio_frame, | |
34 bool muted, | |
ivoc
2017/05/16 13:25:50
Since this is not used you can comment out the nam
hlundin-webrtc
2017/05/30 14:56:06
Done.
| |
35 NetEq* neteq) { | |
36 get_audio_time_ms_.push_back(time_now_ms); | |
37 // Check what timestamps were decoded in the last GetAudio call. | |
38 std::vector<uint32_t> dec_ts = neteq->LastDecodedTimestamps(); | |
39 // Find those timestamps in data_, insert their decoding time and sync | |
40 // delay. | |
41 for (uint32_t ts : dec_ts) { | |
42 auto it = data_.find(ts); | |
43 if (it == data_.end()) { | |
44 // This is a packet that was split out from another packet. Skip it. | |
45 continue; | |
46 } | |
47 RTC_CHECK(!it->second.decode_get_audio_count) | |
ivoc
2017/05/16 13:25:50
I think this code block would be easier to read wi
hlundin-webrtc
2017/05/30 14:56:06
Done.
| |
48 << "Decode time already written"; | |
49 it->second.decode_get_audio_count = | |
50 rtc::Optional<int64_t>(get_audio_count_); | |
51 RTC_CHECK(!it->second.sync_delay_ms) << "Decode time already written"; | |
52 it->second.sync_delay_ms = rtc::Optional<int64_t>(last_sync_buffer_ms_); | |
53 it->second.target_delay_ms = rtc::Optional<int>(neteq->TargetDelayMs()); | |
54 it->second.current_delay_ms = | |
55 rtc::Optional<int>(neteq->FilteredCurrentDelayMs()); | |
56 } | |
57 last_sample_rate_hz_ = audio_frame.sample_rate_hz_; | |
58 ++get_audio_count_; | |
59 } | |
60 | |
61 void NetEqDelayAnalyzer::CreateGraphs( | |
ivoc
2017/05/16 13:25:50
This function is pretty long, so you can consider
hlundin-webrtc
2017/05/30 14:56:06
Done.
| |
62 std::vector<float>* send_time_s, | |
63 std::vector<float>* arrival_delay_ms, | |
64 std::vector<float>* corrected_arrival_delay_ms, | |
65 std::vector<rtc::Optional<float>>* playout_delay_ms, | |
66 std::vector<rtc::Optional<float>>* target_delay_ms) const { | |
67 // Create nominal_get_audio_time_ms, a vector starting at | |
68 // get_audio_time_ms_[0] and increasing by 10 for each element. | |
69 std::vector<int64_t> nominal_get_audio_time_ms(get_audio_time_ms_.size()); | |
70 nominal_get_audio_time_ms[0] = get_audio_time_ms_[0]; | |
71 std::transform( | |
72 nominal_get_audio_time_ms.begin(), nominal_get_audio_time_ms.end() - 1, | |
ivoc
2017/05/16 13:25:50
Will this crash if nominal_get_audio_time_ms is em
hlundin-webrtc
2017/05/30 14:56:06
Presumably, but we already set the first element o
ivoc
2017/05/30 16:29:45
Acknowledged.
| |
73 nominal_get_audio_time_ms.begin() + 1, [](int64_t& x) { return x + 10; }); | |
74 RTC_DCHECK( | |
75 std::is_sorted(get_audio_time_ms_.begin(), get_audio_time_ms_.end())); | |
76 | |
77 std::vector<double> rtp_timestamps_ms; | |
78 std::vector<double> arrival_time_ms; | |
79 std::vector<double> corrected_arrival_time_ms; | |
80 std::vector<int64_t> decode_get_audio_count; | |
81 std::vector<int64_t> sync_delay_ms; | |
82 std::vector<int> raw_target_delay_ms; | |
83 std::vector<int> filtered_delay_ms; | |
84 double offset = std::numeric_limits<double>::max(); | |
85 | |
86 TimestampUnwrapper unwrapper; | |
87 for (auto& d : data_) { | |
ivoc
2017/05/16 13:25:50
Please add a comment to explain what this loop doe
hlundin-webrtc
2017/05/30 14:56:06
Done.
| |
88 rtp_timestamps_ms.push_back(unwrapper.Unwrap(d.first) / | |
89 (last_sample_rate_hz_ / 1000.f)); | |
90 arrival_time_ms.push_back(d.second.arrival_time_ms); | |
ivoc
2017/05/16 13:25:50
Also here I would suggest to introduce an intermed
hlundin-webrtc
2017/05/30 14:56:06
Done.
| |
91 offset = | |
92 std::min(offset, arrival_time_ms.back() - rtp_timestamps_ms.back()); | |
93 // Interpolate arrival times. | |
94 double x = d.second.arrival_time_ms; | |
95 // Find first element which is larger than x. | |
96 auto it = std::find_if(get_audio_time_ms_.begin(), get_audio_time_ms_.end(), | |
97 [x](int64_t v) -> bool { return v > x; }); | |
98 if (it == get_audio_time_ms_.end()) { | |
99 --it; | |
100 } | |
101 const size_t upper_ix = it - get_audio_time_ms_.begin(); | |
102 | |
103 size_t lower_ix; | |
104 if (upper_ix == 0 || get_audio_time_ms_[upper_ix] <= x) { | |
105 lower_ix = upper_ix; | |
106 } else { | |
107 lower_ix = upper_ix - 1; | |
108 } | |
109 double y; | |
ivoc
2017/05/16 13:25:50
The variable names are a bit cryptic in this funct
hlundin-webrtc
2017/05/30 14:56:06
I broke this part out to a generalized interpolati
| |
110 if (lower_ix == upper_ix) { | |
111 y = nominal_get_audio_time_ms[lower_ix]; | |
112 } else { | |
113 RTC_DCHECK_NE(get_audio_time_ms_[lower_ix], get_audio_time_ms_[upper_ix]); | |
114 y = (x - get_audio_time_ms_[lower_ix]) * | |
115 (nominal_get_audio_time_ms[upper_ix] - | |
116 nominal_get_audio_time_ms[lower_ix]) / | |
117 (get_audio_time_ms_[upper_ix] - get_audio_time_ms_[lower_ix]) + | |
118 nominal_get_audio_time_ms[lower_ix]; | |
119 } | |
120 corrected_arrival_time_ms.push_back(y); | |
121 | |
122 decode_get_audio_count.push_back( | |
123 d.second.decode_get_audio_count.value_or(-1)); | |
124 sync_delay_ms.push_back(d.second.sync_delay_ms.value_or(-1)); | |
125 raw_target_delay_ms.push_back(d.second.target_delay_ms.value_or(-1)); | |
126 filtered_delay_ms.push_back(d.second.current_delay_ms.value_or(-1)); | |
127 } | |
128 send_time_s->resize(rtp_timestamps_ms.size()); | |
129 std::transform(rtp_timestamps_ms.begin(), rtp_timestamps_ms.end(), | |
130 send_time_s->begin(), [rtp_timestamps_ms](double x) { | |
131 return (x - rtp_timestamps_ms[0]) / 1000.f; | |
132 }); | |
133 | |
134 RTC_DCHECK_EQ(send_time_s->size(), corrected_arrival_time_ms.size()); | |
135 RTC_DCHECK_EQ(send_time_s->size(), rtp_timestamps_ms.size()); | |
136 RTC_DCHECK_EQ(send_time_s->size(), decode_get_audio_count.size()); | |
137 for (size_t i = 0; i < send_time_s->size(); ++i) { | |
ivoc
2017/05/16 13:25:50
Please add a comment to explain what this for loop
hlundin-webrtc
2017/05/30 14:56:06
Done.
| |
138 const double y = | |
139 corrected_arrival_time_ms[i] - (rtp_timestamps_ms[i] + offset); | |
140 corrected_arrival_delay_ms->emplace_back(y); | |
ivoc
2017/05/16 13:25:50
This is exactly the same as push_back for a vector
hlundin-webrtc
2017/05/30 14:56:06
You are right. This is over-kill. I changed them a
| |
141 const double z = arrival_time_ms[i] - (rtp_timestamps_ms[i] + offset); | |
142 arrival_delay_ms->emplace_back(z); | |
143 | |
144 if (decode_get_audio_count[i] > -1) { | |
145 RTC_DCHECK_NE(sync_delay_ms[i], -1); | |
146 const float playout_ms = decode_get_audio_count[i] * 10 + | |
147 get_audio_time_ms_[0] + sync_delay_ms[i] - | |
148 (rtp_timestamps_ms[i] + offset); | |
149 playout_delay_ms->emplace_back(rtc::Optional<float>(playout_ms)); | |
150 RTC_DCHECK_GT(raw_target_delay_ms[i], -1); | |
151 RTC_DCHECK_GT(filtered_delay_ms[i], -1); | |
152 const float target = | |
153 playout_ms - filtered_delay_ms[i] + raw_target_delay_ms[i]; | |
154 target_delay_ms->emplace_back(rtc::Optional<float>(target)); | |
155 } else { | |
156 playout_delay_ms->emplace_back(rtc::Optional<float>()); | |
157 target_delay_ms->emplace_back(rtc::Optional<float>()); | |
158 } | |
159 } | |
160 RTC_DCHECK_EQ(send_time_s->size(), corrected_arrival_delay_ms->size()); | |
161 RTC_DCHECK_EQ(send_time_s->size(), playout_delay_ms->size()); | |
162 RTC_DCHECK_EQ(send_time_s->size(), target_delay_ms->size()); | |
163 } | |
164 | |
165 } // namespace test | |
166 } // namespace webrtc | |
OLD | NEW |