From e028410838cd976c75e379b3c2e2eb0ac52b3c99 Mon Sep 17 00:00:00 2001 From: "stefan@webrtc.org" Date: Mon, 18 Nov 2013 11:45:11 +0000 Subject: Hook up audio/video sync to Call. Adds an end-to-end audio/video sync test. BUG=2530, 2608 TEST=trybots R=henrika@webrtc.org, mflodman@webrtc.org, pbos@webrtc.org Review URL: https://webrtc-codereview.appspot.com/3699004 git-svn-id: http://webrtc.googlecode.com/svn/trunk/webrtc@5128 4adac7df-926f-26a2-2b94-8c16560cd09d --- test/fake_audio_device.cc | 146 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 test/fake_audio_device.cc (limited to 'test/fake_audio_device.cc') diff --git a/test/fake_audio_device.cc b/test/fake_audio_device.cc new file mode 100644 index 00000000..a6fe165b --- /dev/null +++ b/test/fake_audio_device.cc @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "webrtc/test/fake_audio_device.h" + +#include + +#include "testing/gtest/include/gtest/gtest.h" +#include "webrtc/modules/media_file/source/media_file_utility.h" +#include "webrtc/system_wrappers/interface/clock.h" +#include "webrtc/system_wrappers/interface/critical_section_wrapper.h" +#include "webrtc/system_wrappers/interface/event_wrapper.h" +#include "webrtc/system_wrappers/interface/file_wrapper.h" +#include "webrtc/system_wrappers/interface/thread_wrapper.h" + +namespace webrtc { +namespace test { + +FakeAudioDevice::FakeAudioDevice(Clock* clock, const std::string& filename) + : audio_callback_(NULL), + capturing_(false), + captured_audio_(), + playout_buffer_(), + last_playout_ms_(-1), + clock_(clock), + tick_(EventWrapper::Create()), + lock_(CriticalSectionWrapper::CreateCriticalSection()), + file_utility_(new ModuleFileUtility(0)), + input_stream_(FileWrapper::Create()) { + memset(captured_audio_, 0, sizeof(captured_audio_)); + memset(playout_buffer_, 0, sizeof(playout_buffer_)); + // Open audio input file as read-only and looping. + EXPECT_EQ(0, input_stream_->OpenFile(filename.c_str(), true, true)) + << filename; +} + +FakeAudioDevice::~FakeAudioDevice() { + Stop(); + + if (thread_.get() != NULL) + thread_->Stop(); +} + +int32_t FakeAudioDevice::Init() { + CriticalSectionScoped cs(lock_.get()); + if (file_utility_->InitPCMReading(*input_stream_.get()) != 0) + return -1; + + if (!tick_->StartTimer(true, 10)) + return -1; + thread_.reset(ThreadWrapper::CreateThread( + FakeAudioDevice::Run, this, webrtc::kHighPriority, "FakeAudioDevice")); + if (thread_.get() == NULL) + return -1; + unsigned int thread_id; + if (!thread_->Start(thread_id)) { + thread_.reset(); + return -1; + } + return 0; +} + +int32_t FakeAudioDevice::RegisterAudioCallback(AudioTransport* callback) { + CriticalSectionScoped cs(lock_.get()); + audio_callback_ = callback; + return 0; +} + +bool FakeAudioDevice::Playing() const { + CriticalSectionScoped cs(lock_.get()); + return capturing_; +} + +int32_t FakeAudioDevice::PlayoutDelay(uint16_t* delay_ms) const { + *delay_ms = 0; + return 0; +} + +bool FakeAudioDevice::Recording() const { + CriticalSectionScoped cs(lock_.get()); + return capturing_; +} + +bool FakeAudioDevice::Run(void* obj) { + static_cast(obj)->CaptureAudio(); + return true; +} + +void FakeAudioDevice::CaptureAudio() { + { + CriticalSectionScoped cs(lock_.get()); + if (capturing_) { + int bytes_read = file_utility_->ReadPCMData( + *input_stream_.get(), captured_audio_, kBufferSizeBytes); + if (bytes_read <= 0) + return; + int num_samples = bytes_read / 2; // 2 bytes per sample. + uint32_t new_mic_level; + EXPECT_EQ(0, + audio_callback_->RecordedDataIsAvailable(captured_audio_, + num_samples, + 2, + 1, + kFrequencyHz, + 0, + 0, + 0, + false, + new_mic_level)); + uint32_t samples_needed = kFrequencyHz / 100; + int64_t now_ms = clock_->TimeInMilliseconds(); + uint32_t time_since_last_playout_ms = now_ms - last_playout_ms_; + if (last_playout_ms_ > 0 && time_since_last_playout_ms > 0) + samples_needed = std::min(kFrequencyHz / time_since_last_playout_ms, + kBufferSizeBytes / 2); + uint32_t samples_out = 0; + EXPECT_EQ(0, + audio_callback_->NeedMorePlayData(samples_needed, + 2, + 1, + kFrequencyHz, + playout_buffer_, + samples_out)); + } + } + tick_->Wait(WEBRTC_EVENT_INFINITE); +} + +void FakeAudioDevice::Start() { + CriticalSectionScoped cs(lock_.get()); + capturing_ = true; +} + +void FakeAudioDevice::Stop() { + CriticalSectionScoped cs(lock_.get()); + capturing_ = false; +} +} // namespace test +} // namespace webrtc -- cgit v1.2.3