• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2014 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 <stdio.h>
12 #include <string.h>
13 #include <vector>
14 
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "webrtc/base/md5digest.h"
17 #include "webrtc/base/platform_thread.h"
18 #include "webrtc/base/scoped_ptr.h"
19 #include "webrtc/base/thread_annotations.h"
20 #include "webrtc/modules/audio_coding/codecs/audio_encoder.h"
21 #include "webrtc/modules/audio_coding/codecs/g711/audio_decoder_pcm.h"
22 #include "webrtc/modules/audio_coding/codecs/g711/audio_encoder_pcm.h"
23 #include "webrtc/modules/audio_coding/codecs/isac/main/include/audio_encoder_isac.h"
24 #include "webrtc/modules/audio_coding/codecs/mock/mock_audio_encoder.h"
25 #include "webrtc/modules/audio_coding/acm2/acm_receive_test_oldapi.h"
26 #include "webrtc/modules/audio_coding/acm2/acm_send_test_oldapi.h"
27 #include "webrtc/modules/audio_coding/include/audio_coding_module.h"
28 #include "webrtc/modules/audio_coding/include/audio_coding_module_typedefs.h"
29 #include "webrtc/modules/audio_coding/neteq/audio_decoder_impl.h"
30 #include "webrtc/modules/audio_coding/neteq/mock/mock_audio_decoder.h"
31 #include "webrtc/modules/audio_coding/neteq/tools/audio_checksum.h"
32 #include "webrtc/modules/audio_coding/neteq/tools/audio_loop.h"
33 #include "webrtc/modules/audio_coding/neteq/tools/constant_pcm_packet_source.h"
34 #include "webrtc/modules/audio_coding/neteq/tools/input_audio_file.h"
35 #include "webrtc/modules/audio_coding/neteq/tools/output_audio_file.h"
36 #include "webrtc/modules/audio_coding/neteq/tools/packet.h"
37 #include "webrtc/modules/audio_coding/neteq/tools/rtp_file_source.h"
38 #include "webrtc/modules/include/module_common_types.h"
39 #include "webrtc/system_wrappers/include/clock.h"
40 #include "webrtc/system_wrappers/include/critical_section_wrapper.h"
41 #include "webrtc/system_wrappers/include/event_wrapper.h"
42 #include "webrtc/system_wrappers/include/sleep.h"
43 #include "webrtc/test/testsupport/fileutils.h"
44 
45 using ::testing::AtLeast;
46 using ::testing::Invoke;
47 using ::testing::_;
48 
49 namespace webrtc {
50 
51 namespace {
52 const int kSampleRateHz = 16000;
53 const int kNumSamples10ms = kSampleRateHz / 100;
54 const int kFrameSizeMs = 10;  // Multiple of 10.
55 const int kFrameSizeSamples = kFrameSizeMs / 10 * kNumSamples10ms;
56 const int kPayloadSizeBytes = kFrameSizeSamples * sizeof(int16_t);
57 const uint8_t kPayloadType = 111;
58 }  // namespace
59 
60 class RtpUtility {
61  public:
RtpUtility(int samples_per_packet,uint8_t payload_type)62   RtpUtility(int samples_per_packet, uint8_t payload_type)
63       : samples_per_packet_(samples_per_packet), payload_type_(payload_type) {}
64 
~RtpUtility()65   virtual ~RtpUtility() {}
66 
Populate(WebRtcRTPHeader * rtp_header)67   void Populate(WebRtcRTPHeader* rtp_header) {
68     rtp_header->header.sequenceNumber = 0xABCD;
69     rtp_header->header.timestamp = 0xABCDEF01;
70     rtp_header->header.payloadType = payload_type_;
71     rtp_header->header.markerBit = false;
72     rtp_header->header.ssrc = 0x1234;
73     rtp_header->header.numCSRCs = 0;
74     rtp_header->frameType = kAudioFrameSpeech;
75 
76     rtp_header->header.payload_type_frequency = kSampleRateHz;
77     rtp_header->type.Audio.channel = 1;
78     rtp_header->type.Audio.isCNG = false;
79   }
80 
Forward(WebRtcRTPHeader * rtp_header)81   void Forward(WebRtcRTPHeader* rtp_header) {
82     ++rtp_header->header.sequenceNumber;
83     rtp_header->header.timestamp += samples_per_packet_;
84   }
85 
86  private:
87   int samples_per_packet_;
88   uint8_t payload_type_;
89 };
90 
91 class PacketizationCallbackStubOldApi : public AudioPacketizationCallback {
92  public:
PacketizationCallbackStubOldApi()93   PacketizationCallbackStubOldApi()
94       : num_calls_(0),
95         last_frame_type_(kEmptyFrame),
96         last_payload_type_(-1),
97         last_timestamp_(0),
98         crit_sect_(CriticalSectionWrapper::CreateCriticalSection()) {}
99 
SendData(FrameType frame_type,uint8_t payload_type,uint32_t timestamp,const uint8_t * payload_data,size_t payload_len_bytes,const RTPFragmentationHeader * fragmentation)100   int32_t SendData(FrameType frame_type,
101                    uint8_t payload_type,
102                    uint32_t timestamp,
103                    const uint8_t* payload_data,
104                    size_t payload_len_bytes,
105                    const RTPFragmentationHeader* fragmentation) override {
106     CriticalSectionScoped lock(crit_sect_.get());
107     ++num_calls_;
108     last_frame_type_ = frame_type;
109     last_payload_type_ = payload_type;
110     last_timestamp_ = timestamp;
111     last_payload_vec_.assign(payload_data, payload_data + payload_len_bytes);
112     return 0;
113   }
114 
num_calls() const115   int num_calls() const {
116     CriticalSectionScoped lock(crit_sect_.get());
117     return num_calls_;
118   }
119 
last_payload_len_bytes() const120   int last_payload_len_bytes() const {
121     CriticalSectionScoped lock(crit_sect_.get());
122     return last_payload_vec_.size();
123   }
124 
last_frame_type() const125   FrameType last_frame_type() const {
126     CriticalSectionScoped lock(crit_sect_.get());
127     return last_frame_type_;
128   }
129 
last_payload_type() const130   int last_payload_type() const {
131     CriticalSectionScoped lock(crit_sect_.get());
132     return last_payload_type_;
133   }
134 
last_timestamp() const135   uint32_t last_timestamp() const {
136     CriticalSectionScoped lock(crit_sect_.get());
137     return last_timestamp_;
138   }
139 
SwapBuffers(std::vector<uint8_t> * payload)140   void SwapBuffers(std::vector<uint8_t>* payload) {
141     CriticalSectionScoped lock(crit_sect_.get());
142     last_payload_vec_.swap(*payload);
143   }
144 
145  private:
146   int num_calls_ GUARDED_BY(crit_sect_);
147   FrameType last_frame_type_ GUARDED_BY(crit_sect_);
148   int last_payload_type_ GUARDED_BY(crit_sect_);
149   uint32_t last_timestamp_ GUARDED_BY(crit_sect_);
150   std::vector<uint8_t> last_payload_vec_ GUARDED_BY(crit_sect_);
151   const rtc::scoped_ptr<CriticalSectionWrapper> crit_sect_;
152 };
153 
154 class AudioCodingModuleTestOldApi : public ::testing::Test {
155  protected:
AudioCodingModuleTestOldApi()156   AudioCodingModuleTestOldApi()
157       : id_(1),
158         rtp_utility_(new RtpUtility(kFrameSizeSamples, kPayloadType)),
159         clock_(Clock::GetRealTimeClock()) {}
160 
~AudioCodingModuleTestOldApi()161   ~AudioCodingModuleTestOldApi() {}
162 
TearDown()163   void TearDown() {}
164 
SetUp()165   void SetUp() {
166     acm_.reset(AudioCodingModule::Create(id_, clock_));
167 
168     rtp_utility_->Populate(&rtp_header_);
169 
170     input_frame_.sample_rate_hz_ = kSampleRateHz;
171     input_frame_.num_channels_ = 1;
172     input_frame_.samples_per_channel_ = kSampleRateHz * 10 / 1000;  // 10 ms.
173     static_assert(kSampleRateHz * 10 / 1000 <= AudioFrame::kMaxDataSizeSamples,
174                   "audio frame too small");
175     memset(input_frame_.data_,
176            0,
177            input_frame_.samples_per_channel_ * sizeof(input_frame_.data_[0]));
178 
179     ASSERT_EQ(0, acm_->RegisterTransportCallback(&packet_cb_));
180 
181     SetUpL16Codec();
182   }
183 
184   // Set up L16 codec.
SetUpL16Codec()185   virtual void SetUpL16Codec() {
186     ASSERT_EQ(0, AudioCodingModule::Codec("L16", &codec_, kSampleRateHz, 1));
187     codec_.pltype = kPayloadType;
188   }
189 
RegisterCodec()190   virtual void RegisterCodec() {
191     ASSERT_EQ(0, acm_->RegisterReceiveCodec(codec_));
192     ASSERT_EQ(0, acm_->RegisterSendCodec(codec_));
193   }
194 
InsertPacketAndPullAudio()195   virtual void InsertPacketAndPullAudio() {
196     InsertPacket();
197     PullAudio();
198   }
199 
InsertPacket()200   virtual void InsertPacket() {
201     const uint8_t kPayload[kPayloadSizeBytes] = {0};
202     ASSERT_EQ(0,
203               acm_->IncomingPacket(kPayload, kPayloadSizeBytes, rtp_header_));
204     rtp_utility_->Forward(&rtp_header_);
205   }
206 
PullAudio()207   virtual void PullAudio() {
208     AudioFrame audio_frame;
209     ASSERT_EQ(0, acm_->PlayoutData10Ms(-1, &audio_frame));
210   }
211 
InsertAudio()212   virtual void InsertAudio() {
213     ASSERT_GE(acm_->Add10MsData(input_frame_), 0);
214     input_frame_.timestamp_ += kNumSamples10ms;
215   }
216 
VerifyEncoding()217   virtual void VerifyEncoding() {
218     int last_length = packet_cb_.last_payload_len_bytes();
219     EXPECT_TRUE(last_length == 2 * codec_.pacsize || last_length == 0)
220         << "Last encoded packet was " << last_length << " bytes.";
221   }
222 
InsertAudioAndVerifyEncoding()223   virtual void InsertAudioAndVerifyEncoding() {
224     InsertAudio();
225     VerifyEncoding();
226   }
227 
228   const int id_;
229   rtc::scoped_ptr<RtpUtility> rtp_utility_;
230   rtc::scoped_ptr<AudioCodingModule> acm_;
231   PacketizationCallbackStubOldApi packet_cb_;
232   WebRtcRTPHeader rtp_header_;
233   AudioFrame input_frame_;
234   CodecInst codec_;
235   Clock* clock_;
236 };
237 
238 // Check if the statistics are initialized correctly. Before any call to ACM
239 // all fields have to be zero.
240 #if defined(WEBRTC_ANDROID)
241 #define MAYBE_InitializedToZero DISABLED_InitializedToZero
242 #else
243 #define MAYBE_InitializedToZero InitializedToZero
244 #endif
TEST_F(AudioCodingModuleTestOldApi,MAYBE_InitializedToZero)245 TEST_F(AudioCodingModuleTestOldApi, MAYBE_InitializedToZero) {
246   RegisterCodec();
247   AudioDecodingCallStats stats;
248   acm_->GetDecodingCallStatistics(&stats);
249   EXPECT_EQ(0, stats.calls_to_neteq);
250   EXPECT_EQ(0, stats.calls_to_silence_generator);
251   EXPECT_EQ(0, stats.decoded_normal);
252   EXPECT_EQ(0, stats.decoded_cng);
253   EXPECT_EQ(0, stats.decoded_plc);
254   EXPECT_EQ(0, stats.decoded_plc_cng);
255 }
256 
257 // Insert some packets and pull audio. Check statistics are valid. Then,
258 // simulate packet loss and check if PLC and PLC-to-CNG statistics are
259 // correctly updated.
260 #if defined(WEBRTC_ANDROID)
261 #define MAYBE_NetEqCalls DISABLED_NetEqCalls
262 #else
263 #define MAYBE_NetEqCalls NetEqCalls
264 #endif
TEST_F(AudioCodingModuleTestOldApi,MAYBE_NetEqCalls)265 TEST_F(AudioCodingModuleTestOldApi, MAYBE_NetEqCalls) {
266   RegisterCodec();
267   AudioDecodingCallStats stats;
268   const int kNumNormalCalls = 10;
269 
270   for (int num_calls = 0; num_calls < kNumNormalCalls; ++num_calls) {
271     InsertPacketAndPullAudio();
272   }
273   acm_->GetDecodingCallStatistics(&stats);
274   EXPECT_EQ(kNumNormalCalls, stats.calls_to_neteq);
275   EXPECT_EQ(0, stats.calls_to_silence_generator);
276   EXPECT_EQ(kNumNormalCalls, stats.decoded_normal);
277   EXPECT_EQ(0, stats.decoded_cng);
278   EXPECT_EQ(0, stats.decoded_plc);
279   EXPECT_EQ(0, stats.decoded_plc_cng);
280 
281   const int kNumPlc = 3;
282   const int kNumPlcCng = 5;
283 
284   // Simulate packet-loss. NetEq first performs PLC then PLC fades to CNG.
285   for (int n = 0; n < kNumPlc + kNumPlcCng; ++n) {
286     PullAudio();
287   }
288   acm_->GetDecodingCallStatistics(&stats);
289   EXPECT_EQ(kNumNormalCalls + kNumPlc + kNumPlcCng, stats.calls_to_neteq);
290   EXPECT_EQ(0, stats.calls_to_silence_generator);
291   EXPECT_EQ(kNumNormalCalls, stats.decoded_normal);
292   EXPECT_EQ(0, stats.decoded_cng);
293   EXPECT_EQ(kNumPlc, stats.decoded_plc);
294   EXPECT_EQ(kNumPlcCng, stats.decoded_plc_cng);
295 }
296 
TEST_F(AudioCodingModuleTestOldApi,VerifyOutputFrame)297 TEST_F(AudioCodingModuleTestOldApi, VerifyOutputFrame) {
298   AudioFrame audio_frame;
299   const int kSampleRateHz = 32000;
300   EXPECT_EQ(0, acm_->PlayoutData10Ms(kSampleRateHz, &audio_frame));
301   EXPECT_EQ(id_, audio_frame.id_);
302   EXPECT_EQ(0u, audio_frame.timestamp_);
303   EXPECT_GT(audio_frame.num_channels_, 0u);
304   EXPECT_EQ(static_cast<size_t>(kSampleRateHz / 100),
305             audio_frame.samples_per_channel_);
306   EXPECT_EQ(kSampleRateHz, audio_frame.sample_rate_hz_);
307 }
308 
TEST_F(AudioCodingModuleTestOldApi,FailOnZeroDesiredFrequency)309 TEST_F(AudioCodingModuleTestOldApi, FailOnZeroDesiredFrequency) {
310   AudioFrame audio_frame;
311   EXPECT_EQ(-1, acm_->PlayoutData10Ms(0, &audio_frame));
312 }
313 
314 // Checks that the transport callback is invoked once for each speech packet.
315 // Also checks that the frame type is kAudioFrameSpeech.
TEST_F(AudioCodingModuleTestOldApi,TransportCallbackIsInvokedForEachPacket)316 TEST_F(AudioCodingModuleTestOldApi, TransportCallbackIsInvokedForEachPacket) {
317   const int k10MsBlocksPerPacket = 3;
318   codec_.pacsize = k10MsBlocksPerPacket * kSampleRateHz / 100;
319   RegisterCodec();
320   const int kLoops = 10;
321   for (int i = 0; i < kLoops; ++i) {
322     EXPECT_EQ(i / k10MsBlocksPerPacket, packet_cb_.num_calls());
323     if (packet_cb_.num_calls() > 0)
324       EXPECT_EQ(kAudioFrameSpeech, packet_cb_.last_frame_type());
325     InsertAudioAndVerifyEncoding();
326   }
327   EXPECT_EQ(kLoops / k10MsBlocksPerPacket, packet_cb_.num_calls());
328   EXPECT_EQ(kAudioFrameSpeech, packet_cb_.last_frame_type());
329 }
330 
331 #if defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX)
332 // Verifies that the RTP timestamp series is not reset when the codec is
333 // changed.
TEST_F(AudioCodingModuleTestOldApi,TimestampSeriesContinuesWhenCodecChanges)334 TEST_F(AudioCodingModuleTestOldApi, TimestampSeriesContinuesWhenCodecChanges) {
335   RegisterCodec();  // This registers the default codec.
336   uint32_t expected_ts = input_frame_.timestamp_;
337   int blocks_per_packet = codec_.pacsize / (kSampleRateHz / 100);
338   // Encode 5 packets of the first codec type.
339   const int kNumPackets1 = 5;
340   for (int j = 0; j < kNumPackets1; ++j) {
341     for (int i = 0; i < blocks_per_packet; ++i) {
342       EXPECT_EQ(j, packet_cb_.num_calls());
343       InsertAudio();
344     }
345     EXPECT_EQ(j + 1, packet_cb_.num_calls());
346     EXPECT_EQ(expected_ts, packet_cb_.last_timestamp());
347     expected_ts += codec_.pacsize;
348   }
349 
350   // Change codec.
351   ASSERT_EQ(0, AudioCodingModule::Codec("ISAC", &codec_, kSampleRateHz, 1));
352   RegisterCodec();
353   blocks_per_packet = codec_.pacsize / (kSampleRateHz / 100);
354   // Encode another 5 packets.
355   const int kNumPackets2 = 5;
356   for (int j = 0; j < kNumPackets2; ++j) {
357     for (int i = 0; i < blocks_per_packet; ++i) {
358       EXPECT_EQ(kNumPackets1 + j, packet_cb_.num_calls());
359       InsertAudio();
360     }
361     EXPECT_EQ(kNumPackets1 + j + 1, packet_cb_.num_calls());
362     EXPECT_EQ(expected_ts, packet_cb_.last_timestamp());
363     expected_ts += codec_.pacsize;
364   }
365 }
366 #endif
367 
368 // Introduce this class to set different expectations on the number of encoded
369 // bytes. This class expects all encoded packets to be 9 bytes (matching one
370 // CNG SID frame) or 0 bytes. This test depends on |input_frame_| containing
371 // (near-)zero values. It also introduces a way to register comfort noise with
372 // a custom payload type.
373 class AudioCodingModuleTestWithComfortNoiseOldApi
374     : public AudioCodingModuleTestOldApi {
375  protected:
RegisterCngCodec(int rtp_payload_type)376   void RegisterCngCodec(int rtp_payload_type) {
377     CodecInst codec;
378     AudioCodingModule::Codec("CN", &codec, kSampleRateHz, 1);
379     codec.pltype = rtp_payload_type;
380     ASSERT_EQ(0, acm_->RegisterReceiveCodec(codec));
381     ASSERT_EQ(0, acm_->RegisterSendCodec(codec));
382   }
383 
VerifyEncoding()384   void VerifyEncoding() override {
385     int last_length = packet_cb_.last_payload_len_bytes();
386     EXPECT_TRUE(last_length == 9 || last_length == 0)
387         << "Last encoded packet was " << last_length << " bytes.";
388   }
389 
DoTest(int blocks_per_packet,int cng_pt)390   void DoTest(int blocks_per_packet, int cng_pt) {
391     const int kLoops = 40;
392     // This array defines the expected frame types, and when they should arrive.
393     // We expect a frame to arrive each time the speech encoder would have
394     // produced a packet, and once every 100 ms the frame should be non-empty,
395     // that is contain comfort noise.
396     const struct {
397       int ix;
398       FrameType type;
399     } expectation[] = {{2, kAudioFrameCN},
400                        {5, kEmptyFrame},
401                        {8, kEmptyFrame},
402                        {11, kAudioFrameCN},
403                        {14, kEmptyFrame},
404                        {17, kEmptyFrame},
405                        {20, kAudioFrameCN},
406                        {23, kEmptyFrame},
407                        {26, kEmptyFrame},
408                        {29, kEmptyFrame},
409                        {32, kAudioFrameCN},
410                        {35, kEmptyFrame},
411                        {38, kEmptyFrame}};
412     for (int i = 0; i < kLoops; ++i) {
413       int num_calls_before = packet_cb_.num_calls();
414       EXPECT_EQ(i / blocks_per_packet, num_calls_before);
415       InsertAudioAndVerifyEncoding();
416       int num_calls = packet_cb_.num_calls();
417       if (num_calls == num_calls_before + 1) {
418         EXPECT_EQ(expectation[num_calls - 1].ix, i);
419         EXPECT_EQ(expectation[num_calls - 1].type, packet_cb_.last_frame_type())
420             << "Wrong frame type for lap " << i;
421         EXPECT_EQ(cng_pt, packet_cb_.last_payload_type());
422       } else {
423         EXPECT_EQ(num_calls, num_calls_before);
424       }
425     }
426   }
427 };
428 
429 // Checks that the transport callback is invoked once per frame period of the
430 // underlying speech encoder, even when comfort noise is produced.
431 // Also checks that the frame type is kAudioFrameCN or kEmptyFrame.
432 // This test and the next check the same thing, but differ in the order of
433 // speech codec and CNG registration.
TEST_F(AudioCodingModuleTestWithComfortNoiseOldApi,TransportCallbackTestForComfortNoiseRegisterCngLast)434 TEST_F(AudioCodingModuleTestWithComfortNoiseOldApi,
435        TransportCallbackTestForComfortNoiseRegisterCngLast) {
436   const int k10MsBlocksPerPacket = 3;
437   codec_.pacsize = k10MsBlocksPerPacket * kSampleRateHz / 100;
438   RegisterCodec();
439   const int kCngPayloadType = 105;
440   RegisterCngCodec(kCngPayloadType);
441   ASSERT_EQ(0, acm_->SetVAD(true, true));
442   DoTest(k10MsBlocksPerPacket, kCngPayloadType);
443 }
444 
TEST_F(AudioCodingModuleTestWithComfortNoiseOldApi,TransportCallbackTestForComfortNoiseRegisterCngFirst)445 TEST_F(AudioCodingModuleTestWithComfortNoiseOldApi,
446        TransportCallbackTestForComfortNoiseRegisterCngFirst) {
447   const int k10MsBlocksPerPacket = 3;
448   codec_.pacsize = k10MsBlocksPerPacket * kSampleRateHz / 100;
449   const int kCngPayloadType = 105;
450   RegisterCngCodec(kCngPayloadType);
451   RegisterCodec();
452   ASSERT_EQ(0, acm_->SetVAD(true, true));
453   DoTest(k10MsBlocksPerPacket, kCngPayloadType);
454 }
455 
456 // A multi-threaded test for ACM. This base class is using the PCM16b 16 kHz
457 // codec, while the derive class AcmIsacMtTest is using iSAC.
458 class AudioCodingModuleMtTestOldApi : public AudioCodingModuleTestOldApi {
459  protected:
460   static const int kNumPackets = 500;
461   static const int kNumPullCalls = 500;
462 
AudioCodingModuleMtTestOldApi()463   AudioCodingModuleMtTestOldApi()
464       : AudioCodingModuleTestOldApi(),
465         send_thread_(CbSendThread, this, "send"),
466         insert_packet_thread_(CbInsertPacketThread, this, "insert_packet"),
467         pull_audio_thread_(CbPullAudioThread, this, "pull_audio"),
468         test_complete_(EventWrapper::Create()),
469         send_count_(0),
470         insert_packet_count_(0),
471         pull_audio_count_(0),
472         crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
473         next_insert_packet_time_ms_(0),
474         fake_clock_(new SimulatedClock(0)) {
475     clock_ = fake_clock_.get();
476   }
477 
SetUp()478   void SetUp() {
479     AudioCodingModuleTestOldApi::SetUp();
480     RegisterCodec();  // Must be called before the threads start below.
481     StartThreads();
482   }
483 
StartThreads()484   void StartThreads() {
485     send_thread_.Start();
486     send_thread_.SetPriority(rtc::kRealtimePriority);
487     insert_packet_thread_.Start();
488     insert_packet_thread_.SetPriority(rtc::kRealtimePriority);
489     pull_audio_thread_.Start();
490     pull_audio_thread_.SetPriority(rtc::kRealtimePriority);
491   }
492 
TearDown()493   void TearDown() {
494     AudioCodingModuleTestOldApi::TearDown();
495     pull_audio_thread_.Stop();
496     send_thread_.Stop();
497     insert_packet_thread_.Stop();
498   }
499 
RunTest()500   EventTypeWrapper RunTest() {
501     return test_complete_->Wait(10 * 60 * 1000);  // 10 minutes' timeout.
502   }
503 
TestDone()504   virtual bool TestDone() {
505     if (packet_cb_.num_calls() > kNumPackets) {
506       CriticalSectionScoped lock(crit_sect_.get());
507       if (pull_audio_count_ > kNumPullCalls) {
508         // Both conditions for completion are met. End the test.
509         return true;
510       }
511     }
512     return false;
513   }
514 
CbSendThread(void * context)515   static bool CbSendThread(void* context) {
516     return reinterpret_cast<AudioCodingModuleMtTestOldApi*>(context)
517         ->CbSendImpl();
518   }
519 
520   // The send thread doesn't have to care about the current simulated time,
521   // since only the AcmReceiver is using the clock.
CbSendImpl()522   bool CbSendImpl() {
523     SleepMs(1);
524     if (HasFatalFailure()) {
525       // End the test early if a fatal failure (ASSERT_*) has occurred.
526       test_complete_->Set();
527     }
528     ++send_count_;
529     InsertAudioAndVerifyEncoding();
530     if (TestDone()) {
531       test_complete_->Set();
532     }
533     return true;
534   }
535 
CbInsertPacketThread(void * context)536   static bool CbInsertPacketThread(void* context) {
537     return reinterpret_cast<AudioCodingModuleMtTestOldApi*>(context)
538         ->CbInsertPacketImpl();
539   }
540 
CbInsertPacketImpl()541   bool CbInsertPacketImpl() {
542     SleepMs(1);
543     {
544       CriticalSectionScoped lock(crit_sect_.get());
545       if (clock_->TimeInMilliseconds() < next_insert_packet_time_ms_) {
546         return true;
547       }
548       next_insert_packet_time_ms_ += 10;
549     }
550     // Now we're not holding the crit sect when calling ACM.
551     ++insert_packet_count_;
552     InsertPacket();
553     return true;
554   }
555 
CbPullAudioThread(void * context)556   static bool CbPullAudioThread(void* context) {
557     return reinterpret_cast<AudioCodingModuleMtTestOldApi*>(context)
558         ->CbPullAudioImpl();
559   }
560 
CbPullAudioImpl()561   bool CbPullAudioImpl() {
562     SleepMs(1);
563     {
564       CriticalSectionScoped lock(crit_sect_.get());
565       // Don't let the insert thread fall behind.
566       if (next_insert_packet_time_ms_ < clock_->TimeInMilliseconds()) {
567         return true;
568       }
569       ++pull_audio_count_;
570     }
571     // Now we're not holding the crit sect when calling ACM.
572     PullAudio();
573     fake_clock_->AdvanceTimeMilliseconds(10);
574     return true;
575   }
576 
577   rtc::PlatformThread send_thread_;
578   rtc::PlatformThread insert_packet_thread_;
579   rtc::PlatformThread pull_audio_thread_;
580   const rtc::scoped_ptr<EventWrapper> test_complete_;
581   int send_count_;
582   int insert_packet_count_;
583   int pull_audio_count_ GUARDED_BY(crit_sect_);
584   const rtc::scoped_ptr<CriticalSectionWrapper> crit_sect_;
585   int64_t next_insert_packet_time_ms_ GUARDED_BY(crit_sect_);
586   rtc::scoped_ptr<SimulatedClock> fake_clock_;
587 };
588 
589 #if defined(WEBRTC_IOS)
590 #define MAYBE_DoTest DISABLED_DoTest
591 #else
592 #define MAYBE_DoTest DoTest
593 #endif
TEST_F(AudioCodingModuleMtTestOldApi,MAYBE_DoTest)594 TEST_F(AudioCodingModuleMtTestOldApi, MAYBE_DoTest) {
595   EXPECT_EQ(kEventSignaled, RunTest());
596 }
597 
598 // This is a multi-threaded ACM test using iSAC. The test encodes audio
599 // from a PCM file. The most recent encoded frame is used as input to the
600 // receiving part. Depending on timing, it may happen that the same RTP packet
601 // is inserted into the receiver multiple times, but this is a valid use-case,
602 // and simplifies the test code a lot.
603 class AcmIsacMtTestOldApi : public AudioCodingModuleMtTestOldApi {
604  protected:
605   static const int kNumPackets = 500;
606   static const int kNumPullCalls = 500;
607 
AcmIsacMtTestOldApi()608   AcmIsacMtTestOldApi()
609       : AudioCodingModuleMtTestOldApi(), last_packet_number_(0) {}
610 
~AcmIsacMtTestOldApi()611   ~AcmIsacMtTestOldApi() {}
612 
SetUp()613   void SetUp() {
614     AudioCodingModuleTestOldApi::SetUp();
615     RegisterCodec();  // Must be called before the threads start below.
616 
617     // Set up input audio source to read from specified file, loop after 5
618     // seconds, and deliver blocks of 10 ms.
619     const std::string input_file_name =
620         webrtc::test::ResourcePath("audio_coding/speech_mono_16kHz", "pcm");
621     audio_loop_.Init(input_file_name, 5 * kSampleRateHz, kNumSamples10ms);
622 
623     // Generate one packet to have something to insert.
624     int loop_counter = 0;
625     while (packet_cb_.last_payload_len_bytes() == 0) {
626       InsertAudio();
627       ASSERT_LT(loop_counter++, 10);
628     }
629     // Set |last_packet_number_| to one less that |num_calls| so that the packet
630     // will be fetched in the next InsertPacket() call.
631     last_packet_number_ = packet_cb_.num_calls() - 1;
632 
633     StartThreads();
634   }
635 
RegisterCodec()636   void RegisterCodec() override {
637     static_assert(kSampleRateHz == 16000, "test designed for iSAC 16 kHz");
638     AudioCodingModule::Codec("ISAC", &codec_, kSampleRateHz, 1);
639     codec_.pltype = kPayloadType;
640 
641     // Register iSAC codec in ACM, effectively unregistering the PCM16B codec
642     // registered in AudioCodingModuleTestOldApi::SetUp();
643     ASSERT_EQ(0, acm_->RegisterReceiveCodec(codec_));
644     ASSERT_EQ(0, acm_->RegisterSendCodec(codec_));
645   }
646 
InsertPacket()647   void InsertPacket() {
648     int num_calls = packet_cb_.num_calls();  // Store locally for thread safety.
649     if (num_calls > last_packet_number_) {
650       // Get the new payload out from the callback handler.
651       // Note that since we swap buffers here instead of directly inserting
652       // a pointer to the data in |packet_cb_|, we avoid locking the callback
653       // for the duration of the IncomingPacket() call.
654       packet_cb_.SwapBuffers(&last_payload_vec_);
655       ASSERT_GT(last_payload_vec_.size(), 0u);
656       rtp_utility_->Forward(&rtp_header_);
657       last_packet_number_ = num_calls;
658     }
659     ASSERT_GT(last_payload_vec_.size(), 0u);
660     ASSERT_EQ(
661         0,
662         acm_->IncomingPacket(
663             &last_payload_vec_[0], last_payload_vec_.size(), rtp_header_));
664   }
665 
InsertAudio()666   void InsertAudio() {
667     // TODO(kwiberg): Use std::copy here. Might be complications because AFAICS
668     // this call confuses the number of samples with the number of bytes, and
669     // ends up copying only half of what it should.
670     memcpy(input_frame_.data_, audio_loop_.GetNextBlock().data(),
671            kNumSamples10ms);
672     AudioCodingModuleTestOldApi::InsertAudio();
673   }
674 
675   // Override the verification function with no-op, since iSAC produces variable
676   // payload sizes.
VerifyEncoding()677   void VerifyEncoding() override {}
678 
679   // This method is the same as AudioCodingModuleMtTestOldApi::TestDone(), but
680   // here it is using the constants defined in this class (i.e., shorter test
681   // run).
TestDone()682   virtual bool TestDone() {
683     if (packet_cb_.num_calls() > kNumPackets) {
684       CriticalSectionScoped lock(crit_sect_.get());
685       if (pull_audio_count_ > kNumPullCalls) {
686         // Both conditions for completion are met. End the test.
687         return true;
688       }
689     }
690     return false;
691   }
692 
693   int last_packet_number_;
694   std::vector<uint8_t> last_payload_vec_;
695   test::AudioLoop audio_loop_;
696 };
697 
698 #if defined(WEBRTC_IOS)
699 #define MAYBE_DoTest DISABLED_DoTest
700 #else
701 #define MAYBE_DoTest DoTest
702 #endif
703 #if defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX)
TEST_F(AcmIsacMtTestOldApi,MAYBE_DoTest)704 TEST_F(AcmIsacMtTestOldApi, MAYBE_DoTest) {
705   EXPECT_EQ(kEventSignaled, RunTest());
706 }
707 #endif
708 
709 class AcmReRegisterIsacMtTestOldApi : public AudioCodingModuleTestOldApi {
710  protected:
711   static const int kRegisterAfterNumPackets = 5;
712   static const int kNumPackets = 10;
713   static const int kPacketSizeMs = 30;
714   static const int kPacketSizeSamples = kPacketSizeMs * 16;
715 
AcmReRegisterIsacMtTestOldApi()716   AcmReRegisterIsacMtTestOldApi()
717       : AudioCodingModuleTestOldApi(),
718         receive_thread_(CbReceiveThread, this, "receive"),
719         codec_registration_thread_(CbCodecRegistrationThread,
720                                    this,
721                                    "codec_registration"),
722         test_complete_(EventWrapper::Create()),
723         crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
724         codec_registered_(false),
725         receive_packet_count_(0),
726         next_insert_packet_time_ms_(0),
727         fake_clock_(new SimulatedClock(0)) {
728     AudioEncoderIsac::Config config;
729     config.payload_type = kPayloadType;
730     isac_encoder_.reset(new AudioEncoderIsac(config));
731     clock_ = fake_clock_.get();
732   }
733 
SetUp()734   void SetUp() {
735     AudioCodingModuleTestOldApi::SetUp();
736     // Set up input audio source to read from specified file, loop after 5
737     // seconds, and deliver blocks of 10 ms.
738     const std::string input_file_name =
739         webrtc::test::ResourcePath("audio_coding/speech_mono_16kHz", "pcm");
740     audio_loop_.Init(input_file_name, 5 * kSampleRateHz, kNumSamples10ms);
741     RegisterCodec();  // Must be called before the threads start below.
742     StartThreads();
743   }
744 
RegisterCodec()745   void RegisterCodec() override {
746     static_assert(kSampleRateHz == 16000, "test designed for iSAC 16 kHz");
747     AudioCodingModule::Codec("ISAC", &codec_, kSampleRateHz, 1);
748     codec_.pltype = kPayloadType;
749 
750     // Register iSAC codec in ACM, effectively unregistering the PCM16B codec
751     // registered in AudioCodingModuleTestOldApi::SetUp();
752     // Only register the decoder for now. The encoder is registered later.
753     ASSERT_EQ(0, acm_->RegisterReceiveCodec(codec_));
754   }
755 
StartThreads()756   void StartThreads() {
757     receive_thread_.Start();
758     receive_thread_.SetPriority(rtc::kRealtimePriority);
759     codec_registration_thread_.Start();
760     codec_registration_thread_.SetPriority(rtc::kRealtimePriority);
761   }
762 
TearDown()763   void TearDown() {
764     AudioCodingModuleTestOldApi::TearDown();
765     receive_thread_.Stop();
766     codec_registration_thread_.Stop();
767   }
768 
RunTest()769   EventTypeWrapper RunTest() {
770     return test_complete_->Wait(10 * 60 * 1000);  // 10 minutes' timeout.
771   }
772 
CbReceiveThread(void * context)773   static bool CbReceiveThread(void* context) {
774     return reinterpret_cast<AcmReRegisterIsacMtTestOldApi*>(context)
775         ->CbReceiveImpl();
776   }
777 
CbReceiveImpl()778   bool CbReceiveImpl() {
779     SleepMs(1);
780     const size_t max_encoded_bytes = isac_encoder_->MaxEncodedBytes();
781     rtc::scoped_ptr<uint8_t[]> encoded(new uint8_t[max_encoded_bytes]);
782     AudioEncoder::EncodedInfo info;
783     {
784       CriticalSectionScoped lock(crit_sect_.get());
785       if (clock_->TimeInMilliseconds() < next_insert_packet_time_ms_) {
786         return true;
787       }
788       next_insert_packet_time_ms_ += kPacketSizeMs;
789       ++receive_packet_count_;
790 
791       // Encode new frame.
792       uint32_t input_timestamp = rtp_header_.header.timestamp;
793       while (info.encoded_bytes == 0) {
794         info =
795             isac_encoder_->Encode(input_timestamp, audio_loop_.GetNextBlock(),
796                                   max_encoded_bytes, encoded.get());
797         input_timestamp += 160;  // 10 ms at 16 kHz.
798       }
799       EXPECT_EQ(rtp_header_.header.timestamp + kPacketSizeSamples,
800                 input_timestamp);
801       EXPECT_EQ(rtp_header_.header.timestamp, info.encoded_timestamp);
802       EXPECT_EQ(rtp_header_.header.payloadType, info.payload_type);
803     }
804     // Now we're not holding the crit sect when calling ACM.
805 
806     // Insert into ACM.
807     EXPECT_EQ(0, acm_->IncomingPacket(encoded.get(), info.encoded_bytes,
808                                       rtp_header_));
809 
810     // Pull audio.
811     for (int i = 0; i < rtc::CheckedDivExact(kPacketSizeMs, 10); ++i) {
812       AudioFrame audio_frame;
813       EXPECT_EQ(0, acm_->PlayoutData10Ms(-1 /* default output frequency */,
814                                          &audio_frame));
815       fake_clock_->AdvanceTimeMilliseconds(10);
816     }
817     rtp_utility_->Forward(&rtp_header_);
818     return true;
819   }
820 
CbCodecRegistrationThread(void * context)821   static bool CbCodecRegistrationThread(void* context) {
822     return reinterpret_cast<AcmReRegisterIsacMtTestOldApi*>(context)
823         ->CbCodecRegistrationImpl();
824   }
825 
CbCodecRegistrationImpl()826   bool CbCodecRegistrationImpl() {
827     SleepMs(1);
828     if (HasFatalFailure()) {
829       // End the test early if a fatal failure (ASSERT_*) has occurred.
830       test_complete_->Set();
831     }
832     CriticalSectionScoped lock(crit_sect_.get());
833     if (!codec_registered_ &&
834         receive_packet_count_ > kRegisterAfterNumPackets) {
835       // Register the iSAC encoder.
836       EXPECT_EQ(0, acm_->RegisterSendCodec(codec_));
837       codec_registered_ = true;
838     }
839     if (codec_registered_ && receive_packet_count_ > kNumPackets) {
840       test_complete_->Set();
841     }
842     return true;
843   }
844 
845   rtc::PlatformThread receive_thread_;
846   rtc::PlatformThread codec_registration_thread_;
847   const rtc::scoped_ptr<EventWrapper> test_complete_;
848   const rtc::scoped_ptr<CriticalSectionWrapper> crit_sect_;
849   bool codec_registered_ GUARDED_BY(crit_sect_);
850   int receive_packet_count_ GUARDED_BY(crit_sect_);
851   int64_t next_insert_packet_time_ms_ GUARDED_BY(crit_sect_);
852   rtc::scoped_ptr<AudioEncoderIsac> isac_encoder_;
853   rtc::scoped_ptr<SimulatedClock> fake_clock_;
854   test::AudioLoop audio_loop_;
855 };
856 
857 #if defined(WEBRTC_IOS)
858 #define MAYBE_DoTest DISABLED_DoTest
859 #else
860 #define MAYBE_DoTest DoTest
861 #endif
862 #if defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX)
TEST_F(AcmReRegisterIsacMtTestOldApi,MAYBE_DoTest)863 TEST_F(AcmReRegisterIsacMtTestOldApi, MAYBE_DoTest) {
864   EXPECT_EQ(kEventSignaled, RunTest());
865 }
866 #endif
867 
868 // Disabling all of these tests on iOS until file support has been added.
869 // See https://code.google.com/p/webrtc/issues/detail?id=4752 for details.
870 #if !defined(WEBRTC_IOS)
871 
872 class AcmReceiverBitExactnessOldApi : public ::testing::Test {
873  public:
PlatformChecksum(std::string others,std::string win64,std::string android_arm32,std::string android_arm64)874   static std::string PlatformChecksum(std::string others,
875                                       std::string win64,
876                                       std::string android_arm32,
877                                       std::string android_arm64) {
878 #if defined(_WIN32) && defined(WEBRTC_ARCH_64_BITS)
879     return win64;
880 #elif defined(WEBRTC_ANDROID) && defined(WEBRTC_ARCH_ARM)
881     return android_arm32;
882 #elif defined(WEBRTC_ANDROID) && defined(WEBRTC_ARCH_ARM64)
883     return android_arm64;
884 #else
885     return others;
886 #endif
887   }
888 
889  protected:
890   struct ExternalDecoder {
891     int rtp_payload_type;
892     AudioDecoder* external_decoder;
893     int sample_rate_hz;
894     int num_channels;
895     std::string name;
896   };
897 
Run(int output_freq_hz,const std::string & checksum_ref,const std::vector<ExternalDecoder> & external_decoders)898   void Run(int output_freq_hz,
899            const std::string& checksum_ref,
900            const std::vector<ExternalDecoder>& external_decoders) {
901     const std::string input_file_name =
902         webrtc::test::ResourcePath("audio_coding/neteq_universal_new", "rtp");
903     rtc::scoped_ptr<test::RtpFileSource> packet_source(
904         test::RtpFileSource::Create(input_file_name));
905 #ifdef WEBRTC_ANDROID
906     // Filter out iLBC and iSAC-swb since they are not supported on Android.
907     packet_source->FilterOutPayloadType(102);  // iLBC.
908     packet_source->FilterOutPayloadType(104);  // iSAC-swb.
909 #endif
910 
911     test::AudioChecksum checksum;
912     const std::string output_file_name =
913         webrtc::test::OutputPath() +
914         ::testing::UnitTest::GetInstance()
915             ->current_test_info()
916             ->test_case_name() +
917         "_" + ::testing::UnitTest::GetInstance()->current_test_info()->name() +
918         "_output.pcm";
919     test::OutputAudioFile output_file(output_file_name);
920     test::AudioSinkFork output(&checksum, &output_file);
921 
922     test::AcmReceiveTestOldApi test(
923         packet_source.get(),
924         &output,
925         output_freq_hz,
926         test::AcmReceiveTestOldApi::kArbitraryChannels);
927     ASSERT_NO_FATAL_FAILURE(test.RegisterNetEqTestCodecs());
928     for (const auto& ed : external_decoders) {
929       ASSERT_EQ(0, test.RegisterExternalReceiveCodec(
930                        ed.rtp_payload_type, ed.external_decoder,
931                        ed.sample_rate_hz, ed.num_channels, ed.name));
932     }
933     test.Run();
934 
935     std::string checksum_string = checksum.Finish();
936     EXPECT_EQ(checksum_ref, checksum_string);
937 
938     // Delete the output file.
939     remove(output_file_name.c_str());
940   }
941 };
942 
943 #if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX)) && \
944     defined(WEBRTC_CODEC_ILBC) && defined(WEBRTC_CODEC_G722)
945 TEST_F(AcmReceiverBitExactnessOldApi, 8kHzOutput) {
946   Run(8000, PlatformChecksum("908002dc01fc4eb1d2be24eb1d3f354b",
947                              "dcee98c623b147ebe1b40dd30efa896e",
948                              "adc92e173f908f93b96ba5844209815a",
949                              "ba16137d3a5a1e637252289c57522bfe"),
950       std::vector<ExternalDecoder>());
951 }
952 
953 TEST_F(AcmReceiverBitExactnessOldApi, 16kHzOutput) {
954   Run(16000, PlatformChecksum("a909560b5ca49fa472b17b7b277195e9",
955                               "f790e7a8cce4e2c8b7bb5e0e4c5dac0d",
956                               "8cffa6abcb3e18e33b9d857666dff66a",
957                               "66ee001e23534d4dcf5d0f81f916c93b"),
958       std::vector<ExternalDecoder>());
959 }
960 
961 TEST_F(AcmReceiverBitExactnessOldApi, 32kHzOutput) {
962   Run(32000, PlatformChecksum("441aab4b347fb3db4e9244337aca8d8e",
963                               "306e0d990ee6e92de3fbecc0123ece37",
964                               "3e126fe894720c3f85edadcc91964ba5",
965                               "9c6ff204b14152c48fe41d5ab757943b"),
966       std::vector<ExternalDecoder>());
967 }
968 
969 TEST_F(AcmReceiverBitExactnessOldApi, 48kHzOutput) {
970   Run(48000, PlatformChecksum("4ee2730fa1daae755e8a8fd3abd779ec",
971                               "aa7c232f63a67b2a72703593bdd172e0",
972                               "0155665e93067c4e89256b944dd11999",
973                               "fc4f0da8844cd808d822bbddf3b9c285"),
974       std::vector<ExternalDecoder>());
975 }
976 
977 TEST_F(AcmReceiverBitExactnessOldApi, 48kHzOutputExternalDecoder) {
978   // Class intended to forward a call from a mock DecodeInternal to Decode on
979   // the real decoder's Decode. DecodeInternal for the real decoder isn't
980   // public.
981   class DecodeForwarder {
982    public:
DecodeForwarder(AudioDecoder * decoder)983     DecodeForwarder(AudioDecoder* decoder) : decoder_(decoder) {}
Decode(const uint8_t * encoded,size_t encoded_len,int sample_rate_hz,int16_t * decoded,AudioDecoder::SpeechType * speech_type)984     int Decode(const uint8_t* encoded,
985                size_t encoded_len,
986                int sample_rate_hz,
987                int16_t* decoded,
988                AudioDecoder::SpeechType* speech_type) {
989       return decoder_->Decode(encoded, encoded_len, sample_rate_hz,
990                               decoder_->PacketDuration(encoded, encoded_len) *
991                                   decoder_->Channels() * sizeof(int16_t),
992                               decoded, speech_type);
993     }
994 
995    private:
996     AudioDecoder* const decoder_;
997   };
998 
999   AudioDecoderPcmU decoder(1);
1000   DecodeForwarder decode_forwarder(&decoder);
1001   MockAudioDecoder mock_decoder;
1002   // Set expectations on the mock decoder and also delegate the calls to the
1003   // real decoder.
1004   EXPECT_CALL(mock_decoder, IncomingPacket(_, _, _, _, _))
1005       .Times(AtLeast(1))
1006       .WillRepeatedly(Invoke(&decoder, &AudioDecoderPcmU::IncomingPacket));
1007   EXPECT_CALL(mock_decoder, Channels())
1008       .Times(AtLeast(1))
1009       .WillRepeatedly(Invoke(&decoder, &AudioDecoderPcmU::Channels));
1010   EXPECT_CALL(mock_decoder, DecodeInternal(_, _, _, _, _))
1011       .Times(AtLeast(1))
1012       .WillRepeatedly(Invoke(&decode_forwarder, &DecodeForwarder::Decode));
1013   EXPECT_CALL(mock_decoder, HasDecodePlc())
1014       .Times(AtLeast(1))
1015       .WillRepeatedly(Invoke(&decoder, &AudioDecoderPcmU::HasDecodePlc));
1016   EXPECT_CALL(mock_decoder, PacketDuration(_, _))
1017       .Times(AtLeast(1))
1018       .WillRepeatedly(Invoke(&decoder, &AudioDecoderPcmU::PacketDuration));
1019   ExternalDecoder ed;
1020   ed.rtp_payload_type = 0;
1021   ed.external_decoder = &mock_decoder;
1022   ed.sample_rate_hz = 8000;
1023   ed.num_channels = 1;
1024   ed.name = "MockPCMU";
1025   std::vector<ExternalDecoder> external_decoders;
1026   external_decoders.push_back(ed);
1027 
1028   Run(48000, PlatformChecksum("4ee2730fa1daae755e8a8fd3abd779ec",
1029                               "aa7c232f63a67b2a72703593bdd172e0",
1030                               "0155665e93067c4e89256b944dd11999",
1031                               "fc4f0da8844cd808d822bbddf3b9c285"),
1032       external_decoders);
1033 
1034   EXPECT_CALL(mock_decoder, Die());
1035 }
1036 #endif
1037 
1038 // This test verifies bit exactness for the send-side of ACM. The test setup is
1039 // a chain of three different test classes:
1040 //
1041 // test::AcmSendTest -> AcmSenderBitExactness -> test::AcmReceiveTest
1042 //
1043 // The receiver side is driving the test by requesting new packets from
1044 // AcmSenderBitExactness::NextPacket(). This method, in turn, asks for the
1045 // packet from test::AcmSendTest::NextPacket, which inserts audio from the
1046 // input file until one packet is produced. (The input file loops indefinitely.)
1047 // Before passing the packet to the receiver, this test class verifies the
1048 // packet header and updates a payload checksum with the new payload. The
1049 // decoded output from the receiver is also verified with a (separate) checksum.
1050 class AcmSenderBitExactnessOldApi : public ::testing::Test,
1051                                     public test::PacketSource {
1052  protected:
1053   static const int kTestDurationMs = 1000;
1054 
AcmSenderBitExactnessOldApi()1055   AcmSenderBitExactnessOldApi()
1056       : frame_size_rtp_timestamps_(0),
1057         packet_count_(0),
1058         payload_type_(0),
1059         last_sequence_number_(0),
1060         last_timestamp_(0) {}
1061 
1062   // Sets up the test::AcmSendTest object. Returns true on success, otherwise
1063   // false.
SetUpSender()1064   bool SetUpSender() {
1065     const std::string input_file_name =
1066         webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm");
1067     // Note that |audio_source_| will loop forever. The test duration is set
1068     // explicitly by |kTestDurationMs|.
1069     audio_source_.reset(new test::InputAudioFile(input_file_name));
1070     static const int kSourceRateHz = 32000;
1071     send_test_.reset(new test::AcmSendTestOldApi(
1072         audio_source_.get(), kSourceRateHz, kTestDurationMs));
1073     return send_test_.get() != NULL;
1074   }
1075 
1076   // Registers a send codec in the test::AcmSendTest object. Returns true on
1077   // success, false on failure.
RegisterSendCodec(const char * payload_name,int sampling_freq_hz,int channels,int payload_type,int frame_size_samples,int frame_size_rtp_timestamps)1078   bool RegisterSendCodec(const char* payload_name,
1079                          int sampling_freq_hz,
1080                          int channels,
1081                          int payload_type,
1082                          int frame_size_samples,
1083                          int frame_size_rtp_timestamps) {
1084     payload_type_ = payload_type;
1085     frame_size_rtp_timestamps_ = frame_size_rtp_timestamps;
1086     return send_test_->RegisterCodec(payload_name,
1087                                      sampling_freq_hz,
1088                                      channels,
1089                                      payload_type,
1090                                      frame_size_samples);
1091   }
1092 
RegisterExternalSendCodec(AudioEncoder * external_speech_encoder,int payload_type)1093   bool RegisterExternalSendCodec(AudioEncoder* external_speech_encoder,
1094                                  int payload_type) {
1095     payload_type_ = payload_type;
1096     frame_size_rtp_timestamps_ =
1097         external_speech_encoder->Num10MsFramesInNextPacket() *
1098         external_speech_encoder->RtpTimestampRateHz() / 100;
1099     return send_test_->RegisterExternalCodec(external_speech_encoder);
1100   }
1101 
1102   // Runs the test. SetUpSender() and RegisterSendCodec() must have been called
1103   // before calling this method.
Run(const std::string & audio_checksum_ref,const std::string & payload_checksum_ref,int expected_packets,test::AcmReceiveTestOldApi::NumOutputChannels expected_channels)1104   void Run(const std::string& audio_checksum_ref,
1105            const std::string& payload_checksum_ref,
1106            int expected_packets,
1107            test::AcmReceiveTestOldApi::NumOutputChannels expected_channels) {
1108     // Set up the receiver used to decode the packets and verify the decoded
1109     // output.
1110     test::AudioChecksum audio_checksum;
1111     const std::string output_file_name =
1112         webrtc::test::OutputPath() +
1113         ::testing::UnitTest::GetInstance()
1114             ->current_test_info()
1115             ->test_case_name() +
1116         "_" + ::testing::UnitTest::GetInstance()->current_test_info()->name() +
1117         "_output.pcm";
1118     test::OutputAudioFile output_file(output_file_name);
1119     // Have the output audio sent both to file and to the checksum calculator.
1120     test::AudioSinkFork output(&audio_checksum, &output_file);
1121     const int kOutputFreqHz = 8000;
1122     test::AcmReceiveTestOldApi receive_test(
1123         this, &output, kOutputFreqHz, expected_channels);
1124     ASSERT_NO_FATAL_FAILURE(receive_test.RegisterDefaultCodecs());
1125 
1126     // This is where the actual test is executed.
1127     receive_test.Run();
1128 
1129     // Extract and verify the audio checksum.
1130     std::string checksum_string = audio_checksum.Finish();
1131     EXPECT_EQ(audio_checksum_ref, checksum_string);
1132 
1133     // Extract and verify the payload checksum.
1134     char checksum_result[rtc::Md5Digest::kSize];
1135     payload_checksum_.Finish(checksum_result, rtc::Md5Digest::kSize);
1136     checksum_string = rtc::hex_encode(checksum_result, rtc::Md5Digest::kSize);
1137     EXPECT_EQ(payload_checksum_ref, checksum_string);
1138 
1139     // Verify number of packets produced.
1140     EXPECT_EQ(expected_packets, packet_count_);
1141 
1142     // Delete the output file.
1143     remove(output_file_name.c_str());
1144   }
1145 
1146   // Returns a pointer to the next packet. Returns NULL if the source is
1147   // depleted (i.e., the test duration is exceeded), or if an error occurred.
1148   // Inherited from test::PacketSource.
NextPacket()1149   test::Packet* NextPacket() override {
1150     // Get the next packet from AcmSendTest. Ownership of |packet| is
1151     // transferred to this method.
1152     test::Packet* packet = send_test_->NextPacket();
1153     if (!packet)
1154       return NULL;
1155 
1156     VerifyPacket(packet);
1157     // TODO(henrik.lundin) Save the packet to file as well.
1158 
1159     // Pass it on to the caller. The caller becomes the owner of |packet|.
1160     return packet;
1161   }
1162 
1163   // Verifies the packet.
VerifyPacket(const test::Packet * packet)1164   void VerifyPacket(const test::Packet* packet) {
1165     EXPECT_TRUE(packet->valid_header());
1166     // (We can check the header fields even if valid_header() is false.)
1167     EXPECT_EQ(payload_type_, packet->header().payloadType);
1168     if (packet_count_ > 0) {
1169       // This is not the first packet.
1170       uint16_t sequence_number_diff =
1171           packet->header().sequenceNumber - last_sequence_number_;
1172       EXPECT_EQ(1, sequence_number_diff);
1173       uint32_t timestamp_diff = packet->header().timestamp - last_timestamp_;
1174       EXPECT_EQ(frame_size_rtp_timestamps_, timestamp_diff);
1175     }
1176     ++packet_count_;
1177     last_sequence_number_ = packet->header().sequenceNumber;
1178     last_timestamp_ = packet->header().timestamp;
1179     // Update the checksum.
1180     payload_checksum_.Update(packet->payload(), packet->payload_length_bytes());
1181   }
1182 
SetUpTest(const char * codec_name,int codec_sample_rate_hz,int channels,int payload_type,int codec_frame_size_samples,int codec_frame_size_rtp_timestamps)1183   void SetUpTest(const char* codec_name,
1184                  int codec_sample_rate_hz,
1185                  int channels,
1186                  int payload_type,
1187                  int codec_frame_size_samples,
1188                  int codec_frame_size_rtp_timestamps) {
1189     ASSERT_TRUE(SetUpSender());
1190     ASSERT_TRUE(RegisterSendCodec(codec_name,
1191                                   codec_sample_rate_hz,
1192                                   channels,
1193                                   payload_type,
1194                                   codec_frame_size_samples,
1195                                   codec_frame_size_rtp_timestamps));
1196   }
1197 
SetUpTestExternalEncoder(AudioEncoder * external_speech_encoder,int payload_type)1198   void SetUpTestExternalEncoder(AudioEncoder* external_speech_encoder,
1199                                 int payload_type) {
1200     ASSERT_TRUE(SetUpSender());
1201     ASSERT_TRUE(
1202         RegisterExternalSendCodec(external_speech_encoder, payload_type));
1203   }
1204 
1205   rtc::scoped_ptr<test::AcmSendTestOldApi> send_test_;
1206   rtc::scoped_ptr<test::InputAudioFile> audio_source_;
1207   uint32_t frame_size_rtp_timestamps_;
1208   int packet_count_;
1209   uint8_t payload_type_;
1210   uint16_t last_sequence_number_;
1211   uint32_t last_timestamp_;
1212   rtc::Md5Digest payload_checksum_;
1213 };
1214 
1215 #if defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX)
TEST_F(AcmSenderBitExactnessOldApi,IsacWb30ms)1216 TEST_F(AcmSenderBitExactnessOldApi, IsacWb30ms) {
1217   ASSERT_NO_FATAL_FAILURE(SetUpTest("ISAC", 16000, 1, 103, 480, 480));
1218   Run(AcmReceiverBitExactnessOldApi::PlatformChecksum(
1219           "0b58f9eeee43d5891f5f6c75e77984a3",
1220           "c7e5bdadfa2871df95639fcc297cf23d",
1221           "0499ca260390769b3172136faad925b9",
1222           "866abf524acd2807efbe65e133c23f95"),
1223       AcmReceiverBitExactnessOldApi::PlatformChecksum(
1224           "3c79f16f34218271f3dca4e2b1dfe1bb",
1225           "d42cb5195463da26c8129bbfe73a22e6",
1226           "83de248aea9c3c2bd680b6952401b4ca",
1227           "3c79f16f34218271f3dca4e2b1dfe1bb"),
1228       33, test::AcmReceiveTestOldApi::kMonoOutput);
1229 }
1230 
TEST_F(AcmSenderBitExactnessOldApi,IsacWb60ms)1231 TEST_F(AcmSenderBitExactnessOldApi, IsacWb60ms) {
1232   ASSERT_NO_FATAL_FAILURE(SetUpTest("ISAC", 16000, 1, 103, 960, 960));
1233   Run(AcmReceiverBitExactnessOldApi::PlatformChecksum(
1234           "1ad29139a04782a33daad8c2b9b35875",
1235           "14d63c5f08127d280e722e3191b73bdd",
1236           "8da003e16c5371af2dc2be79a50f9076",
1237           "ef75e900e6f375e3061163c53fd09a63"),
1238       AcmReceiverBitExactnessOldApi::PlatformChecksum(
1239           "9e0a0ab743ad987b55b8e14802769c56",
1240           "ebe04a819d3a9d83a83a17f271e1139a",
1241           "97aeef98553b5a4b5a68f8b716e8eaf0",
1242           "9e0a0ab743ad987b55b8e14802769c56"),
1243       16, test::AcmReceiveTestOldApi::kMonoOutput);
1244 }
1245 #endif
1246 
1247 #if defined(WEBRTC_ANDROID)
1248 #define MAYBE_IsacSwb30ms DISABLED_IsacSwb30ms
1249 #else
1250 #define MAYBE_IsacSwb30ms IsacSwb30ms
1251 #endif
1252 #if defined(WEBRTC_CODEC_ISAC)
TEST_F(AcmSenderBitExactnessOldApi,MAYBE_IsacSwb30ms)1253 TEST_F(AcmSenderBitExactnessOldApi, MAYBE_IsacSwb30ms) {
1254   ASSERT_NO_FATAL_FAILURE(SetUpTest("ISAC", 32000, 1, 104, 960, 960));
1255   Run(AcmReceiverBitExactnessOldApi::PlatformChecksum(
1256           "5683b58da0fbf2063c7adc2e6bfb3fb8",
1257           "2b3c387d06f00b7b7aad4c9be56fb83d", "android_arm32_audio",
1258           "android_arm64_audio"),
1259       AcmReceiverBitExactnessOldApi::PlatformChecksum(
1260           "ce86106a93419aefb063097108ec94ab",
1261           "bcc2041e7744c7ebd9f701866856849c", "android_arm32_payload",
1262           "android_arm64_payload"),
1263       33, test::AcmReceiveTestOldApi::kMonoOutput);
1264 }
1265 #endif
1266 
TEST_F(AcmSenderBitExactnessOldApi,Pcm16_8000khz_10ms)1267 TEST_F(AcmSenderBitExactnessOldApi, Pcm16_8000khz_10ms) {
1268   ASSERT_NO_FATAL_FAILURE(SetUpTest("L16", 8000, 1, 107, 80, 80));
1269   Run("de4a98e1406f8b798d99cd0704e862e2",
1270       "c1edd36339ce0326cc4550041ad719a0",
1271       100,
1272       test::AcmReceiveTestOldApi::kMonoOutput);
1273 }
1274 
TEST_F(AcmSenderBitExactnessOldApi,Pcm16_16000khz_10ms)1275 TEST_F(AcmSenderBitExactnessOldApi, Pcm16_16000khz_10ms) {
1276   ASSERT_NO_FATAL_FAILURE(SetUpTest("L16", 16000, 1, 108, 160, 160));
1277   Run("ae646d7b68384a1269cc080dd4501916",
1278       "ad786526383178b08d80d6eee06e9bad",
1279       100,
1280       test::AcmReceiveTestOldApi::kMonoOutput);
1281 }
1282 
TEST_F(AcmSenderBitExactnessOldApi,Pcm16_32000khz_10ms)1283 TEST_F(AcmSenderBitExactnessOldApi, Pcm16_32000khz_10ms) {
1284   ASSERT_NO_FATAL_FAILURE(SetUpTest("L16", 32000, 1, 109, 320, 320));
1285   Run("7fe325e8fbaf755e3c5df0b11a4774fb",
1286       "5ef82ea885e922263606c6fdbc49f651",
1287       100,
1288       test::AcmReceiveTestOldApi::kMonoOutput);
1289 }
1290 
TEST_F(AcmSenderBitExactnessOldApi,Pcm16_stereo_8000khz_10ms)1291 TEST_F(AcmSenderBitExactnessOldApi, Pcm16_stereo_8000khz_10ms) {
1292   ASSERT_NO_FATAL_FAILURE(SetUpTest("L16", 8000, 2, 111, 80, 80));
1293   Run("fb263b74e7ac3de915474d77e4744ceb",
1294       "62ce5adb0d4965d0a52ec98ae7f98974",
1295       100,
1296       test::AcmReceiveTestOldApi::kStereoOutput);
1297 }
1298 
TEST_F(AcmSenderBitExactnessOldApi,Pcm16_stereo_16000khz_10ms)1299 TEST_F(AcmSenderBitExactnessOldApi, Pcm16_stereo_16000khz_10ms) {
1300   ASSERT_NO_FATAL_FAILURE(SetUpTest("L16", 16000, 2, 112, 160, 160));
1301   Run("d09e9239553649d7ac93e19d304281fd",
1302       "41ca8edac4b8c71cd54fd9f25ec14870",
1303       100,
1304       test::AcmReceiveTestOldApi::kStereoOutput);
1305 }
1306 
TEST_F(AcmSenderBitExactnessOldApi,Pcm16_stereo_32000khz_10ms)1307 TEST_F(AcmSenderBitExactnessOldApi, Pcm16_stereo_32000khz_10ms) {
1308   ASSERT_NO_FATAL_FAILURE(SetUpTest("L16", 32000, 2, 113, 320, 320));
1309   Run("5f025d4f390982cc26b3d92fe02e3044",
1310       "50e58502fb04421bf5b857dda4c96879",
1311       100,
1312       test::AcmReceiveTestOldApi::kStereoOutput);
1313 }
1314 
TEST_F(AcmSenderBitExactnessOldApi,Pcmu_20ms)1315 TEST_F(AcmSenderBitExactnessOldApi, Pcmu_20ms) {
1316   ASSERT_NO_FATAL_FAILURE(SetUpTest("PCMU", 8000, 1, 0, 160, 160));
1317   Run("81a9d4c0bb72e9becc43aef124c981e9",
1318       "8f9b8750bd80fe26b6cbf6659b89f0f9",
1319       50,
1320       test::AcmReceiveTestOldApi::kMonoOutput);
1321 }
1322 
TEST_F(AcmSenderBitExactnessOldApi,Pcma_20ms)1323 TEST_F(AcmSenderBitExactnessOldApi, Pcma_20ms) {
1324   ASSERT_NO_FATAL_FAILURE(SetUpTest("PCMA", 8000, 1, 8, 160, 160));
1325   Run("39611f798969053925a49dc06d08de29",
1326       "6ad745e55aa48981bfc790d0eeef2dd1",
1327       50,
1328       test::AcmReceiveTestOldApi::kMonoOutput);
1329 }
1330 
TEST_F(AcmSenderBitExactnessOldApi,Pcmu_stereo_20ms)1331 TEST_F(AcmSenderBitExactnessOldApi, Pcmu_stereo_20ms) {
1332   ASSERT_NO_FATAL_FAILURE(SetUpTest("PCMU", 8000, 2, 110, 160, 160));
1333   Run("437bec032fdc5cbaa0d5175430af7b18",
1334       "60b6f25e8d1e74cb679cfe756dd9bca5",
1335       50,
1336       test::AcmReceiveTestOldApi::kStereoOutput);
1337 }
1338 
TEST_F(AcmSenderBitExactnessOldApi,Pcma_stereo_20ms)1339 TEST_F(AcmSenderBitExactnessOldApi, Pcma_stereo_20ms) {
1340   ASSERT_NO_FATAL_FAILURE(SetUpTest("PCMA", 8000, 2, 118, 160, 160));
1341   Run("a5c6d83c5b7cedbeff734238220a4b0c",
1342       "92b282c83efd20e7eeef52ba40842cf7",
1343       50,
1344       test::AcmReceiveTestOldApi::kStereoOutput);
1345 }
1346 
1347 #if defined(WEBRTC_ANDROID)
1348 #define MAYBE_Ilbc_30ms DISABLED_Ilbc_30ms
1349 #else
1350 #define MAYBE_Ilbc_30ms Ilbc_30ms
1351 #endif
1352 #if defined(WEBRTC_CODEC_ILBC)
TEST_F(AcmSenderBitExactnessOldApi,MAYBE_Ilbc_30ms)1353 TEST_F(AcmSenderBitExactnessOldApi, MAYBE_Ilbc_30ms) {
1354   ASSERT_NO_FATAL_FAILURE(SetUpTest("ILBC", 8000, 1, 102, 240, 240));
1355   Run(AcmReceiverBitExactnessOldApi::PlatformChecksum(
1356           "7b6ec10910debd9af08011d3ed5249f7",
1357           "7b6ec10910debd9af08011d3ed5249f7", "android_arm32_audio",
1358           "android_arm64_audio"),
1359       AcmReceiverBitExactnessOldApi::PlatformChecksum(
1360           "cfae2e9f6aba96e145f2bcdd5050ce78",
1361           "cfae2e9f6aba96e145f2bcdd5050ce78", "android_arm32_payload",
1362           "android_arm64_payload"),
1363       33, test::AcmReceiveTestOldApi::kMonoOutput);
1364 }
1365 #endif
1366 
1367 #if defined(WEBRTC_ANDROID)
1368 #define MAYBE_G722_20ms DISABLED_G722_20ms
1369 #else
1370 #define MAYBE_G722_20ms G722_20ms
1371 #endif
1372 #if defined(WEBRTC_CODEC_G722)
TEST_F(AcmSenderBitExactnessOldApi,MAYBE_G722_20ms)1373 TEST_F(AcmSenderBitExactnessOldApi, MAYBE_G722_20ms) {
1374   ASSERT_NO_FATAL_FAILURE(SetUpTest("G722", 16000, 1, 9, 320, 160));
1375   Run(AcmReceiverBitExactnessOldApi::PlatformChecksum(
1376           "7d759436f2533582950d148b5161a36c",
1377           "7d759436f2533582950d148b5161a36c", "android_arm32_audio",
1378           "android_arm64_audio"),
1379       AcmReceiverBitExactnessOldApi::PlatformChecksum(
1380           "fc68a87e1380614e658087cb35d5ca10",
1381           "fc68a87e1380614e658087cb35d5ca10", "android_arm32_payload",
1382           "android_arm64_payload"),
1383       50, test::AcmReceiveTestOldApi::kMonoOutput);
1384 }
1385 #endif
1386 
1387 #if defined(WEBRTC_ANDROID)
1388 #define MAYBE_G722_stereo_20ms DISABLED_G722_stereo_20ms
1389 #else
1390 #define MAYBE_G722_stereo_20ms G722_stereo_20ms
1391 #endif
1392 #if defined(WEBRTC_CODEC_G722)
TEST_F(AcmSenderBitExactnessOldApi,MAYBE_G722_stereo_20ms)1393 TEST_F(AcmSenderBitExactnessOldApi, MAYBE_G722_stereo_20ms) {
1394   ASSERT_NO_FATAL_FAILURE(SetUpTest("G722", 16000, 2, 119, 320, 160));
1395   Run(AcmReceiverBitExactnessOldApi::PlatformChecksum(
1396           "7190ee718ab3d80eca181e5f7140c210",
1397           "7190ee718ab3d80eca181e5f7140c210", "android_arm32_audio",
1398           "android_arm64_audio"),
1399       AcmReceiverBitExactnessOldApi::PlatformChecksum(
1400           "66516152eeaa1e650ad94ff85f668dac",
1401           "66516152eeaa1e650ad94ff85f668dac", "android_arm32_payload",
1402           "android_arm64_payload"),
1403       50, test::AcmReceiveTestOldApi::kStereoOutput);
1404 }
1405 #endif
1406 
TEST_F(AcmSenderBitExactnessOldApi,Opus_stereo_20ms)1407 TEST_F(AcmSenderBitExactnessOldApi, Opus_stereo_20ms) {
1408   ASSERT_NO_FATAL_FAILURE(SetUpTest("opus", 48000, 2, 120, 960, 960));
1409   Run(AcmReceiverBitExactnessOldApi::PlatformChecksum(
1410           "855041f2490b887302bce9d544731849",
1411           "855041f2490b887302bce9d544731849",
1412           "1e1a0fce893fef2d66886a7f09e2ebce",
1413           "7417a66c28be42d5d9b2d64e0c191585"),
1414       AcmReceiverBitExactnessOldApi::PlatformChecksum(
1415           "d781cce1ab986b618d0da87226cdde30",
1416           "d781cce1ab986b618d0da87226cdde30",
1417           "1a1fe04dd12e755949987c8d729fb3e0",
1418           "47b0b04f1d03076b857c86c72c2c298b"),
1419       50, test::AcmReceiveTestOldApi::kStereoOutput);
1420 }
1421 
TEST_F(AcmSenderBitExactnessOldApi,Opus_stereo_20ms_voip)1422 TEST_F(AcmSenderBitExactnessOldApi, Opus_stereo_20ms_voip) {
1423   ASSERT_NO_FATAL_FAILURE(SetUpTest("opus", 48000, 2, 120, 960, 960));
1424   // If not set, default will be kAudio in case of stereo.
1425   EXPECT_EQ(0, send_test_->acm()->SetOpusApplication(kVoip));
1426   Run(AcmReceiverBitExactnessOldApi::PlatformChecksum(
1427           "9b9e12bc3cc793740966e11cbfa8b35b",
1428           "9b9e12bc3cc793740966e11cbfa8b35b",
1429           "57412a4b5771d19ff03ec35deffe7067",
1430           "7ad0bbefcaa87e23187bf4a56d2f3513"),
1431       AcmReceiverBitExactnessOldApi::PlatformChecksum(
1432           "c7340b1189652ab6b5e80dade7390cb4",
1433           "c7340b1189652ab6b5e80dade7390cb4",
1434           "cdfe85939c411d12b61701c566e22d26",
1435           "7a678fbe46df5bf0c67e88264a2d9275"),
1436       50, test::AcmReceiveTestOldApi::kStereoOutput);
1437 }
1438 
1439 // This test is for verifying the SetBitRate function. The bitrate is changed at
1440 // the beginning, and the number of generated bytes are checked.
1441 class AcmSetBitRateOldApi : public ::testing::Test {
1442  protected:
1443   static const int kTestDurationMs = 1000;
1444 
1445   // Sets up the test::AcmSendTest object. Returns true on success, otherwise
1446   // false.
SetUpSender()1447   bool SetUpSender() {
1448     const std::string input_file_name =
1449         webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm");
1450     // Note that |audio_source_| will loop forever. The test duration is set
1451     // explicitly by |kTestDurationMs|.
1452     audio_source_.reset(new test::InputAudioFile(input_file_name));
1453     static const int kSourceRateHz = 32000;
1454     send_test_.reset(new test::AcmSendTestOldApi(
1455         audio_source_.get(), kSourceRateHz, kTestDurationMs));
1456     return send_test_.get();
1457   }
1458 
1459   // Registers a send codec in the test::AcmSendTest object. Returns true on
1460   // success, false on failure.
RegisterSendCodec(const char * payload_name,int sampling_freq_hz,int channels,int payload_type,int frame_size_samples,int frame_size_rtp_timestamps)1461   virtual bool RegisterSendCodec(const char* payload_name,
1462                                  int sampling_freq_hz,
1463                                  int channels,
1464                                  int payload_type,
1465                                  int frame_size_samples,
1466                                  int frame_size_rtp_timestamps) {
1467     return send_test_->RegisterCodec(payload_name, sampling_freq_hz, channels,
1468                                      payload_type, frame_size_samples);
1469   }
1470 
1471   // Runs the test. SetUpSender() and RegisterSendCodec() must have been called
1472   // before calling this method.
Run(int target_bitrate_bps,int expected_total_bits)1473   void Run(int target_bitrate_bps, int expected_total_bits) {
1474     ASSERT_TRUE(send_test_->acm());
1475     send_test_->acm()->SetBitRate(target_bitrate_bps);
1476     int nr_bytes = 0;
1477     while (test::Packet* next_packet = send_test_->NextPacket()) {
1478       nr_bytes += next_packet->payload_length_bytes();
1479       delete next_packet;
1480     }
1481     EXPECT_EQ(expected_total_bits, nr_bytes * 8);
1482   }
1483 
SetUpTest(const char * codec_name,int codec_sample_rate_hz,int channels,int payload_type,int codec_frame_size_samples,int codec_frame_size_rtp_timestamps)1484   void SetUpTest(const char* codec_name,
1485                  int codec_sample_rate_hz,
1486                  int channels,
1487                  int payload_type,
1488                  int codec_frame_size_samples,
1489                  int codec_frame_size_rtp_timestamps) {
1490     ASSERT_TRUE(SetUpSender());
1491     ASSERT_TRUE(RegisterSendCodec(codec_name, codec_sample_rate_hz, channels,
1492                                   payload_type, codec_frame_size_samples,
1493                                   codec_frame_size_rtp_timestamps));
1494   }
1495 
1496   rtc::scoped_ptr<test::AcmSendTestOldApi> send_test_;
1497   rtc::scoped_ptr<test::InputAudioFile> audio_source_;
1498 };
1499 
TEST_F(AcmSetBitRateOldApi,Opus_48khz_20ms_10kbps)1500 TEST_F(AcmSetBitRateOldApi, Opus_48khz_20ms_10kbps) {
1501   ASSERT_NO_FATAL_FAILURE(SetUpTest("opus", 48000, 1, 107, 960, 960));
1502 #if defined(WEBRTC_ANDROID)
1503   Run(10000, 9328);
1504 #else
1505   Run(10000, 9072);
1506 #endif // WEBRTC_ANDROID
1507 
1508 }
1509 
TEST_F(AcmSetBitRateOldApi,Opus_48khz_20ms_50kbps)1510 TEST_F(AcmSetBitRateOldApi, Opus_48khz_20ms_50kbps) {
1511   ASSERT_NO_FATAL_FAILURE(SetUpTest("opus", 48000, 1, 107, 960, 960));
1512 #if defined(WEBRTC_ANDROID)
1513   Run(50000, 47952);
1514 #else
1515   Run(50000, 49600);
1516 #endif // WEBRTC_ANDROID
1517 }
1518 
1519 // The result on the Android platforms is inconsistent for this test case.
1520 // On android_rel the result is different from android and android arm64 rel.
1521 #if defined(WEBRTC_ANDROID)
1522 #define MAYBE_Opus_48khz_20ms_100kbps DISABLED_Opus_48khz_20ms_100kbps
1523 #else
1524 #define MAYBE_Opus_48khz_20ms_100kbps Opus_48khz_20ms_100kbps
1525 #endif
TEST_F(AcmSetBitRateOldApi,MAYBE_Opus_48khz_20ms_100kbps)1526 TEST_F(AcmSetBitRateOldApi, MAYBE_Opus_48khz_20ms_100kbps) {
1527   ASSERT_NO_FATAL_FAILURE(SetUpTest("opus", 48000, 1, 107, 960, 960));
1528   Run(100000, 100888);
1529 }
1530 
1531 // These next 2 tests ensure that the SetBitRate function has no effect on PCM
TEST_F(AcmSetBitRateOldApi,Pcm16_8khz_10ms_8kbps)1532 TEST_F(AcmSetBitRateOldApi, Pcm16_8khz_10ms_8kbps) {
1533   ASSERT_NO_FATAL_FAILURE(SetUpTest("L16", 8000, 1, 107, 80, 80));
1534   Run(8000, 128000);
1535 }
1536 
TEST_F(AcmSetBitRateOldApi,Pcm16_8khz_10ms_32kbps)1537 TEST_F(AcmSetBitRateOldApi, Pcm16_8khz_10ms_32kbps) {
1538   ASSERT_NO_FATAL_FAILURE(SetUpTest("L16", 8000, 1, 107, 80, 80));
1539   Run(32000, 128000);
1540 }
1541 
1542 // This test is for verifying the SetBitRate function. The bitrate is changed
1543 // in the middle, and the number of generated bytes are before and after the
1544 // change are checked.
1545 class AcmChangeBitRateOldApi : public AcmSetBitRateOldApi {
1546  protected:
AcmChangeBitRateOldApi()1547   AcmChangeBitRateOldApi() : sampling_freq_hz_(0), frame_size_samples_(0) {}
1548 
1549   // Registers a send codec in the test::AcmSendTest object. Returns true on
1550   // success, false on failure.
RegisterSendCodec(const char * payload_name,int sampling_freq_hz,int channels,int payload_type,int frame_size_samples,int frame_size_rtp_timestamps)1551   bool RegisterSendCodec(const char* payload_name,
1552                          int sampling_freq_hz,
1553                          int channels,
1554                          int payload_type,
1555                          int frame_size_samples,
1556                          int frame_size_rtp_timestamps) override {
1557     frame_size_samples_ = frame_size_samples;
1558     sampling_freq_hz_ = sampling_freq_hz;
1559     return AcmSetBitRateOldApi::RegisterSendCodec(
1560         payload_name, sampling_freq_hz, channels, payload_type,
1561         frame_size_samples, frame_size_rtp_timestamps);
1562   }
1563 
1564   // Runs the test. SetUpSender() and RegisterSendCodec() must have been called
1565   // before calling this method.
Run(int target_bitrate_bps,int expected_before_switch_bits,int expected_after_switch_bits)1566   void Run(int target_bitrate_bps,
1567            int expected_before_switch_bits,
1568            int expected_after_switch_bits) {
1569     ASSERT_TRUE(send_test_->acm());
1570     int nr_packets =
1571         sampling_freq_hz_ * kTestDurationMs / (frame_size_samples_ * 1000);
1572     int nr_bytes_before = 0, nr_bytes_after = 0;
1573     int packet_counter = 0;
1574     while (test::Packet* next_packet = send_test_->NextPacket()) {
1575       if (packet_counter == nr_packets / 2)
1576         send_test_->acm()->SetBitRate(target_bitrate_bps);
1577       if (packet_counter < nr_packets / 2)
1578         nr_bytes_before += next_packet->payload_length_bytes();
1579       else
1580         nr_bytes_after += next_packet->payload_length_bytes();
1581       packet_counter++;
1582       delete next_packet;
1583     }
1584     EXPECT_EQ(expected_before_switch_bits, nr_bytes_before * 8);
1585     EXPECT_EQ(expected_after_switch_bits, nr_bytes_after * 8);
1586   }
1587 
1588   uint32_t sampling_freq_hz_;
1589   uint32_t frame_size_samples_;
1590 };
1591 
TEST_F(AcmChangeBitRateOldApi,Opus_48khz_20ms_10kbps)1592 TEST_F(AcmChangeBitRateOldApi, Opus_48khz_20ms_10kbps) {
1593   ASSERT_NO_FATAL_FAILURE(SetUpTest("opus", 48000, 1, 107, 960, 960));
1594 #if defined(WEBRTC_ANDROID)
1595   Run(10000, 32200, 5496);
1596 #else
1597   Run(10000, 32200, 5432);
1598 #endif // WEBRTC_ANDROID
1599 }
1600 
TEST_F(AcmChangeBitRateOldApi,Opus_48khz_20ms_50kbps)1601 TEST_F(AcmChangeBitRateOldApi, Opus_48khz_20ms_50kbps) {
1602   ASSERT_NO_FATAL_FAILURE(SetUpTest("opus", 48000, 1, 107, 960, 960));
1603 #if defined(WEBRTC_ANDROID)
1604   Run(50000, 32200, 24912);
1605 #else
1606   Run(50000, 32200, 24792);
1607 #endif // WEBRTC_ANDROID
1608 }
1609 
TEST_F(AcmChangeBitRateOldApi,Opus_48khz_20ms_100kbps)1610 TEST_F(AcmChangeBitRateOldApi, Opus_48khz_20ms_100kbps) {
1611   ASSERT_NO_FATAL_FAILURE(SetUpTest("opus", 48000, 1, 107, 960, 960));
1612 #if defined(WEBRTC_ANDROID)
1613   Run(100000, 32200, 51480);
1614 #else
1615   Run(100000, 32200, 50584);
1616 #endif // WEBRTC_ANDROID
1617 }
1618 
1619 // These next 2 tests ensure that the SetBitRate function has no effect on PCM
TEST_F(AcmChangeBitRateOldApi,Pcm16_8khz_10ms_8kbps)1620 TEST_F(AcmChangeBitRateOldApi, Pcm16_8khz_10ms_8kbps) {
1621   ASSERT_NO_FATAL_FAILURE(SetUpTest("L16", 8000, 1, 107, 80, 80));
1622   Run(8000, 64000, 64000);
1623 }
1624 
TEST_F(AcmChangeBitRateOldApi,Pcm16_8khz_10ms_32kbps)1625 TEST_F(AcmChangeBitRateOldApi, Pcm16_8khz_10ms_32kbps) {
1626   ASSERT_NO_FATAL_FAILURE(SetUpTest("L16", 8000, 1, 107, 80, 80));
1627   Run(32000, 64000, 64000);
1628 }
1629 
TEST_F(AcmSenderBitExactnessOldApi,External_Pcmu_20ms)1630 TEST_F(AcmSenderBitExactnessOldApi, External_Pcmu_20ms) {
1631   CodecInst codec_inst;
1632   codec_inst.channels = 1;
1633   codec_inst.pacsize = 160;
1634   codec_inst.pltype = 0;
1635   AudioEncoderPcmU encoder(codec_inst);
1636   MockAudioEncoder mock_encoder;
1637   // Set expectations on the mock encoder and also delegate the calls to the
1638   // real encoder.
1639   EXPECT_CALL(mock_encoder, MaxEncodedBytes())
1640       .Times(AtLeast(1))
1641       .WillRepeatedly(Invoke(&encoder, &AudioEncoderPcmU::MaxEncodedBytes));
1642   EXPECT_CALL(mock_encoder, SampleRateHz())
1643       .Times(AtLeast(1))
1644       .WillRepeatedly(Invoke(&encoder, &AudioEncoderPcmU::SampleRateHz));
1645   EXPECT_CALL(mock_encoder, NumChannels())
1646       .Times(AtLeast(1))
1647       .WillRepeatedly(Invoke(&encoder, &AudioEncoderPcmU::NumChannels));
1648   EXPECT_CALL(mock_encoder, RtpTimestampRateHz())
1649       .Times(AtLeast(1))
1650       .WillRepeatedly(Invoke(&encoder, &AudioEncoderPcmU::RtpTimestampRateHz));
1651   EXPECT_CALL(mock_encoder, Num10MsFramesInNextPacket())
1652       .Times(AtLeast(1))
1653       .WillRepeatedly(
1654           Invoke(&encoder, &AudioEncoderPcmU::Num10MsFramesInNextPacket));
1655   EXPECT_CALL(mock_encoder, GetTargetBitrate())
1656       .Times(AtLeast(1))
1657       .WillRepeatedly(Invoke(&encoder, &AudioEncoderPcmU::GetTargetBitrate));
1658   EXPECT_CALL(mock_encoder, EncodeInternal(_, _, _, _))
1659       .Times(AtLeast(1))
1660       .WillRepeatedly(Invoke(&encoder, &AudioEncoderPcmU::EncodeInternal));
1661   EXPECT_CALL(mock_encoder, SetFec(_))
1662       .Times(AtLeast(1))
1663       .WillRepeatedly(Invoke(&encoder, &AudioEncoderPcmU::SetFec));
1664   ASSERT_NO_FATAL_FAILURE(
1665       SetUpTestExternalEncoder(&mock_encoder, codec_inst.pltype));
1666   Run("81a9d4c0bb72e9becc43aef124c981e9", "8f9b8750bd80fe26b6cbf6659b89f0f9",
1667       50, test::AcmReceiveTestOldApi::kMonoOutput);
1668 }
1669 
1670 // This test fixture is implemented to run ACM and change the desired output
1671 // frequency during the call. The input packets are simply PCM16b-wb encoded
1672 // payloads with a constant value of |kSampleValue|. The test fixture itself
1673 // acts as PacketSource in between the receive test class and the constant-
1674 // payload packet source class. The output is both written to file, and analyzed
1675 // in this test fixture.
1676 class AcmSwitchingOutputFrequencyOldApi : public ::testing::Test,
1677                                           public test::PacketSource,
1678                                           public test::AudioSink {
1679  protected:
1680   static const size_t kTestNumPackets = 50;
1681   static const int kEncodedSampleRateHz = 16000;
1682   static const size_t kPayloadLenSamples = 30 * kEncodedSampleRateHz / 1000;
1683   static const int kPayloadType = 108;  // Default payload type for PCM16b-wb.
1684 
AcmSwitchingOutputFrequencyOldApi()1685   AcmSwitchingOutputFrequencyOldApi()
1686       : first_output_(true),
1687         num_packets_(0),
1688         packet_source_(kPayloadLenSamples,
1689                        kSampleValue,
1690                        kEncodedSampleRateHz,
1691                        kPayloadType),
1692         output_freq_2_(0),
1693         has_toggled_(false) {}
1694 
Run(int output_freq_1,int output_freq_2,int toggle_period_ms)1695   void Run(int output_freq_1, int output_freq_2, int toggle_period_ms) {
1696     // Set up the receiver used to decode the packets and verify the decoded
1697     // output.
1698     const std::string output_file_name =
1699         webrtc::test::OutputPath() +
1700         ::testing::UnitTest::GetInstance()
1701             ->current_test_info()
1702             ->test_case_name() +
1703         "_" + ::testing::UnitTest::GetInstance()->current_test_info()->name() +
1704         "_output.pcm";
1705     test::OutputAudioFile output_file(output_file_name);
1706     // Have the output audio sent both to file and to the WriteArray method in
1707     // this class.
1708     test::AudioSinkFork output(this, &output_file);
1709     test::AcmReceiveTestToggleOutputFreqOldApi receive_test(
1710         this,
1711         &output,
1712         output_freq_1,
1713         output_freq_2,
1714         toggle_period_ms,
1715         test::AcmReceiveTestOldApi::kMonoOutput);
1716     ASSERT_NO_FATAL_FAILURE(receive_test.RegisterDefaultCodecs());
1717     output_freq_2_ = output_freq_2;
1718 
1719     // This is where the actual test is executed.
1720     receive_test.Run();
1721 
1722     // Delete output file.
1723     remove(output_file_name.c_str());
1724   }
1725 
1726   // Inherited from test::PacketSource.
NextPacket()1727   test::Packet* NextPacket() override {
1728     // Check if it is time to terminate the test. The packet source is of type
1729     // ConstantPcmPacketSource, which is infinite, so we must end the test
1730     // "manually".
1731     if (num_packets_++ > kTestNumPackets) {
1732       EXPECT_TRUE(has_toggled_);
1733       return NULL;  // Test ended.
1734     }
1735 
1736     // Get the next packet from the source.
1737     return packet_source_.NextPacket();
1738   }
1739 
1740   // Inherited from test::AudioSink.
WriteArray(const int16_t * audio,size_t num_samples)1741   bool WriteArray(const int16_t* audio, size_t num_samples) {
1742     // Skip checking the first output frame, since it has a number of zeros
1743     // due to how NetEq is initialized.
1744     if (first_output_) {
1745       first_output_ = false;
1746       return true;
1747     }
1748     for (size_t i = 0; i < num_samples; ++i) {
1749       EXPECT_EQ(kSampleValue, audio[i]);
1750     }
1751     if (num_samples ==
1752         static_cast<size_t>(output_freq_2_ / 100))  // Size of 10 ms frame.
1753       has_toggled_ = true;
1754     // The return value does not say if the values match the expectation, just
1755     // that the method could process the samples.
1756     return true;
1757   }
1758 
1759   const int16_t kSampleValue = 1000;
1760   bool first_output_;
1761   size_t num_packets_;
1762   test::ConstantPcmPacketSource packet_source_;
1763   int output_freq_2_;
1764   bool has_toggled_;
1765 };
1766 
TEST_F(AcmSwitchingOutputFrequencyOldApi,TestWithoutToggling)1767 TEST_F(AcmSwitchingOutputFrequencyOldApi, TestWithoutToggling) {
1768   Run(16000, 16000, 1000);
1769 }
1770 
TEST_F(AcmSwitchingOutputFrequencyOldApi,Toggle16KhzTo32Khz)1771 TEST_F(AcmSwitchingOutputFrequencyOldApi, Toggle16KhzTo32Khz) {
1772   Run(16000, 32000, 1000);
1773 }
1774 
TEST_F(AcmSwitchingOutputFrequencyOldApi,Toggle32KhzTo16Khz)1775 TEST_F(AcmSwitchingOutputFrequencyOldApi, Toggle32KhzTo16Khz) {
1776   Run(32000, 16000, 1000);
1777 }
1778 
TEST_F(AcmSwitchingOutputFrequencyOldApi,Toggle16KhzTo8Khz)1779 TEST_F(AcmSwitchingOutputFrequencyOldApi, Toggle16KhzTo8Khz) {
1780   Run(16000, 8000, 1000);
1781 }
1782 
TEST_F(AcmSwitchingOutputFrequencyOldApi,Toggle8KhzTo16Khz)1783 TEST_F(AcmSwitchingOutputFrequencyOldApi, Toggle8KhzTo16Khz) {
1784   Run(8000, 16000, 1000);
1785 }
1786 
1787 #endif
1788 
1789 }  // namespace webrtc
1790