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

Side by Side Diff: webrtc/modules/audio_coding/acm2/acm_receiver_unittest_oldapi.cc

Issue 2387113005: Drop _oldapi from ACM test file names (Closed)
Patch Set: Created 4 years, 2 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
(Empty)
1 /*
2 * Copyright (c) 2013 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/acm2/acm_receiver.h"
12
13 #include <algorithm> // std::min
14 #include <memory>
15
16 #include "webrtc/base/checks.h"
17 #include "webrtc/base/safe_conversions.h"
18 #include "webrtc/modules/audio_coding/codecs/builtin_audio_decoder_factory.h"
19 #include "webrtc/modules/audio_coding/include/audio_coding_module.h"
20 #include "webrtc/modules/audio_coding/neteq/tools/rtp_generator.h"
21 #include "webrtc/system_wrappers/include/clock.h"
22 #include "webrtc/test/gtest.h"
23 #include "webrtc/test/test_suite.h"
24 #include "webrtc/test/testsupport/fileutils.h"
25
26 namespace webrtc {
27
28 namespace acm2 {
29 namespace {
30
31 bool CodecsEqual(const CodecInst& codec_a, const CodecInst& codec_b) {
32 if (strcmp(codec_a.plname, codec_b.plname) != 0 ||
33 codec_a.plfreq != codec_b.plfreq ||
34 codec_a.pltype != codec_b.pltype ||
35 codec_b.channels != codec_a.channels)
36 return false;
37 return true;
38 }
39
40 struct CodecIdInst {
41 explicit CodecIdInst(RentACodec::CodecId codec_id) {
42 const auto codec_ix = RentACodec::CodecIndexFromId(codec_id);
43 EXPECT_TRUE(codec_ix);
44 id = *codec_ix;
45 const auto codec_inst = RentACodec::CodecInstById(codec_id);
46 EXPECT_TRUE(codec_inst);
47 inst = *codec_inst;
48 }
49 int id;
50 CodecInst inst;
51 };
52
53 } // namespace
54
55 class AcmReceiverTestOldApi : public AudioPacketizationCallback,
56 public ::testing::Test {
57 protected:
58 AcmReceiverTestOldApi()
59 : timestamp_(0),
60 packet_sent_(false),
61 last_packet_send_timestamp_(timestamp_),
62 last_frame_type_(kEmptyFrame) {
63 config_.decoder_factory = CreateBuiltinAudioDecoderFactory();
64 }
65
66 ~AcmReceiverTestOldApi() {}
67
68 void SetUp() override {
69 acm_.reset(AudioCodingModule::Create(config_));
70 receiver_.reset(new AcmReceiver(config_));
71 ASSERT_TRUE(receiver_.get() != NULL);
72 ASSERT_TRUE(acm_.get() != NULL);
73 codecs_ = RentACodec::Database();
74
75 acm_->InitializeReceiver();
76 acm_->RegisterTransportCallback(this);
77
78 rtp_header_.header.sequenceNumber = 0;
79 rtp_header_.header.timestamp = 0;
80 rtp_header_.header.markerBit = false;
81 rtp_header_.header.ssrc = 0x12345678; // Arbitrary.
82 rtp_header_.header.numCSRCs = 0;
83 rtp_header_.header.payloadType = 0;
84 rtp_header_.frameType = kAudioFrameSpeech;
85 rtp_header_.type.Audio.isCNG = false;
86 }
87
88 void TearDown() override {}
89
90 void InsertOnePacketOfSilence(int codec_id) {
91 CodecInst codec =
92 *RentACodec::CodecInstById(*RentACodec::CodecIdFromIndex(codec_id));
93 if (timestamp_ == 0) { // This is the first time inserting audio.
94 ASSERT_EQ(0, acm_->RegisterSendCodec(codec));
95 } else {
96 auto current_codec = acm_->SendCodec();
97 ASSERT_TRUE(current_codec);
98 if (!CodecsEqual(codec, *current_codec))
99 ASSERT_EQ(0, acm_->RegisterSendCodec(codec));
100 }
101 AudioFrame frame;
102 // Frame setup according to the codec.
103 frame.sample_rate_hz_ = codec.plfreq;
104 frame.samples_per_channel_ = codec.plfreq / 100; // 10 ms.
105 frame.num_channels_ = codec.channels;
106 memset(frame.data_, 0, frame.samples_per_channel_ * frame.num_channels_ *
107 sizeof(int16_t));
108 packet_sent_ = false;
109 last_packet_send_timestamp_ = timestamp_;
110 while (!packet_sent_) {
111 frame.timestamp_ = timestamp_;
112 timestamp_ += frame.samples_per_channel_;
113 ASSERT_GE(acm_->Add10MsData(frame), 0);
114 }
115 }
116
117 template <size_t N>
118 void AddSetOfCodecs(const RentACodec::CodecId(&ids)[N]) {
119 for (auto id : ids) {
120 const auto i = RentACodec::CodecIndexFromId(id);
121 ASSERT_TRUE(i);
122 ASSERT_EQ(0, receiver_->AddCodec(*i, codecs_[*i].pltype,
123 codecs_[*i].channels, codecs_[*i].plfreq,
124 nullptr, codecs_[*i].plname));
125 }
126 }
127
128 int SendData(FrameType frame_type,
129 uint8_t payload_type,
130 uint32_t timestamp,
131 const uint8_t* payload_data,
132 size_t payload_len_bytes,
133 const RTPFragmentationHeader* fragmentation) override {
134 if (frame_type == kEmptyFrame)
135 return 0;
136
137 rtp_header_.header.payloadType = payload_type;
138 rtp_header_.frameType = frame_type;
139 if (frame_type == kAudioFrameSpeech)
140 rtp_header_.type.Audio.isCNG = false;
141 else
142 rtp_header_.type.Audio.isCNG = true;
143 rtp_header_.header.timestamp = timestamp;
144
145 int ret_val = receiver_->InsertPacket(
146 rtp_header_,
147 rtc::ArrayView<const uint8_t>(payload_data, payload_len_bytes));
148 if (ret_val < 0) {
149 assert(false);
150 return -1;
151 }
152 rtp_header_.header.sequenceNumber++;
153 packet_sent_ = true;
154 last_frame_type_ = frame_type;
155 return 0;
156 }
157
158 AudioCodingModule::Config config_;
159 std::unique_ptr<AcmReceiver> receiver_;
160 rtc::ArrayView<const CodecInst> codecs_;
161 std::unique_ptr<AudioCodingModule> acm_;
162 WebRtcRTPHeader rtp_header_;
163 uint32_t timestamp_;
164 bool packet_sent_; // Set when SendData is called reset when inserting audio.
165 uint32_t last_packet_send_timestamp_;
166 FrameType last_frame_type_;
167 };
168
169 #if defined(WEBRTC_ANDROID)
170 #define MAYBE_AddCodecGetCodec DISABLED_AddCodecGetCodec
171 #else
172 #define MAYBE_AddCodecGetCodec AddCodecGetCodec
173 #endif
174 TEST_F(AcmReceiverTestOldApi, MAYBE_AddCodecGetCodec) {
175 // Add codec.
176 for (size_t n = 0; n < codecs_.size(); ++n) {
177 if (n & 0x1) { // Just add codecs with odd index.
178 EXPECT_EQ(
179 0, receiver_->AddCodec(n, codecs_[n].pltype, codecs_[n].channels,
180 codecs_[n].plfreq, NULL, codecs_[n].plname));
181 }
182 }
183 // Get codec and compare.
184 for (size_t n = 0; n < codecs_.size(); ++n) {
185 CodecInst my_codec;
186 if (n & 0x1) {
187 // Codecs with odd index should match the reference.
188 EXPECT_EQ(0, receiver_->DecoderByPayloadType(codecs_[n].pltype,
189 &my_codec));
190 EXPECT_TRUE(CodecsEqual(codecs_[n], my_codec));
191 } else {
192 // Codecs with even index are not registered.
193 EXPECT_EQ(-1, receiver_->DecoderByPayloadType(codecs_[n].pltype,
194 &my_codec));
195 }
196 }
197 }
198
199 #if defined(WEBRTC_ANDROID)
200 #define MAYBE_AddCodecChangePayloadType DISABLED_AddCodecChangePayloadType
201 #else
202 #define MAYBE_AddCodecChangePayloadType AddCodecChangePayloadType
203 #endif
204 TEST_F(AcmReceiverTestOldApi, MAYBE_AddCodecChangePayloadType) {
205 const CodecIdInst codec1(RentACodec::CodecId::kPCMA);
206 CodecInst codec2 = codec1.inst;
207 ++codec2.pltype;
208 CodecInst test_codec;
209
210 // Register the same codec with different payloads.
211 EXPECT_EQ(0, receiver_->AddCodec(codec1.id, codec1.inst.pltype,
212 codec1.inst.channels, codec1.inst.plfreq,
213 nullptr, codec1.inst.plname));
214 EXPECT_EQ(0, receiver_->AddCodec(codec1.id, codec2.pltype, codec2.channels,
215 codec2.plfreq, NULL, codec2.plname));
216
217 // Both payload types should exist.
218 EXPECT_EQ(0,
219 receiver_->DecoderByPayloadType(codec1.inst.pltype, &test_codec));
220 EXPECT_EQ(true, CodecsEqual(codec1.inst, test_codec));
221 EXPECT_EQ(0, receiver_->DecoderByPayloadType(codec2.pltype, &test_codec));
222 EXPECT_EQ(true, CodecsEqual(codec2, test_codec));
223 }
224
225 #if defined(WEBRTC_ANDROID)
226 #define MAYBE_AddCodecChangeCodecId DISABLED_AddCodecChangeCodecId
227 #else
228 #define MAYBE_AddCodecChangeCodecId AddCodecChangeCodecId
229 #endif
230 TEST_F(AcmReceiverTestOldApi, AddCodecChangeCodecId) {
231 const CodecIdInst codec1(RentACodec::CodecId::kPCMU);
232 CodecIdInst codec2(RentACodec::CodecId::kPCMA);
233 codec2.inst.pltype = codec1.inst.pltype;
234 CodecInst test_codec;
235
236 // Register the same payload type with different codec ID.
237 EXPECT_EQ(0, receiver_->AddCodec(codec1.id, codec1.inst.pltype,
238 codec1.inst.channels, codec1.inst.plfreq,
239 nullptr, codec1.inst.plname));
240 EXPECT_EQ(0, receiver_->AddCodec(codec2.id, codec2.inst.pltype,
241 codec2.inst.channels, codec2.inst.plfreq,
242 nullptr, codec2.inst.plname));
243
244 // Make sure that the last codec is used.
245 EXPECT_EQ(0,
246 receiver_->DecoderByPayloadType(codec2.inst.pltype, &test_codec));
247 EXPECT_EQ(true, CodecsEqual(codec2.inst, test_codec));
248 }
249
250 #if defined(WEBRTC_ANDROID)
251 #define MAYBE_AddCodecRemoveCodec DISABLED_AddCodecRemoveCodec
252 #else
253 #define MAYBE_AddCodecRemoveCodec AddCodecRemoveCodec
254 #endif
255 TEST_F(AcmReceiverTestOldApi, MAYBE_AddCodecRemoveCodec) {
256 const CodecIdInst codec(RentACodec::CodecId::kPCMA);
257 const int payload_type = codec.inst.pltype;
258 EXPECT_EQ(
259 0, receiver_->AddCodec(codec.id, codec.inst.pltype, codec.inst.channels,
260 codec.inst.plfreq, nullptr, codec.inst.plname));
261
262 // Remove non-existing codec should not fail. ACM1 legacy.
263 EXPECT_EQ(0, receiver_->RemoveCodec(payload_type + 1));
264
265 // Remove an existing codec.
266 EXPECT_EQ(0, receiver_->RemoveCodec(payload_type));
267
268 // Ask for the removed codec, must fail.
269 CodecInst ci;
270 EXPECT_EQ(-1, receiver_->DecoderByPayloadType(payload_type, &ci));
271 }
272
273 #if defined(WEBRTC_ANDROID)
274 #define MAYBE_SampleRate DISABLED_SampleRate
275 #else
276 #define MAYBE_SampleRate SampleRate
277 #endif
278 TEST_F(AcmReceiverTestOldApi, MAYBE_SampleRate) {
279 const RentACodec::CodecId kCodecId[] = {RentACodec::CodecId::kISAC,
280 RentACodec::CodecId::kISACSWB};
281 AddSetOfCodecs(kCodecId);
282
283 AudioFrame frame;
284 const int kOutSampleRateHz = 8000; // Different than codec sample rate.
285 for (const auto codec_id : kCodecId) {
286 const CodecIdInst codec(codec_id);
287 const int num_10ms_frames = codec.inst.pacsize / (codec.inst.plfreq / 100);
288 InsertOnePacketOfSilence(codec.id);
289 for (int k = 0; k < num_10ms_frames; ++k) {
290 bool muted;
291 EXPECT_EQ(0, receiver_->GetAudio(kOutSampleRateHz, &frame, &muted));
292 }
293 EXPECT_EQ(codec.inst.plfreq, receiver_->last_output_sample_rate_hz());
294 }
295 }
296
297 class AcmReceiverTestFaxModeOldApi : public AcmReceiverTestOldApi {
298 protected:
299 AcmReceiverTestFaxModeOldApi() {
300 config_.neteq_config.playout_mode = kPlayoutFax;
301 }
302
303 void RunVerifyAudioFrame(RentACodec::CodecId codec_id) {
304 // Make sure "fax mode" is enabled. This will avoid delay changes unless the
305 // packet-loss concealment is made. We do this in order to make the
306 // timestamp increments predictable; in normal mode, NetEq may decide to do
307 // accelerate or pre-emptive expand operations after some time, offsetting
308 // the timestamp.
309 EXPECT_EQ(kPlayoutFax, config_.neteq_config.playout_mode);
310
311 const RentACodec::CodecId kCodecId[] = {codec_id};
312 AddSetOfCodecs(kCodecId);
313
314 const CodecIdInst codec(codec_id);
315 const int output_sample_rate_hz = codec.inst.plfreq;
316 const size_t output_channels = codec.inst.channels;
317 const size_t samples_per_ms = rtc::checked_cast<size_t>(
318 rtc::CheckedDivExact(output_sample_rate_hz, 1000));
319 const int num_10ms_frames = rtc::CheckedDivExact(
320 codec.inst.pacsize, rtc::checked_cast<int>(10 * samples_per_ms));
321 const AudioFrame::VADActivity expected_vad_activity =
322 output_sample_rate_hz > 16000 ? AudioFrame::kVadActive
323 : AudioFrame::kVadPassive;
324
325 // Expect the first output timestamp to be 5*fs/8000 samples before the
326 // first inserted timestamp (because of NetEq's look-ahead). (This value is
327 // defined in Expand::overlap_length_.)
328 uint32_t expected_output_ts = last_packet_send_timestamp_ -
329 rtc::CheckedDivExact(5 * output_sample_rate_hz, 8000);
330
331 AudioFrame frame;
332 bool muted;
333 EXPECT_EQ(0, receiver_->GetAudio(output_sample_rate_hz, &frame, &muted));
334 // Expect timestamp = 0 before first packet is inserted.
335 EXPECT_EQ(0u, frame.timestamp_);
336 for (int i = 0; i < 5; ++i) {
337 InsertOnePacketOfSilence(codec.id);
338 for (int k = 0; k < num_10ms_frames; ++k) {
339 EXPECT_EQ(0,
340 receiver_->GetAudio(output_sample_rate_hz, &frame, &muted));
341 EXPECT_EQ(expected_output_ts, frame.timestamp_);
342 expected_output_ts += 10 * samples_per_ms;
343 EXPECT_EQ(10 * samples_per_ms, frame.samples_per_channel_);
344 EXPECT_EQ(output_sample_rate_hz, frame.sample_rate_hz_);
345 EXPECT_EQ(output_channels, frame.num_channels_);
346 EXPECT_EQ(AudioFrame::kNormalSpeech, frame.speech_type_);
347 EXPECT_EQ(expected_vad_activity, frame.vad_activity_);
348 EXPECT_FALSE(muted);
349 }
350 }
351 }
352 };
353
354 #if defined(WEBRTC_ANDROID)
355 #define MAYBE_VerifyAudioFramePCMU DISABLED_VerifyAudioFramePCMU
356 #else
357 #define MAYBE_VerifyAudioFramePCMU VerifyAudioFramePCMU
358 #endif
359 TEST_F(AcmReceiverTestFaxModeOldApi, MAYBE_VerifyAudioFramePCMU) {
360 RunVerifyAudioFrame(RentACodec::CodecId::kPCMU);
361 }
362
363 #if defined(WEBRTC_ANDROID)
364 #define MAYBE_VerifyAudioFrameISAC DISABLED_VerifyAudioFrameISAC
365 #else
366 #define MAYBE_VerifyAudioFrameISAC VerifyAudioFrameISAC
367 #endif
368 TEST_F(AcmReceiverTestFaxModeOldApi, MAYBE_VerifyAudioFrameISAC) {
369 RunVerifyAudioFrame(RentACodec::CodecId::kISAC);
370 }
371
372 #if defined(WEBRTC_ANDROID)
373 #define MAYBE_VerifyAudioFrameOpus DISABLED_VerifyAudioFrameOpus
374 #else
375 #define MAYBE_VerifyAudioFrameOpus VerifyAudioFrameOpus
376 #endif
377 TEST_F(AcmReceiverTestFaxModeOldApi, MAYBE_VerifyAudioFrameOpus) {
378 RunVerifyAudioFrame(RentACodec::CodecId::kOpus);
379 }
380
381 #if defined(WEBRTC_ANDROID)
382 #define MAYBE_PostdecodingVad DISABLED_PostdecodingVad
383 #else
384 #define MAYBE_PostdecodingVad PostdecodingVad
385 #endif
386 TEST_F(AcmReceiverTestOldApi, MAYBE_PostdecodingVad) {
387 EXPECT_TRUE(config_.neteq_config.enable_post_decode_vad);
388 const CodecIdInst codec(RentACodec::CodecId::kPCM16Bwb);
389 ASSERT_EQ(
390 0, receiver_->AddCodec(codec.id, codec.inst.pltype, codec.inst.channels,
391 codec.inst.plfreq, nullptr, ""));
392 const int kNumPackets = 5;
393 const int num_10ms_frames = codec.inst.pacsize / (codec.inst.plfreq / 100);
394 AudioFrame frame;
395 for (int n = 0; n < kNumPackets; ++n) {
396 InsertOnePacketOfSilence(codec.id);
397 for (int k = 0; k < num_10ms_frames; ++k) {
398 bool muted;
399 ASSERT_EQ(0, receiver_->GetAudio(codec.inst.plfreq, &frame, &muted));
400 }
401 }
402 EXPECT_EQ(AudioFrame::kVadPassive, frame.vad_activity_);
403 }
404
405 class AcmReceiverTestPostDecodeVadPassiveOldApi : public AcmReceiverTestOldApi {
406 protected:
407 AcmReceiverTestPostDecodeVadPassiveOldApi() {
408 config_.neteq_config.enable_post_decode_vad = false;
409 }
410 };
411
412 #if defined(WEBRTC_ANDROID)
413 #define MAYBE_PostdecodingVad DISABLED_PostdecodingVad
414 #else
415 #define MAYBE_PostdecodingVad PostdecodingVad
416 #endif
417 TEST_F(AcmReceiverTestPostDecodeVadPassiveOldApi, MAYBE_PostdecodingVad) {
418 EXPECT_FALSE(config_.neteq_config.enable_post_decode_vad);
419 const CodecIdInst codec(RentACodec::CodecId::kPCM16Bwb);
420 ASSERT_EQ(
421 0, receiver_->AddCodec(codec.id, codec.inst.pltype, codec.inst.channels,
422 codec.inst.plfreq, nullptr, ""));
423 const int kNumPackets = 5;
424 const int num_10ms_frames = codec.inst.pacsize / (codec.inst.plfreq / 100);
425 AudioFrame frame;
426 for (int n = 0; n < kNumPackets; ++n) {
427 InsertOnePacketOfSilence(codec.id);
428 for (int k = 0; k < num_10ms_frames; ++k) {
429 bool muted;
430 ASSERT_EQ(0, receiver_->GetAudio(codec.inst.plfreq, &frame, &muted));
431 }
432 }
433 EXPECT_EQ(AudioFrame::kVadUnknown, frame.vad_activity_);
434 }
435
436 #if defined(WEBRTC_ANDROID)
437 #define MAYBE_LastAudioCodec DISABLED_LastAudioCodec
438 #else
439 #define MAYBE_LastAudioCodec LastAudioCodec
440 #endif
441 #if defined(WEBRTC_CODEC_ISAC)
442 TEST_F(AcmReceiverTestOldApi, MAYBE_LastAudioCodec) {
443 const RentACodec::CodecId kCodecId[] = {
444 RentACodec::CodecId::kISAC, RentACodec::CodecId::kPCMA,
445 RentACodec::CodecId::kISACSWB, RentACodec::CodecId::kPCM16Bswb32kHz};
446 AddSetOfCodecs(kCodecId);
447
448 const RentACodec::CodecId kCngId[] = {
449 // Not including full-band.
450 RentACodec::CodecId::kCNNB, RentACodec::CodecId::kCNWB,
451 RentACodec::CodecId::kCNSWB};
452 AddSetOfCodecs(kCngId);
453
454 // Register CNG at sender side.
455 for (auto id : kCngId)
456 ASSERT_EQ(0, acm_->RegisterSendCodec(CodecIdInst(id).inst));
457
458 CodecInst codec;
459 // No audio payload is received.
460 EXPECT_EQ(-1, receiver_->LastAudioCodec(&codec));
461
462 // Start with sending DTX.
463 ASSERT_EQ(0, acm_->SetVAD(true, true, VADVeryAggr));
464 packet_sent_ = false;
465 InsertOnePacketOfSilence(CodecIdInst(kCodecId[0]).id); // Enough to test
466 // with one codec.
467 ASSERT_TRUE(packet_sent_);
468 EXPECT_EQ(kAudioFrameCN, last_frame_type_);
469
470 // Has received, only, DTX. Last Audio codec is undefined.
471 EXPECT_EQ(-1, receiver_->LastAudioCodec(&codec));
472 EXPECT_FALSE(receiver_->last_packet_sample_rate_hz());
473
474 for (auto id : kCodecId) {
475 const CodecIdInst c(id);
476
477 // Set DTX off to send audio payload.
478 acm_->SetVAD(false, false, VADAggr);
479 packet_sent_ = false;
480 InsertOnePacketOfSilence(c.id);
481
482 // Sanity check if Actually an audio payload received, and it should be
483 // of type "speech."
484 ASSERT_TRUE(packet_sent_);
485 ASSERT_EQ(kAudioFrameSpeech, last_frame_type_);
486 EXPECT_EQ(rtc::Optional<int>(c.inst.plfreq),
487 receiver_->last_packet_sample_rate_hz());
488
489 // Set VAD on to send DTX. Then check if the "Last Audio codec" returns
490 // the expected codec.
491 acm_->SetVAD(true, true, VADAggr);
492
493 // Do as many encoding until a DTX is sent.
494 while (last_frame_type_ != kAudioFrameCN) {
495 packet_sent_ = false;
496 InsertOnePacketOfSilence(c.id);
497 ASSERT_TRUE(packet_sent_);
498 }
499 EXPECT_EQ(rtc::Optional<int>(c.inst.plfreq),
500 receiver_->last_packet_sample_rate_hz());
501 EXPECT_EQ(0, receiver_->LastAudioCodec(&codec));
502 EXPECT_TRUE(CodecsEqual(c.inst, codec));
503 }
504 }
505 #endif
506
507 } // namespace acm2
508
509 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/audio_coding/acm2/acm_receiver_unittest.cc ('k') | webrtc/modules/audio_coding/acm2/acm_send_test.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698