OLD | NEW |
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 "testing/gmock/include/gmock/gmock.h" | 11 #include "testing/gmock/include/gmock/gmock.h" |
12 #include "webrtc/base/scoped_ptr.h" | 12 #include "webrtc/base/scoped_ptr.h" |
13 #include "webrtc/modules/audio_coding/codecs/opus/interface/audio_decoder_opus.h
" | |
14 #include "webrtc/modules/audio_coding/neteq/tools/neteq_external_decoder_test.h" | 13 #include "webrtc/modules/audio_coding/neteq/tools/neteq_external_decoder_test.h" |
15 #include "webrtc/modules/audio_coding/neteq/tools/rtp_generator.h" | 14 #include "webrtc/modules/audio_coding/neteq/tools/rtp_generator.h" |
16 | 15 |
17 namespace webrtc { | 16 namespace webrtc { |
18 namespace test { | 17 namespace test { |
19 | 18 |
20 using ::testing::_; | 19 using ::testing::_; |
21 using ::testing::SetArgPointee; | 20 using ::testing::SetArgPointee; |
22 using ::testing::Return; | 21 using ::testing::Return; |
23 | 22 |
24 | 23 class MockAudioDecoder final : public AudioDecoder { |
25 class MockAudioDecoderOpus : public AudioDecoderOpus { | |
26 public: | 24 public: |
27 static const int kPacketDuration = 960; // 48 kHz * 20 ms | 25 static const int kPacketDuration = 960; // 48 kHz * 20 ms |
28 | 26 |
29 explicit MockAudioDecoderOpus(int num_channels) | 27 explicit MockAudioDecoder(size_t num_channels) |
30 : AudioDecoderOpus(num_channels), | 28 : num_channels_(num_channels), fec_enabled_(false) { |
31 fec_enabled_(false) { | |
32 } | 29 } |
33 virtual ~MockAudioDecoderOpus() { Die(); } | 30 ~MockAudioDecoder() override { Die(); } |
34 MOCK_METHOD0(Die, void()); | 31 MOCK_METHOD0(Die, void()); |
35 | 32 |
36 MOCK_METHOD0(Reset, void()); | 33 MOCK_METHOD0(Reset, void()); |
37 | 34 |
38 int PacketDuration(const uint8_t* encoded, | 35 int PacketDuration(const uint8_t* encoded, |
39 size_t encoded_len) const override { | 36 size_t encoded_len) const override { |
40 return kPacketDuration; | 37 return kPacketDuration; |
41 } | 38 } |
42 | 39 |
43 int PacketDurationRedundant(const uint8_t* encoded, | 40 int PacketDurationRedundant(const uint8_t* encoded, |
44 size_t encoded_len) const override { | 41 size_t encoded_len) const override { |
45 return kPacketDuration; | 42 return kPacketDuration; |
46 } | 43 } |
47 | 44 |
48 bool PacketHasFec(const uint8_t* encoded, size_t encoded_len) const override { | 45 bool PacketHasFec(const uint8_t* encoded, size_t encoded_len) const override { |
49 return fec_enabled_; | 46 return fec_enabled_; |
50 } | 47 } |
51 | 48 |
| 49 size_t Channels() const override { return num_channels_; } |
| 50 |
52 void set_fec_enabled(bool enable_fec) { fec_enabled_ = enable_fec; } | 51 void set_fec_enabled(bool enable_fec) { fec_enabled_ = enable_fec; } |
53 | 52 |
54 bool fec_enabled() const { return fec_enabled_; } | 53 bool fec_enabled() const { return fec_enabled_; } |
55 | 54 |
56 protected: | 55 protected: |
57 // Override the following methods such that no actual payload is needed. | 56 // Override the following methods such that no actual payload is needed. |
58 int DecodeInternal(const uint8_t* encoded, | 57 int DecodeInternal(const uint8_t* encoded, |
59 size_t encoded_len, | 58 size_t encoded_len, |
60 int /*sample_rate_hz*/, | 59 int /*sample_rate_hz*/, |
61 int16_t* decoded, | 60 int16_t* decoded, |
62 SpeechType* speech_type) override { | 61 SpeechType* speech_type) override { |
63 *speech_type = kSpeech; | 62 *speech_type = kSpeech; |
64 memset(decoded, 0, sizeof(int16_t) * kPacketDuration * Channels()); | 63 memset(decoded, 0, sizeof(int16_t) * kPacketDuration * Channels()); |
65 return kPacketDuration * Channels(); | 64 return kPacketDuration * Channels(); |
66 } | 65 } |
67 | 66 |
68 int DecodeRedundantInternal(const uint8_t* encoded, | 67 int DecodeRedundantInternal(const uint8_t* encoded, |
69 size_t encoded_len, | 68 size_t encoded_len, |
70 int sample_rate_hz, | 69 int sample_rate_hz, |
71 int16_t* decoded, | 70 int16_t* decoded, |
72 SpeechType* speech_type) override { | 71 SpeechType* speech_type) override { |
73 return DecodeInternal(encoded, encoded_len, sample_rate_hz, decoded, | 72 return DecodeInternal(encoded, encoded_len, sample_rate_hz, decoded, |
74 speech_type); | 73 speech_type); |
75 } | 74 } |
76 | 75 |
77 private: | 76 private: |
| 77 const size_t num_channels_; |
78 bool fec_enabled_; | 78 bool fec_enabled_; |
79 }; | 79 }; |
80 | 80 |
81 class NetEqNetworkStatsTest : public NetEqExternalDecoderTest { | 81 class NetEqNetworkStatsTest : public NetEqExternalDecoderTest { |
82 public: | 82 public: |
83 static const int kPayloadSizeByte = 30; | 83 static const int kPayloadSizeByte = 30; |
84 static const int kFrameSizeMs = 20; // frame size of Opus | 84 static const int kFrameSizeMs = 20; |
85 static const int kMaxOutputSize = 960; // 10 ms * 48 kHz * 2 channels. | 85 static const int kMaxOutputSize = 960; // 10 ms * 48 kHz * 2 channels. |
86 | 86 |
87 enum logic { | 87 enum logic { |
88 IGNORE, | 88 IGNORE, |
89 EQUAL, | 89 EQUAL, |
90 SMALLER_THAN, | 90 SMALLER_THAN, |
91 LARGER_THAN, | 91 LARGER_THAN, |
92 }; | 92 }; |
93 | 93 |
94 struct NetEqNetworkStatsCheck { | 94 struct NetEqNetworkStatsCheck { |
95 logic current_buffer_size_ms; | 95 logic current_buffer_size_ms; |
96 logic preferred_buffer_size_ms; | 96 logic preferred_buffer_size_ms; |
97 logic jitter_peaks_found; | 97 logic jitter_peaks_found; |
98 logic packet_loss_rate; | 98 logic packet_loss_rate; |
99 logic packet_discard_rate; | 99 logic packet_discard_rate; |
100 logic expand_rate; | 100 logic expand_rate; |
101 logic speech_expand_rate; | 101 logic speech_expand_rate; |
102 logic preemptive_rate; | 102 logic preemptive_rate; |
103 logic accelerate_rate; | 103 logic accelerate_rate; |
104 logic secondary_decoded_rate; | 104 logic secondary_decoded_rate; |
105 logic clockdrift_ppm; | 105 logic clockdrift_ppm; |
106 logic added_zero_samples; | 106 logic added_zero_samples; |
107 NetEqNetworkStatistics stats_ref; | 107 NetEqNetworkStatistics stats_ref; |
108 }; | 108 }; |
109 | 109 |
110 NetEqNetworkStatsTest(NetEqDecoder codec, | 110 NetEqNetworkStatsTest(NetEqDecoder codec, |
111 MockAudioDecoderOpus* decoder) | 111 MockAudioDecoder* decoder) |
112 : NetEqExternalDecoderTest(codec, decoder), | 112 : NetEqExternalDecoderTest(codec, decoder), |
113 external_decoder_(decoder), | 113 external_decoder_(decoder), |
114 samples_per_ms_(CodecSampleRateHz(codec) / 1000), | 114 samples_per_ms_(CodecSampleRateHz(codec) / 1000), |
115 frame_size_samples_(kFrameSizeMs * samples_per_ms_), | 115 frame_size_samples_(kFrameSizeMs * samples_per_ms_), |
116 rtp_generator_(new test::RtpGenerator(samples_per_ms_)), | 116 rtp_generator_(new test::RtpGenerator(samples_per_ms_)), |
117 last_lost_time_(0), | 117 last_lost_time_(0), |
118 packet_loss_interval_(0xffffffff) { | 118 packet_loss_interval_(0xffffffff) { |
119 Init(); | 119 Init(); |
120 } | 120 } |
121 | 121 |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
220 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} | 220 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} |
221 }; | 221 }; |
222 RunTest(50, expects); | 222 RunTest(50, expects); |
223 | 223 |
224 // Next we introduce packet losses. | 224 // Next we introduce packet losses. |
225 SetPacketLossRate(0.1); | 225 SetPacketLossRate(0.1); |
226 expects.stats_ref.packet_loss_rate = 1337; | 226 expects.stats_ref.packet_loss_rate = 1337; |
227 expects.stats_ref.expand_rate = expects.stats_ref.speech_expand_rate = 1065; | 227 expects.stats_ref.expand_rate = expects.stats_ref.speech_expand_rate = 1065; |
228 RunTest(50, expects); | 228 RunTest(50, expects); |
229 | 229 |
230 // Next we enable Opus FEC. | 230 // Next we enable FEC. |
231 external_decoder_->set_fec_enabled(true); | 231 external_decoder_->set_fec_enabled(true); |
232 // If FEC fills in the lost packets, no packet loss will be counted. | 232 // If FEC fills in the lost packets, no packet loss will be counted. |
233 expects.stats_ref.packet_loss_rate = 0; | 233 expects.stats_ref.packet_loss_rate = 0; |
234 expects.stats_ref.expand_rate = expects.stats_ref.speech_expand_rate = 0; | 234 expects.stats_ref.expand_rate = expects.stats_ref.speech_expand_rate = 0; |
235 expects.stats_ref.secondary_decoded_rate = 2006; | 235 expects.stats_ref.secondary_decoded_rate = 2006; |
236 RunTest(50, expects); | 236 RunTest(50, expects); |
237 } | 237 } |
238 | 238 |
239 void NoiseExpansionTest() { | 239 void NoiseExpansionTest() { |
240 NetEqNetworkStatsCheck expects = { | 240 NetEqNetworkStatsCheck expects = { |
(...skipping 13 matching lines...) Expand all Loading... |
254 }; | 254 }; |
255 RunTest(50, expects); | 255 RunTest(50, expects); |
256 | 256 |
257 SetPacketLossRate(1); | 257 SetPacketLossRate(1); |
258 expects.stats_ref.expand_rate = 16384; | 258 expects.stats_ref.expand_rate = 16384; |
259 expects.stats_ref.speech_expand_rate = 5324; | 259 expects.stats_ref.speech_expand_rate = 5324; |
260 RunTest(10, expects); // Lost 10 * 20ms in a row. | 260 RunTest(10, expects); // Lost 10 * 20ms in a row. |
261 } | 261 } |
262 | 262 |
263 private: | 263 private: |
264 MockAudioDecoderOpus* external_decoder_; | 264 MockAudioDecoder* external_decoder_; |
265 const int samples_per_ms_; | 265 const int samples_per_ms_; |
266 const size_t frame_size_samples_; | 266 const size_t frame_size_samples_; |
267 rtc::scoped_ptr<test::RtpGenerator> rtp_generator_; | 267 rtc::scoped_ptr<test::RtpGenerator> rtp_generator_; |
268 WebRtcRTPHeader rtp_header_; | 268 WebRtcRTPHeader rtp_header_; |
269 uint32_t last_lost_time_; | 269 uint32_t last_lost_time_; |
270 uint32_t packet_loss_interval_; | 270 uint32_t packet_loss_interval_; |
271 uint8_t payload_[kPayloadSizeByte]; | 271 uint8_t payload_[kPayloadSizeByte]; |
272 int16_t output_[kMaxOutputSize]; | 272 int16_t output_[kMaxOutputSize]; |
273 }; | 273 }; |
274 | 274 |
275 TEST(NetEqNetworkStatsTest, OpusDecodeFec) { | 275 TEST(NetEqNetworkStatsTest, DecodeFec) { |
276 MockAudioDecoderOpus decoder(1); | 276 MockAudioDecoder decoder(1); |
277 NetEqNetworkStatsTest test(kDecoderOpus, &decoder); | 277 NetEqNetworkStatsTest test(kDecoderOpus, &decoder); |
278 test.DecodeFecTest(); | 278 test.DecodeFecTest(); |
279 EXPECT_CALL(decoder, Die()).Times(1); | 279 EXPECT_CALL(decoder, Die()).Times(1); |
280 } | 280 } |
281 | 281 |
282 TEST(NetEqNetworkStatsTest, StereoOpusDecodeFec) { | 282 TEST(NetEqNetworkStatsTest, StereoDecodeFec) { |
283 MockAudioDecoderOpus decoder(2); | 283 MockAudioDecoder decoder(2); |
284 NetEqNetworkStatsTest test(kDecoderOpus, &decoder); | 284 NetEqNetworkStatsTest test(kDecoderOpus, &decoder); |
285 test.DecodeFecTest(); | 285 test.DecodeFecTest(); |
286 EXPECT_CALL(decoder, Die()).Times(1); | 286 EXPECT_CALL(decoder, Die()).Times(1); |
287 } | 287 } |
288 | 288 |
289 TEST(NetEqNetworkStatsTest, NoiseExpansionTest) { | 289 TEST(NetEqNetworkStatsTest, NoiseExpansionTest) { |
290 MockAudioDecoderOpus decoder(1); | 290 MockAudioDecoder decoder(1); |
291 NetEqNetworkStatsTest test(kDecoderOpus, &decoder); | 291 NetEqNetworkStatsTest test(kDecoderOpus, &decoder); |
292 test.NoiseExpansionTest(); | 292 test.NoiseExpansionTest(); |
293 EXPECT_CALL(decoder, Die()).Times(1); | 293 EXPECT_CALL(decoder, Die()).Times(1); |
294 } | 294 } |
295 | 295 |
296 } // namespace test | 296 } // namespace test |
297 } // namespace webrtc | 297 } // namespace webrtc |
298 | 298 |
299 | 299 |
300 | 300 |
301 | 301 |
OLD | NEW |