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

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

Issue 1481493004: audio_coding: remove "main" directory (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Rebased Created 5 years 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/main/acm2/acm_receiver.h"
12
13 #include <algorithm> // std::min
14
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "webrtc/base/scoped_ptr.h"
17 #include "webrtc/modules/audio_coding/main/include/audio_coding_module.h"
18 #include "webrtc/modules/audio_coding/main/acm2/audio_coding_module_impl.h"
19 #include "webrtc/modules/audio_coding/neteq/tools/rtp_generator.h"
20 #include "webrtc/system_wrappers/include/clock.h"
21 #include "webrtc/test/test_suite.h"
22 #include "webrtc/test/testsupport/fileutils.h"
23 #include "webrtc/test/testsupport/gtest_disable.h"
24
25 namespace webrtc {
26
27 namespace acm2 {
28 namespace {
29
30 bool CodecsEqual(const CodecInst& codec_a, const CodecInst& codec_b) {
31 if (strcmp(codec_a.plname, codec_b.plname) != 0 ||
32 codec_a.plfreq != codec_b.plfreq ||
33 codec_a.pltype != codec_b.pltype ||
34 codec_b.channels != codec_a.channels)
35 return false;
36 return true;
37 }
38
39 struct CodecIdInst {
40 explicit CodecIdInst(RentACodec::CodecId codec_id) {
41 const auto codec_ix = RentACodec::CodecIndexFromId(codec_id);
42 EXPECT_TRUE(codec_ix);
43 id = *codec_ix;
44 const auto codec_inst = RentACodec::CodecInstById(codec_id);
45 EXPECT_TRUE(codec_inst);
46 inst = *codec_inst;
47 }
48 int id;
49 CodecInst inst;
50 };
51
52 } // namespace
53
54 class AcmReceiverTestOldApi : public AudioPacketizationCallback,
55 public ::testing::Test {
56 protected:
57 AcmReceiverTestOldApi()
58 : timestamp_(0),
59 packet_sent_(false),
60 last_packet_send_timestamp_(timestamp_),
61 last_frame_type_(kEmptyFrame) {
62 AudioCodingModule::Config config;
63 acm_.reset(new AudioCodingModuleImpl(config));
64 receiver_.reset(new AcmReceiver(config));
65 }
66
67 ~AcmReceiverTestOldApi() {}
68
69 void SetUp() override {
70 ASSERT_TRUE(receiver_.get() != NULL);
71 ASSERT_TRUE(acm_.get() != NULL);
72 codecs_ = RentACodec::Database();
73
74 acm_->InitializeReceiver();
75 acm_->RegisterTransportCallback(this);
76
77 rtp_header_.header.sequenceNumber = 0;
78 rtp_header_.header.timestamp = 0;
79 rtp_header_.header.markerBit = false;
80 rtp_header_.header.ssrc = 0x12345678; // Arbitrary.
81 rtp_header_.header.numCSRCs = 0;
82 rtp_header_.header.payloadType = 0;
83 rtp_header_.frameType = kAudioFrameSpeech;
84 rtp_header_.type.Audio.isCNG = false;
85 }
86
87 void TearDown() override {}
88
89 void InsertOnePacketOfSilence(int codec_id) {
90 CodecInst codec =
91 *RentACodec::CodecInstById(*RentACodec::CodecIdFromIndex(codec_id));
92 if (timestamp_ == 0) { // This is the first time inserting audio.
93 ASSERT_EQ(0, acm_->RegisterSendCodec(codec));
94 } else {
95 auto current_codec = acm_->SendCodec();
96 ASSERT_TRUE(current_codec);
97 if (!CodecsEqual(codec, *current_codec))
98 ASSERT_EQ(0, acm_->RegisterSendCodec(codec));
99 }
100 AudioFrame frame;
101 // Frame setup according to the codec.
102 frame.sample_rate_hz_ = codec.plfreq;
103 frame.samples_per_channel_ = codec.plfreq / 100; // 10 ms.
104 frame.num_channels_ = codec.channels;
105 memset(frame.data_, 0, frame.samples_per_channel_ * frame.num_channels_ *
106 sizeof(int16_t));
107 packet_sent_ = false;
108 last_packet_send_timestamp_ = timestamp_;
109 while (!packet_sent_) {
110 frame.timestamp_ = timestamp_;
111 timestamp_ += frame.samples_per_channel_;
112 ASSERT_GE(acm_->Add10MsData(frame), 0);
113 }
114 }
115
116 template <size_t N>
117 void AddSetOfCodecs(const RentACodec::CodecId(&ids)[N]) {
118 for (auto id : ids) {
119 const auto i = RentACodec::CodecIndexFromId(id);
120 ASSERT_TRUE(i);
121 ASSERT_EQ(
122 0, receiver_->AddCodec(*i, codecs_[*i].pltype, codecs_[*i].channels,
123 codecs_[*i].plfreq, nullptr));
124 }
125 }
126
127 int SendData(FrameType frame_type,
128 uint8_t payload_type,
129 uint32_t timestamp,
130 const uint8_t* payload_data,
131 size_t payload_len_bytes,
132 const RTPFragmentationHeader* fragmentation) override {
133 if (frame_type == kEmptyFrame)
134 return 0;
135
136 rtp_header_.header.payloadType = payload_type;
137 rtp_header_.frameType = frame_type;
138 if (frame_type == kAudioFrameSpeech)
139 rtp_header_.type.Audio.isCNG = false;
140 else
141 rtp_header_.type.Audio.isCNG = true;
142 rtp_header_.header.timestamp = timestamp;
143
144 int ret_val = receiver_->InsertPacket(
145 rtp_header_,
146 rtc::ArrayView<const uint8_t>(payload_data, payload_len_bytes));
147 if (ret_val < 0) {
148 assert(false);
149 return -1;
150 }
151 rtp_header_.header.sequenceNumber++;
152 packet_sent_ = true;
153 last_frame_type_ = frame_type;
154 return 0;
155 }
156
157 rtc::scoped_ptr<AcmReceiver> receiver_;
158 rtc::ArrayView<const CodecInst> codecs_;
159 rtc::scoped_ptr<AudioCodingModule> acm_;
160 WebRtcRTPHeader rtp_header_;
161 uint32_t timestamp_;
162 bool packet_sent_; // Set when SendData is called reset when inserting audio.
163 uint32_t last_packet_send_timestamp_;
164 FrameType last_frame_type_;
165 };
166
167 TEST_F(AcmReceiverTestOldApi, DISABLED_ON_ANDROID(AddCodecGetCodec)) {
168 // Add codec.
169 for (size_t n = 0; n < codecs_.size(); ++n) {
170 if (n & 0x1) // Just add codecs with odd index.
171 EXPECT_EQ(0,
172 receiver_->AddCodec(n, codecs_[n].pltype, codecs_[n].channels,
173 codecs_[n].plfreq, NULL));
174 }
175 // Get codec and compare.
176 for (size_t n = 0; n < codecs_.size(); ++n) {
177 CodecInst my_codec;
178 if (n & 0x1) {
179 // Codecs with odd index should match the reference.
180 EXPECT_EQ(0, receiver_->DecoderByPayloadType(codecs_[n].pltype,
181 &my_codec));
182 EXPECT_TRUE(CodecsEqual(codecs_[n], my_codec));
183 } else {
184 // Codecs with even index are not registered.
185 EXPECT_EQ(-1, receiver_->DecoderByPayloadType(codecs_[n].pltype,
186 &my_codec));
187 }
188 }
189 }
190
191 TEST_F(AcmReceiverTestOldApi, DISABLED_ON_ANDROID(AddCodecChangePayloadType)) {
192 const CodecIdInst codec1(RentACodec::CodecId::kPCMA);
193 CodecInst codec2 = codec1.inst;
194 ++codec2.pltype;
195 CodecInst test_codec;
196
197 // Register the same codec with different payloads.
198 EXPECT_EQ(0, receiver_->AddCodec(codec1.id, codec1.inst.pltype,
199 codec1.inst.channels, codec1.inst.plfreq,
200 nullptr));
201 EXPECT_EQ(0, receiver_->AddCodec(codec1.id, codec2.pltype, codec2.channels,
202 codec2.plfreq, NULL));
203
204 // Both payload types should exist.
205 EXPECT_EQ(0,
206 receiver_->DecoderByPayloadType(codec1.inst.pltype, &test_codec));
207 EXPECT_EQ(true, CodecsEqual(codec1.inst, test_codec));
208 EXPECT_EQ(0, receiver_->DecoderByPayloadType(codec2.pltype, &test_codec));
209 EXPECT_EQ(true, CodecsEqual(codec2, test_codec));
210 }
211
212 TEST_F(AcmReceiverTestOldApi, DISABLED_ON_ANDROID(AddCodecChangeCodecId)) {
213 const CodecIdInst codec1(RentACodec::CodecId::kPCMU);
214 CodecIdInst codec2(RentACodec::CodecId::kPCMA);
215 codec2.inst.pltype = codec1.inst.pltype;
216 CodecInst test_codec;
217
218 // Register the same payload type with different codec ID.
219 EXPECT_EQ(0, receiver_->AddCodec(codec1.id, codec1.inst.pltype,
220 codec1.inst.channels, codec1.inst.plfreq,
221 nullptr));
222 EXPECT_EQ(0, receiver_->AddCodec(codec2.id, codec2.inst.pltype,
223 codec2.inst.channels, codec2.inst.plfreq,
224 nullptr));
225
226 // Make sure that the last codec is used.
227 EXPECT_EQ(0,
228 receiver_->DecoderByPayloadType(codec2.inst.pltype, &test_codec));
229 EXPECT_EQ(true, CodecsEqual(codec2.inst, test_codec));
230 }
231
232 TEST_F(AcmReceiverTestOldApi, DISABLED_ON_ANDROID(AddCodecRemoveCodec)) {
233 const CodecIdInst codec(RentACodec::CodecId::kPCMA);
234 const int payload_type = codec.inst.pltype;
235 EXPECT_EQ(
236 0, receiver_->AddCodec(codec.id, codec.inst.pltype, codec.inst.channels,
237 codec.inst.plfreq, nullptr));
238
239 // Remove non-existing codec should not fail. ACM1 legacy.
240 EXPECT_EQ(0, receiver_->RemoveCodec(payload_type + 1));
241
242 // Remove an existing codec.
243 EXPECT_EQ(0, receiver_->RemoveCodec(payload_type));
244
245 // Ask for the removed codec, must fail.
246 CodecInst ci;
247 EXPECT_EQ(-1, receiver_->DecoderByPayloadType(payload_type, &ci));
248 }
249
250 TEST_F(AcmReceiverTestOldApi, DISABLED_ON_ANDROID(SampleRate)) {
251 const RentACodec::CodecId kCodecId[] = {RentACodec::CodecId::kISAC,
252 RentACodec::CodecId::kISACSWB};
253 AddSetOfCodecs(kCodecId);
254
255 AudioFrame frame;
256 const int kOutSampleRateHz = 8000; // Different than codec sample rate.
257 for (const auto codec_id : kCodecId) {
258 const CodecIdInst codec(codec_id);
259 const int num_10ms_frames = codec.inst.pacsize / (codec.inst.plfreq / 100);
260 InsertOnePacketOfSilence(codec.id);
261 for (int k = 0; k < num_10ms_frames; ++k) {
262 EXPECT_EQ(0, receiver_->GetAudio(kOutSampleRateHz, &frame));
263 }
264 EXPECT_EQ(codec.inst.plfreq, receiver_->last_output_sample_rate_hz());
265 }
266 }
267
268 TEST_F(AcmReceiverTestOldApi, DISABLED_ON_ANDROID(PostdecodingVad)) {
269 receiver_->EnableVad();
270 EXPECT_TRUE(receiver_->vad_enabled());
271 const CodecIdInst codec(RentACodec::CodecId::kPCM16Bwb);
272 ASSERT_EQ(
273 0, receiver_->AddCodec(codec.id, codec.inst.pltype, codec.inst.channels,
274 codec.inst.plfreq, nullptr));
275 const int kNumPackets = 5;
276 const int num_10ms_frames = codec.inst.pacsize / (codec.inst.plfreq / 100);
277 AudioFrame frame;
278 for (int n = 0; n < kNumPackets; ++n) {
279 InsertOnePacketOfSilence(codec.id);
280 for (int k = 0; k < num_10ms_frames; ++k)
281 ASSERT_EQ(0, receiver_->GetAudio(codec.inst.plfreq, &frame));
282 }
283 EXPECT_EQ(AudioFrame::kVadPassive, frame.vad_activity_);
284
285 receiver_->DisableVad();
286 EXPECT_FALSE(receiver_->vad_enabled());
287
288 for (int n = 0; n < kNumPackets; ++n) {
289 InsertOnePacketOfSilence(codec.id);
290 for (int k = 0; k < num_10ms_frames; ++k)
291 ASSERT_EQ(0, receiver_->GetAudio(codec.inst.plfreq, &frame));
292 }
293 EXPECT_EQ(AudioFrame::kVadUnknown, frame.vad_activity_);
294 }
295
296 #ifdef WEBRTC_CODEC_ISAC
297 #define IF_ISAC_FLOAT(x) x
298 #else
299 #define IF_ISAC_FLOAT(x) DISABLED_##x
300 #endif
301
302 TEST_F(AcmReceiverTestOldApi,
303 DISABLED_ON_ANDROID(IF_ISAC_FLOAT(LastAudioCodec))) {
304 const RentACodec::CodecId kCodecId[] = {
305 RentACodec::CodecId::kISAC, RentACodec::CodecId::kPCMA,
306 RentACodec::CodecId::kISACSWB, RentACodec::CodecId::kPCM16Bswb32kHz};
307 AddSetOfCodecs(kCodecId);
308
309 const RentACodec::CodecId kCngId[] = {
310 // Not including full-band.
311 RentACodec::CodecId::kCNNB, RentACodec::CodecId::kCNWB,
312 RentACodec::CodecId::kCNSWB};
313 AddSetOfCodecs(kCngId);
314
315 // Register CNG at sender side.
316 for (auto id : kCngId)
317 ASSERT_EQ(0, acm_->RegisterSendCodec(CodecIdInst(id).inst));
318
319 CodecInst codec;
320 // No audio payload is received.
321 EXPECT_EQ(-1, receiver_->LastAudioCodec(&codec));
322
323 // Start with sending DTX.
324 ASSERT_EQ(0, acm_->SetVAD(true, true, VADVeryAggr));
325 packet_sent_ = false;
326 InsertOnePacketOfSilence(CodecIdInst(kCodecId[0]).id); // Enough to test
327 // with one codec.
328 ASSERT_TRUE(packet_sent_);
329 EXPECT_EQ(kAudioFrameCN, last_frame_type_);
330
331 // Has received, only, DTX. Last Audio codec is undefined.
332 EXPECT_EQ(-1, receiver_->LastAudioCodec(&codec));
333 EXPECT_FALSE(receiver_->last_packet_sample_rate_hz());
334
335 for (auto id : kCodecId) {
336 const CodecIdInst c(id);
337
338 // Set DTX off to send audio payload.
339 acm_->SetVAD(false, false, VADAggr);
340 packet_sent_ = false;
341 InsertOnePacketOfSilence(c.id);
342
343 // Sanity check if Actually an audio payload received, and it should be
344 // of type "speech."
345 ASSERT_TRUE(packet_sent_);
346 ASSERT_EQ(kAudioFrameSpeech, last_frame_type_);
347 EXPECT_EQ(rtc::Optional<int>(c.inst.plfreq),
348 receiver_->last_packet_sample_rate_hz());
349
350 // Set VAD on to send DTX. Then check if the "Last Audio codec" returns
351 // the expected codec.
352 acm_->SetVAD(true, true, VADAggr);
353
354 // Do as many encoding until a DTX is sent.
355 while (last_frame_type_ != kAudioFrameCN) {
356 packet_sent_ = false;
357 InsertOnePacketOfSilence(c.id);
358 ASSERT_TRUE(packet_sent_);
359 }
360 EXPECT_EQ(rtc::Optional<int>(c.inst.plfreq),
361 receiver_->last_packet_sample_rate_hz());
362 EXPECT_EQ(0, receiver_->LastAudioCodec(&codec));
363 EXPECT_TRUE(CodecsEqual(c.inst, codec));
364 }
365 }
366
367 } // namespace acm2
368
369 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/audio_coding/main/acm2/acm_receiver.cc ('k') | webrtc/modules/audio_coding/main/acm2/acm_resampler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698