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

Unified Diff: webrtc/modules/audio_coding/main/acm2/audio_coding_module_unittest_oldapi.cc

Issue 1176303004: Fix a data race in AudioEncoderMutableImpl and derived classes (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Return config_ by value instead of reference Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « webrtc/modules/audio_coding/codecs/opus/interface/audio_encoder_opus.h ('k') | webrtc/modules/modules.gyp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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)
« no previous file with comments | « webrtc/modules/audio_coding/codecs/opus/interface/audio_encoder_opus.h ('k') | webrtc/modules/modules.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698