Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |