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

Side by Side Diff: webrtc/modules/audio_coding/neteq/neteq_unittest.cc

Issue 2839163002: NetEq: Add functionality to assist with delay analysis and tooling (Closed)
Patch Set: Created 3 years, 7 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) 2011 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2011 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 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
263 bool expect_seq_no_wrap, bool expect_timestamp_wrap); 263 bool expect_seq_no_wrap, bool expect_timestamp_wrap);
264 264
265 void LongCngWithClockDrift(double drift_factor, 265 void LongCngWithClockDrift(double drift_factor,
266 double network_freeze_ms, 266 double network_freeze_ms,
267 bool pull_audio_during_freeze, 267 bool pull_audio_during_freeze,
268 int delay_tolerance_ms, 268 int delay_tolerance_ms,
269 int max_time_to_speech_ms); 269 int max_time_to_speech_ms);
270 270
271 void DuplicateCng(); 271 void DuplicateCng();
272 272
273 rtc::Optional<uint32_t> PlayoutTimestamp();
hlundin-webrtc 2017/04/26 11:41:31 This is unrelated, but I deleted this unnecessary
274
275 NetEq* neteq_; 273 NetEq* neteq_;
276 NetEq::Config config_; 274 NetEq::Config config_;
277 std::unique_ptr<test::RtpFileSource> rtp_source_; 275 std::unique_ptr<test::RtpFileSource> rtp_source_;
278 std::unique_ptr<test::Packet> packet_; 276 std::unique_ptr<test::Packet> packet_;
279 unsigned int sim_clock_; 277 unsigned int sim_clock_;
280 AudioFrame out_frame_; 278 AudioFrame out_frame_;
281 int output_sample_rate_; 279 int output_sample_rate_;
282 int algorithmic_delay_ms_; 280 int algorithmic_delay_ms_;
283 }; 281 };
284 282
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after
637 ++seq_no; 635 ++seq_no;
638 timestamp += kSamples; 636 timestamp += kSamples;
639 next_input_time_ms += static_cast<double>(kFrameSizeMs) * drift_factor; 637 next_input_time_ms += static_cast<double>(kFrameSizeMs) * drift_factor;
640 } 638 }
641 // Pull out data once. 639 // Pull out data once.
642 ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &muted)); 640 ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &muted));
643 ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_); 641 ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_);
644 } 642 }
645 643
646 EXPECT_EQ(AudioFrame::kNormalSpeech, out_frame_.speech_type_); 644 EXPECT_EQ(AudioFrame::kNormalSpeech, out_frame_.speech_type_);
647 rtc::Optional<uint32_t> playout_timestamp = PlayoutTimestamp(); 645 rtc::Optional<uint32_t> playout_timestamp = neteq_->GetPlayoutTimestamp();
648 ASSERT_TRUE(playout_timestamp); 646 ASSERT_TRUE(playout_timestamp);
649 int32_t delay_before = timestamp - *playout_timestamp; 647 int32_t delay_before = timestamp - *playout_timestamp;
650 648
651 // Insert CNG for 1 minute (= 60000 ms). 649 // Insert CNG for 1 minute (= 60000 ms).
652 const int kCngPeriodMs = 100; 650 const int kCngPeriodMs = 100;
653 const int kCngPeriodSamples = kCngPeriodMs * 16; // Period in 16 kHz samples. 651 const int kCngPeriodSamples = kCngPeriodMs * 16; // Period in 16 kHz samples.
654 const int kCngDurationMs = 60000; 652 const int kCngDurationMs = 60000;
655 for (; t_ms < kSpeechDurationMs + kCngDurationMs; t_ms += 10) { 653 for (; t_ms < kSpeechDurationMs + kCngDurationMs; t_ms += 10) {
656 // Each turn in this for loop is 10 ms. 654 // Each turn in this for loop is 10 ms.
657 while (next_input_time_ms <= t_ms) { 655 while (next_input_time_ms <= t_ms) {
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
729 // Pull out data once. 727 // Pull out data once.
730 ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &muted)); 728 ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &muted));
731 ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_); 729 ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_);
732 // Increase clock. 730 // Increase clock.
733 t_ms += 10; 731 t_ms += 10;
734 } 732 }
735 733
736 // Check that the speech starts again within reasonable time. 734 // Check that the speech starts again within reasonable time.
737 double time_until_speech_returns_ms = t_ms - speech_restart_time_ms; 735 double time_until_speech_returns_ms = t_ms - speech_restart_time_ms;
738 EXPECT_LT(time_until_speech_returns_ms, max_time_to_speech_ms); 736 EXPECT_LT(time_until_speech_returns_ms, max_time_to_speech_ms);
739 playout_timestamp = PlayoutTimestamp(); 737 playout_timestamp = neteq_->GetPlayoutTimestamp();
740 ASSERT_TRUE(playout_timestamp); 738 ASSERT_TRUE(playout_timestamp);
741 int32_t delay_after = timestamp - *playout_timestamp; 739 int32_t delay_after = timestamp - *playout_timestamp;
742 // Compare delay before and after, and make sure it differs less than 20 ms. 740 // Compare delay before and after, and make sure it differs less than 20 ms.
743 EXPECT_LE(delay_after, delay_before + delay_tolerance_ms * 16); 741 EXPECT_LE(delay_after, delay_before + delay_tolerance_ms * 16);
744 EXPECT_GE(delay_after, delay_before - delay_tolerance_ms * 16); 742 EXPECT_GE(delay_after, delay_before - delay_tolerance_ms * 16);
745 } 743 }
746 744
747 TEST_F(NetEqDecodingTest, LongCngWithNegativeClockDrift) { 745 TEST_F(NetEqDecodingTest, LongCngWithNegativeClockDrift) {
748 // Apply a clock drift of -25 ms / s (sender faster than receiver). 746 // Apply a clock drift of -25 ms / s (sender faster than receiver).
749 const double kDriftFactor = 1000.0 / (1000.0 + 25.0); 747 const double kDriftFactor = 1000.0 / (1000.0 + 25.0);
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after
1121 timestamp_wrapped |= timestamp < last_timestamp; 1119 timestamp_wrapped |= timestamp < last_timestamp;
1122 } 1120 }
1123 // Pull out data once. 1121 // Pull out data once.
1124 AudioFrame output; 1122 AudioFrame output;
1125 bool muted; 1123 bool muted;
1126 ASSERT_EQ(0, neteq_->GetAudio(&output, &muted)); 1124 ASSERT_EQ(0, neteq_->GetAudio(&output, &muted));
1127 ASSERT_EQ(kBlockSize16kHz, output.samples_per_channel_); 1125 ASSERT_EQ(kBlockSize16kHz, output.samples_per_channel_);
1128 ASSERT_EQ(1u, output.num_channels_); 1126 ASSERT_EQ(1u, output.num_channels_);
1129 1127
1130 // Expect delay (in samples) to be less than 2 packets. 1128 // Expect delay (in samples) to be less than 2 packets.
1131 rtc::Optional<uint32_t> playout_timestamp = PlayoutTimestamp(); 1129 rtc::Optional<uint32_t> playout_timestamp = neteq_->GetPlayoutTimestamp();
1132 ASSERT_TRUE(playout_timestamp); 1130 ASSERT_TRUE(playout_timestamp);
1133 EXPECT_LE(timestamp - *playout_timestamp, 1131 EXPECT_LE(timestamp - *playout_timestamp,
1134 static_cast<uint32_t>(kSamples * 2)); 1132 static_cast<uint32_t>(kSamples * 2));
1135 } 1133 }
1136 // Make sure we have actually tested wrap-around. 1134 // Make sure we have actually tested wrap-around.
1137 ASSERT_EQ(expect_seq_no_wrap, seq_no_wrapped); 1135 ASSERT_EQ(expect_seq_no_wrap, seq_no_wrapped);
1138 ASSERT_EQ(expect_timestamp_wrap, timestamp_wrapped); 1136 ASSERT_EQ(expect_timestamp_wrap, timestamp_wrapped);
1139 } 1137 }
1140 1138
1141 TEST_F(NetEqDecodingTest, SequenceNumberWrap) { 1139 TEST_F(NetEqDecodingTest, SequenceNumberWrap) {
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1200 PopulateCng(seq_no, timestamp, &rtp_info, payload, &payload_len); 1198 PopulateCng(seq_no, timestamp, &rtp_info, payload, &payload_len);
1201 // This is the first time this CNG packet is inserted. 1199 // This is the first time this CNG packet is inserted.
1202 ASSERT_EQ( 1200 ASSERT_EQ(
1203 0, neteq_->InsertPacket( 1201 0, neteq_->InsertPacket(
1204 rtp_info, rtc::ArrayView<const uint8_t>(payload, payload_len), 0)); 1202 rtp_info, rtc::ArrayView<const uint8_t>(payload, payload_len), 0));
1205 1203
1206 // Pull audio once and make sure CNG is played. 1204 // Pull audio once and make sure CNG is played.
1207 ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &muted)); 1205 ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &muted));
1208 ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_); 1206 ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_);
1209 EXPECT_EQ(AudioFrame::kCNG, out_frame_.speech_type_); 1207 EXPECT_EQ(AudioFrame::kCNG, out_frame_.speech_type_);
1210 EXPECT_FALSE(PlayoutTimestamp()); // Returns empty value during CNG. 1208 EXPECT_FALSE(
1209 neteq_->GetPlayoutTimestamp()); // Returns empty value during CNG.
1211 EXPECT_EQ(timestamp - algorithmic_delay_samples, 1210 EXPECT_EQ(timestamp - algorithmic_delay_samples,
1212 out_frame_.timestamp_ + out_frame_.samples_per_channel_); 1211 out_frame_.timestamp_ + out_frame_.samples_per_channel_);
1213 1212
1214 // Insert the same CNG packet again. Note that at this point it is old, since 1213 // Insert the same CNG packet again. Note that at this point it is old, since
1215 // we have already decoded the first copy of it. 1214 // we have already decoded the first copy of it.
1216 ASSERT_EQ( 1215 ASSERT_EQ(
1217 0, neteq_->InsertPacket( 1216 0, neteq_->InsertPacket(
1218 rtp_info, rtc::ArrayView<const uint8_t>(payload, payload_len), 0)); 1217 rtp_info, rtc::ArrayView<const uint8_t>(payload, payload_len), 0));
1219 1218
1220 // Pull audio until we have played |kCngPeriodMs| of CNG. Start at 10 ms since 1219 // Pull audio until we have played |kCngPeriodMs| of CNG. Start at 10 ms since
1221 // we have already pulled out CNG once. 1220 // we have already pulled out CNG once.
1222 for (int cng_time_ms = 10; cng_time_ms < kCngPeriodMs; cng_time_ms += 10) { 1221 for (int cng_time_ms = 10; cng_time_ms < kCngPeriodMs; cng_time_ms += 10) {
1223 ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &muted)); 1222 ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &muted));
1224 ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_); 1223 ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_);
1225 EXPECT_EQ(AudioFrame::kCNG, out_frame_.speech_type_); 1224 EXPECT_EQ(AudioFrame::kCNG, out_frame_.speech_type_);
1226 EXPECT_FALSE(PlayoutTimestamp()); // Returns empty value during CNG. 1225 EXPECT_FALSE(
1226 neteq_->GetPlayoutTimestamp()); // Returns empty value during CNG.
1227 EXPECT_EQ(timestamp - algorithmic_delay_samples, 1227 EXPECT_EQ(timestamp - algorithmic_delay_samples,
1228 out_frame_.timestamp_ + out_frame_.samples_per_channel_); 1228 out_frame_.timestamp_ + out_frame_.samples_per_channel_);
1229 } 1229 }
1230 1230
1231 // Insert speech again. 1231 // Insert speech again.
1232 ++seq_no; 1232 ++seq_no;
1233 timestamp += kCngPeriodSamples; 1233 timestamp += kCngPeriodSamples;
1234 PopulateRtpInfo(seq_no, timestamp, &rtp_info); 1234 PopulateRtpInfo(seq_no, timestamp, &rtp_info);
1235 ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, 0)); 1235 ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, 0));
1236 1236
1237 // Pull audio once and verify that the output is speech again. 1237 // Pull audio once and verify that the output is speech again.
1238 ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &muted)); 1238 ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &muted));
1239 ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_); 1239 ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_);
1240 EXPECT_EQ(AudioFrame::kNormalSpeech, out_frame_.speech_type_); 1240 EXPECT_EQ(AudioFrame::kNormalSpeech, out_frame_.speech_type_);
1241 rtc::Optional<uint32_t> playout_timestamp = PlayoutTimestamp(); 1241 rtc::Optional<uint32_t> playout_timestamp = neteq_->GetPlayoutTimestamp();
1242 ASSERT_TRUE(playout_timestamp); 1242 ASSERT_TRUE(playout_timestamp);
1243 EXPECT_EQ(timestamp + kSamples - algorithmic_delay_samples, 1243 EXPECT_EQ(timestamp + kSamples - algorithmic_delay_samples,
1244 *playout_timestamp); 1244 *playout_timestamp);
1245 } 1245 }
1246 1246
1247 rtc::Optional<uint32_t> NetEqDecodingTest::PlayoutTimestamp() {
1248 return neteq_->GetPlayoutTimestamp();
1249 }
1250
1251 TEST_F(NetEqDecodingTest, DiscardDuplicateCng) { DuplicateCng(); } 1247 TEST_F(NetEqDecodingTest, DiscardDuplicateCng) { DuplicateCng(); }
1252 1248
1253 TEST_F(NetEqDecodingTest, CngFirst) { 1249 TEST_F(NetEqDecodingTest, CngFirst) {
1254 uint16_t seq_no = 0; 1250 uint16_t seq_no = 0;
1255 uint32_t timestamp = 0; 1251 uint32_t timestamp = 0;
1256 const int kFrameSizeMs = 10; 1252 const int kFrameSizeMs = 10;
1257 const int kSampleRateKhz = 16; 1253 const int kSampleRateKhz = 16;
1258 const int kSamples = kFrameSizeMs * kSampleRateKhz; 1254 const int kSamples = kFrameSizeMs * kSampleRateKhz;
1259 const int kPayloadBytes = kSamples * 2; 1255 const int kPayloadBytes = kSamples * 2;
1260 const int kCngPeriodMs = 100; 1256 const int kCngPeriodMs = 100;
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after
1583 EXPECT_EQ(0, neteq2_->GetAudio(&out_frame2, &muted)); 1579 EXPECT_EQ(0, neteq2_->GetAudio(&out_frame2, &muted));
1584 if (muted) { 1580 if (muted) {
1585 EXPECT_TRUE(AudioFramesEqualExceptData(out_frame1, out_frame2)); 1581 EXPECT_TRUE(AudioFramesEqualExceptData(out_frame1, out_frame2));
1586 } else { 1582 } else {
1587 EXPECT_TRUE(AudioFramesEqual(out_frame1, out_frame2)); 1583 EXPECT_TRUE(AudioFramesEqual(out_frame1, out_frame2));
1588 } 1584 }
1589 } 1585 }
1590 EXPECT_FALSE(muted); 1586 EXPECT_FALSE(muted);
1591 } 1587 }
1592 1588
1589 TEST_F(NetEqDecodingTest, LastDecodedTimestampsEmpty) {
1590 EXPECT_TRUE(neteq_->LastDecodedTimestamps().empty());
1591
1592 // Pull out data once.
1593 AudioFrame output;
1594 bool muted;
1595 ASSERT_EQ(0, neteq_->GetAudio(&output, &muted));
1596
1597 EXPECT_TRUE(neteq_->LastDecodedTimestamps().empty());
1598 }
1599
1600 TEST_F(NetEqDecodingTest, LastDecodedTimestampsOneDecoded) {
1601 // Insert one packet with PCM16b WB data (this is what PopulateRtpInfo does by
1602 // default). Make the length 10 ms.
1603 constexpr size_t kPayloadSamples = 16 * 10;
1604 constexpr size_t kPayloadBytes = 2 * kPayloadSamples;
1605 uint8_t payload[kPayloadBytes] = {0};
1606
1607 RTPHeader rtp_info;
1608 constexpr uint32_t kRtpTimestamp = 0x1234;
1609 PopulateRtpInfo(0, kRtpTimestamp, &rtp_info);
1610 EXPECT_EQ(0, neteq_->InsertPacket(rtp_info, payload, 0));
1611
1612 // Pull out data once.
1613 AudioFrame output;
1614 bool muted;
1615 ASSERT_EQ(0, neteq_->GetAudio(&output, &muted));
1616
1617 // auto decoded_timestamps = neteq_->LastDecodedTimestamps();
AleBzk 2017/04/26 13:52:34 Did you forget to remove the comment above?
hlundin-webrtc 2017/04/26 14:11:39 Ooops! Thanks.
1618 EXPECT_EQ(std::vector<uint32_t>({kRtpTimestamp}),
1619 neteq_->LastDecodedTimestamps());
1620
1621 // Nothing decoded on the second call.
1622 ASSERT_EQ(0, neteq_->GetAudio(&output, &muted));
1623 EXPECT_TRUE(neteq_->LastDecodedTimestamps().empty());
1624 }
1625
1626 TEST_F(NetEqDecodingTest, LastDecodedTimestampsTwoDecoded) {
1627 // Insert two packets with PCM16b WB data (this is what PopulateRtpInfo does
1628 // by default). Make the length 5 ms so that NetEq must decode them both in
1629 // the same GetAudio call.
1630 constexpr size_t kPayloadSamples = 16 * 5;
1631 constexpr size_t kPayloadBytes = 2 * kPayloadSamples;
1632 uint8_t payload[kPayloadBytes] = {0};
1633
1634 RTPHeader rtp_info;
1635 constexpr uint32_t kRtpTimestamp1 = 0x1234;
1636 PopulateRtpInfo(0, kRtpTimestamp1, &rtp_info);
1637 EXPECT_EQ(0, neteq_->InsertPacket(rtp_info, payload, 0));
1638 constexpr uint32_t kRtpTimestamp2 = kRtpTimestamp1 + kPayloadSamples;
1639 PopulateRtpInfo(1, kRtpTimestamp2, &rtp_info);
1640 EXPECT_EQ(0, neteq_->InsertPacket(rtp_info, payload, 0));
1641
1642 // Pull out data once.
1643 AudioFrame output;
1644 bool muted;
1645 ASSERT_EQ(0, neteq_->GetAudio(&output, &muted));
1646
1647 // auto decoded_timestamps = neteq_->LastDecodedTimestamps();
1648 EXPECT_EQ(std::vector<uint32_t>({kRtpTimestamp1, kRtpTimestamp2}),
1649 neteq_->LastDecodedTimestamps());
1650 }
1651
1593 } // namespace webrtc 1652 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698