Index: webrtc/modules/audio_coding/main/acm2/audio_coding_module_unittest_oldapi.cc |
diff --git a/webrtc/modules/audio_coding/main/acm2/audio_coding_module_unittest_oldapi.cc b/webrtc/modules/audio_coding/main/acm2/audio_coding_module_unittest_oldapi.cc |
index d97f4e65b35db3049cac1c30466a4041bd0d1d4b..183d526ffc3ce2d694ab02286a06514c2a094a8e 100644 |
--- a/webrtc/modules/audio_coding/main/acm2/audio_coding_module_unittest_oldapi.cc |
+++ b/webrtc/modules/audio_coding/main/acm2/audio_coding_module_unittest_oldapi.cc |
@@ -17,6 +17,7 @@ |
#include "webrtc/base/thread_annotations.h" |
#include "webrtc/modules/audio_coding/codecs/audio_encoder.h" |
#include "webrtc/modules/audio_coding/codecs/g711/include/audio_encoder_pcm.h" |
+#include "webrtc/modules/audio_coding/codecs/isac/main/interface/audio_encoder_isac.h" |
#include "webrtc/modules/audio_coding/codecs/mock/mock_audio_encoder.h" |
#include "webrtc/modules/audio_coding/main/acm2/acm_receive_test_oldapi.h" |
#include "webrtc/modules/audio_coding/main/acm2/acm_send_test_oldapi.h" |
@@ -699,6 +700,160 @@ TEST_F(AcmIsacMtTestOldApi, DISABLED_ON_IOS(DoTest)) { |
EXPECT_EQ(kEventSignaled, RunTest()); |
} |
+class AcmReRegisterIsacMtTestOldApi : public AudioCodingModuleTestOldApi { |
+ protected: |
+ static const int kRegisterAfterNumPackets = 5; |
+ static const int kNumPackets = 10; |
+ static const int kPacketSizeMs = 30; |
+ static const int kPacketSizeSamples = kPacketSizeMs * 16; |
+ |
+ AcmReRegisterIsacMtTestOldApi() |
+ : AudioCodingModuleTestOldApi(), |
+ receive_thread_( |
+ ThreadWrapper::CreateThread(CbReceiveThread, this, "receive")), |
+ codec_registration_thread_( |
+ ThreadWrapper::CreateThread(CbCodecRegistrationThread, |
+ this, |
+ "codec_registration")), |
+ test_complete_(EventWrapper::Create()), |
+ crit_sect_(CriticalSectionWrapper::CreateCriticalSection()), |
+ codec_registered_(false), |
+ receive_packet_count_(0), |
+ next_insert_packet_time_ms_(0), |
+ fake_clock_(new SimulatedClock(0)) { |
+ AudioEncoderDecoderIsac::Config config; |
+ config.payload_type = kPayloadType; |
+ isac_encoder_.reset(new AudioEncoderDecoderIsac(config)); |
+ clock_ = fake_clock_.get(); |
+ } |
+ |
+ void SetUp() { |
+ AudioCodingModuleTestOldApi::SetUp(); |
+ // Set up input audio source to read from specified file, loop after 5 |
+ // seconds, and deliver blocks of 10 ms. |
+ const std::string input_file_name = |
+ webrtc::test::ResourcePath("audio_coding/speech_mono_16kHz", "pcm"); |
+ audio_loop_.Init(input_file_name, 5 * kSampleRateHz, kNumSamples10ms); |
+ RegisterCodec(); // Must be called before the threads start below. |
+ StartThreads(); |
+ } |
+ |
+ void RegisterCodec() override { |
+ static_assert(kSampleRateHz == 16000, "test designed for iSAC 16 kHz"); |
+ AudioCodingModule::Codec("ISAC", &codec_, kSampleRateHz, 1); |
+ codec_.pltype = kPayloadType; |
+ |
+ // Register iSAC codec in ACM, effectively unregistering the PCM16B codec |
+ // registered in AudioCodingModuleTestOldApi::SetUp(); |
+ // Only register the decoder for now. The encoder is registered later. |
+ ASSERT_EQ(0, acm_->RegisterReceiveCodec(codec_)); |
+ } |
+ |
+ void StartThreads() { |
+ ASSERT_TRUE(receive_thread_->Start()); |
+ receive_thread_->SetPriority(kRealtimePriority); |
+ ASSERT_TRUE(codec_registration_thread_->Start()); |
+ codec_registration_thread_->SetPriority(kRealtimePriority); |
+ } |
+ |
+ void TearDown() { |
+ AudioCodingModuleTestOldApi::TearDown(); |
+ receive_thread_->Stop(); |
+ codec_registration_thread_->Stop(); |
+ } |
+ |
+ EventTypeWrapper RunTest() { |
+ return test_complete_->Wait(10 * 60 * 1000); // 10 minutes' timeout. |
+ } |
+ |
+ static bool CbReceiveThread(void* context) { |
+ return reinterpret_cast<AcmReRegisterIsacMtTestOldApi*>(context) |
+ ->CbReceiveImpl(); |
+ } |
+ |
+ bool CbReceiveImpl() { |
+ SleepMs(1); |
+ const size_t max_encoded_bytes = isac_encoder_->MaxEncodedBytes(); |
+ rtc::scoped_ptr<uint8_t[]> encoded(new uint8_t[max_encoded_bytes]); |
+ AudioEncoder::EncodedInfo info; |
+ { |
+ CriticalSectionScoped lock(crit_sect_.get()); |
+ if (clock_->TimeInMilliseconds() < next_insert_packet_time_ms_) { |
+ return true; |
+ } |
+ next_insert_packet_time_ms_ += kPacketSizeMs; |
+ ++receive_packet_count_; |
+ |
+ // Encode new frame. |
+ uint32_t input_timestamp = rtp_header_.header.timestamp; |
+ while (info.encoded_bytes == 0) { |
+ info = isac_encoder_->Encode( |
+ input_timestamp, audio_loop_.GetNextBlock(), kNumSamples10ms, |
+ max_encoded_bytes, encoded.get()); |
+ input_timestamp += 160; // 10 ms at 16 kHz. |
+ } |
+ EXPECT_EQ(rtp_header_.header.timestamp + kPacketSizeSamples, |
+ input_timestamp); |
+ EXPECT_EQ(rtp_header_.header.timestamp, info.encoded_timestamp); |
+ EXPECT_EQ(rtp_header_.header.payloadType, info.payload_type); |
+ } |
+ // Now we're not holding the crit sect when calling ACM. |
+ |
+ // Insert into ACM. |
+ EXPECT_EQ(0, acm_->IncomingPacket(encoded.get(), info.encoded_bytes, |
+ rtp_header_)); |
+ |
+ // Pull audio. |
+ for (int i = 0; i < rtc::CheckedDivExact(kPacketSizeMs, 10); ++i) { |
+ AudioFrame audio_frame; |
+ EXPECT_EQ(0, acm_->PlayoutData10Ms(-1 /* default output frequency */, |
+ &audio_frame)); |
+ fake_clock_->AdvanceTimeMilliseconds(10); |
+ } |
+ rtp_utility_->Forward(&rtp_header_); |
+ return true; |
+ } |
+ |
+ static bool CbCodecRegistrationThread(void* context) { |
+ return reinterpret_cast<AcmReRegisterIsacMtTestOldApi*>(context) |
+ ->CbCodecRegistrationImpl(); |
+ } |
+ |
+ bool CbCodecRegistrationImpl() { |
+ SleepMs(1); |
+ if (HasFatalFailure()) { |
+ // End the test early if a fatal failure (ASSERT_*) has occurred. |
+ test_complete_->Set(); |
+ } |
+ CriticalSectionScoped lock(crit_sect_.get()); |
+ if (!codec_registered_ && |
+ receive_packet_count_ > kRegisterAfterNumPackets) { |
+ // Register the iSAC encoder. |
+ EXPECT_EQ(0, acm_->RegisterSendCodec(codec_)); |
+ codec_registered_ = true; |
+ } |
+ if (codec_registered_ && receive_packet_count_ > kNumPackets) { |
+ test_complete_->Set(); |
+ } |
+ return true; |
+ } |
+ |
+ rtc::scoped_ptr<ThreadWrapper> receive_thread_; |
+ rtc::scoped_ptr<ThreadWrapper> codec_registration_thread_; |
+ const rtc::scoped_ptr<EventWrapper> test_complete_; |
+ const rtc::scoped_ptr<CriticalSectionWrapper> crit_sect_; |
+ bool codec_registered_ GUARDED_BY(crit_sect_); |
+ int receive_packet_count_ GUARDED_BY(crit_sect_); |
+ int64_t next_insert_packet_time_ms_ GUARDED_BY(crit_sect_); |
+ rtc::scoped_ptr<AudioEncoderDecoderIsac> isac_encoder_; |
+ rtc::scoped_ptr<SimulatedClock> fake_clock_; |
+ test::AudioLoop audio_loop_; |
+}; |
+ |
+TEST_F(AcmReRegisterIsacMtTestOldApi, DISABLED_ON_IOS(DoTest)) { |
+ EXPECT_EQ(kEventSignaled, RunTest()); |
+} |
+ |
// Disabling all of these tests on iOS until file support has been added. |
// See https://code.google.com/p/webrtc/issues/detail?id=4752 for details. |
#if !defined(WEBRTC_IOS) |