webrtc_local_audio_track_unittest.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// Copyright 2013 The Chromium Authors. All rights reserved. 256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// Use of this source code is governed by a BSD-style license that can be 356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// found in the LICENSE file. 456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#include "base/synchronization/waitable_event.h" 656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#include "base/test/test_timeouts.h" 756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#include "content/renderer/media/mock_media_constraint_factory.h" 856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#include "content/renderer/media/webrtc/webrtc_local_audio_track_adapter.h" 956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#include "content/renderer/media/webrtc_audio_capturer.h" 107df30109963092559d3760c0661a020f9daf1030The Android Open Source Project#include "content/renderer/media/webrtc_audio_device_impl.h" 117df30109963092559d3760c0661a020f9daf1030The Android Open Source Project#include "content/renderer/media/webrtc_local_audio_source_provider.h" 127df30109963092559d3760c0661a020f9daf1030The Android Open Source Project#include "content/renderer/media/webrtc_local_audio_track.h" 137df30109963092559d3760c0661a020f9daf1030The Android Open Source Project#include "media/audio/audio_parameters.h" 147df30109963092559d3760c0661a020f9daf1030The Android Open Source Project#include "media/base/audio_bus.h" 157df30109963092559d3760c0661a020f9daf1030The Android Open Source Project#include "media/base/audio_capturer_source.h" 167df30109963092559d3760c0661a020f9daf1030The Android Open Source Project#include "testing/gmock/include/gmock/gmock.h" 177df30109963092559d3760c0661a020f9daf1030The Android Open Source Project#include "testing/gtest/include/gtest/gtest.h" 187df30109963092559d3760c0661a020f9daf1030The Android Open Source Project#include "third_party/WebKit/public/platform/WebMediaConstraints.h" 197df30109963092559d3760c0661a020f9daf1030The Android Open Source Project#include "third_party/libjingle/source/talk/app/webrtc/mediastreaminterface.h" 207df30109963092559d3760c0661a020f9daf1030The Android Open Source Project 217df30109963092559d3760c0661a020f9daf1030The Android Open Source Projectusing ::testing::_; 2256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksusing ::testing::AnyNumber; 2356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksusing ::testing::AtLeast; 2456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksusing ::testing::Return; 2556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 2656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksnamespace content { 2756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 2856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksnamespace { 2956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 3056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave SparksACTION_P(SignalEvent, event) { 3156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks event->Signal(); 3256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks} 3356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 3456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// A simple thread that we use to fake the audio thread which provides data to 3556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// the |WebRtcAudioCapturer|. 3656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksclass FakeAudioThread : public base::PlatformThread::Delegate { 3756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks public: 3856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks FakeAudioThread(const scoped_refptr<WebRtcAudioCapturer>& capturer, 3956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks const media::AudioParameters& params) 4056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks : capturer_(capturer), 4156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks thread_(), 4256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks closure_(false, false) { 4356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks DCHECK(capturer.get()); 4456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks audio_bus_ = media::AudioBus::Create(params); 4556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks } 4656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 4756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks virtual ~FakeAudioThread() { DCHECK(thread_.is_null()); } 4856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 4956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks // base::PlatformThread::Delegate: 5056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks virtual void ThreadMain() OVERRIDE { 5156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks while (true) { 5256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks if (closure_.IsSignaled()) 5356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks return; 5456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 5556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks media::AudioCapturerSource::CaptureCallback* callback = 5656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks static_cast<media::AudioCapturerSource::CaptureCallback*>( 5756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks capturer_.get()); 5856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks audio_bus_->Zero(); 5956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks callback->Capture(audio_bus_.get(), 0, 0, false); 6056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 6156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks // Sleep 1ms to yield the resource for the main thread. 6256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1)); 6356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks } 6456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks } 6556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 6656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks void Start() { 6756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks base::PlatformThread::CreateWithPriority( 6856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 0, this, &thread_, base::kThreadPriority_RealtimeAudio); 6956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks CHECK(!thread_.is_null()); 7056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks } 7156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 7256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks void Stop() { 7356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks closure_.Signal(); 7456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks base::PlatformThread::Join(thread_); 7556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks thread_ = base::PlatformThreadHandle(); 7656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks } 7756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 7856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks private: 7956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks scoped_ptr<media::AudioBus> audio_bus_; 8056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks scoped_refptr<WebRtcAudioCapturer> capturer_; 8156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks base::PlatformThreadHandle thread_; 8256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks base::WaitableEvent closure_; 8356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks DISALLOW_COPY_AND_ASSIGN(FakeAudioThread); 8456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks}; 8556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 8656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksclass MockCapturerSource : public media::AudioCapturerSource { 8756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks public: 8856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks explicit MockCapturerSource(WebRtcAudioCapturer* capturer) 8956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks : capturer_(capturer) {} 9056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks MOCK_METHOD3(OnInitialize, void(const media::AudioParameters& params, 9156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks CaptureCallback* callback, 9256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks int session_id)); 9356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks MOCK_METHOD0(OnStart, void()); 9456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks MOCK_METHOD0(OnStop, void()); 9556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks MOCK_METHOD1(SetVolume, void(double volume)); 9656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks MOCK_METHOD1(SetAutomaticGainControl, void(bool enable)); 9756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 9856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks virtual void Initialize(const media::AudioParameters& params, 9956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks CaptureCallback* callback, 10056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks int session_id) OVERRIDE { 10156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks DCHECK(params.IsValid()); 10256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks params_ = params; 10356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks OnInitialize(params, callback, session_id); 10456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks } 10556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks virtual void Start() OVERRIDE { 10656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks audio_thread_.reset(new FakeAudioThread(capturer_, params_)); 10756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks audio_thread_->Start(); 10856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks OnStart(); 10956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks } 11056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks virtual void Stop() OVERRIDE { 11156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks audio_thread_->Stop(); 11256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks audio_thread_.reset(); 11356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks OnStop(); 11456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks } 11556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks protected: 11656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks virtual ~MockCapturerSource() {} 11756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 11856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks private: 11956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks scoped_ptr<FakeAudioThread> audio_thread_; 12056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks WebRtcAudioCapturer* capturer_; 12156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks media::AudioParameters params_; 12256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks}; 12356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 12456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// TODO(xians): Use MediaStreamAudioSink. 12556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksclass MockMediaStreamAudioSink : public PeerConnectionAudioSink { 12656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks public: 12756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks MockMediaStreamAudioSink() {} 12856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks ~MockMediaStreamAudioSink() {} 12956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks int OnData(const int16* audio_data, 13056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks int sample_rate, 13156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks int number_of_channels, 13256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks int number_of_frames, 13356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks const std::vector<int>& channels, 13456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks int audio_delay_milliseconds, 13556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks int current_volume, 13656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks bool need_audio_processing, 13756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks bool key_pressed) OVERRIDE { 13856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_EQ(params_.sample_rate(), sample_rate); 13956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_EQ(params_.channels(), number_of_channels); 14056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_EQ(params_.frames_per_buffer(), number_of_frames); 14156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks CaptureData(channels.size(), 14256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks audio_delay_milliseconds, 14356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks current_volume, 14456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks need_audio_processing, 14556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks key_pressed); 14656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks return 0; 14756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks } 14856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks MOCK_METHOD5(CaptureData, 14956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks void(int number_of_network_channels, 15056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks int audio_delay_milliseconds, 15156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks int current_volume, 15256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks bool need_audio_processing, 15356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks bool key_pressed)); 15456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks void OnSetFormat(const media::AudioParameters& params) { 15556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks params_ = params; 15656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks FormatIsSet(); 15756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks } 15856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks MOCK_METHOD0(FormatIsSet, void()); 15956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 16056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks const media::AudioParameters& audio_params() const { return params_; } 16156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 16256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks private: 16356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks media::AudioParameters params_; 16456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks}; 16556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 16656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks} // namespace 16756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 16856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksclass WebRtcLocalAudioTrackTest : public ::testing::Test { 16956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks protected: 17056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks virtual void SetUp() OVERRIDE { 17156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks params_.Reset(media::AudioParameters::AUDIO_PCM_LOW_LATENCY, 17256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks media::CHANNEL_LAYOUT_STEREO, 2, 0, 48000, 16, 480); 17356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks blink::WebMediaConstraints constraints; 17456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks StreamDeviceInfo device(MEDIA_DEVICE_AUDIO_CAPTURE, 17556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks std::string(), std::string()); 17656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks capturer_ = WebRtcAudioCapturer::CreateCapturer(-1, device, 17756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks constraints, NULL); 17856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks capturer_source_ = new MockCapturerSource(capturer_.get()); 17956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_CALL(*capturer_source_.get(), OnInitialize(_, capturer_.get(), -1)) 18056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks .WillOnce(Return()); 18156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks capturer_->SetCapturerSourceForTesting(capturer_source_, params_); 18256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks } 18356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 18456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks media::AudioParameters params_; 18556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks scoped_refptr<MockCapturerSource> capturer_source_; 18656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks scoped_refptr<WebRtcAudioCapturer> capturer_; 18756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks}; 18856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 18956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// Creates a capturer and audio track, fakes its audio thread, and 19056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// connect/disconnect the sink to the audio track on the fly, the sink should 19156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// get data callback when the track is connected to the capturer but not when 19256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// the track is disconnected from the capturer. 19356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave SparksTEST_F(WebRtcLocalAudioTrackTest, ConnectAndDisconnectOneSink) { 19456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_CALL(*capturer_source_.get(), SetAutomaticGainControl(true)); 19556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_CALL(*capturer_source_.get(), OnStart()); 19656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter( 19756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL)); 19856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks scoped_ptr<WebRtcLocalAudioTrack> track( 19956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks new WebRtcLocalAudioTrack(adapter, capturer_, NULL)); 20056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks static_cast<WebRtcLocalAudioSourceProvider*>( 20156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks track->audio_source_provider())->SetSinkParamsForTesting(params_); 20256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks track->Start(); 20356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_TRUE(track->GetAudioAdapter()->enabled()); 20456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 20556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks // Connect a number of network channels to the audio track. 20656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks static const int kNumberOfNetworkChannels = 4; 20756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks for (int i = 0; i < kNumberOfNetworkChannels; ++i) { 20856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks static_cast<webrtc::AudioTrackInterface*>( 20956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks adapter.get())->GetRenderer()->AddChannel(i); 21056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks } 21156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks scoped_ptr<MockMediaStreamAudioSink> sink(new MockMediaStreamAudioSink()); 21256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks base::WaitableEvent event(false, false); 21356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_CALL(*sink, FormatIsSet()); 21456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_CALL(*sink, 21556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks CaptureData(kNumberOfNetworkChannels, 21656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 0, 21756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 0, 21856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks _, 21956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks false)).Times(AtLeast(1)) 22056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks .WillRepeatedly(SignalEvent(&event)); 22156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks track->AddSink(sink.get()); 22256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout())); 22356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks track->RemoveSink(sink.get()); 22456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 22556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_CALL(*capturer_source_.get(), OnStop()).WillOnce(Return()); 22656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks capturer_->Stop(); 22756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks} 22856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 22956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// The same setup as ConnectAndDisconnectOneSink, but enable and disable the 23056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// audio track on the fly. When the audio track is disabled, there is no data 23156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// callback to the sink; when the audio track is enabled, there comes data 23256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// callback. 23356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// TODO(xians): Enable this test after resolving the racing issue that TSAN 23456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// reports on MediaStreamTrack::enabled(); 23556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave SparksTEST_F(WebRtcLocalAudioTrackTest, DISABLED_DisableEnableAudioTrack) { 23656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_CALL(*capturer_source_.get(), SetAutomaticGainControl(true)); 23756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_CALL(*capturer_source_.get(), OnStart()); 23856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter( 23956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL)); 24056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks scoped_ptr<WebRtcLocalAudioTrack> track( 24156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks new WebRtcLocalAudioTrack(adapter, capturer_, NULL)); 24256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks static_cast<WebRtcLocalAudioSourceProvider*>( 24356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks track->audio_source_provider())->SetSinkParamsForTesting(params_); 24456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks track->Start(); 24556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks static_cast<webrtc::AudioTrackInterface*>( 24656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks adapter.get())->GetRenderer()->AddChannel(0); 24756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_TRUE(track->GetAudioAdapter()->enabled()); 24856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_TRUE(track->GetAudioAdapter()->set_enabled(false)); 24956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks scoped_ptr<MockMediaStreamAudioSink> sink(new MockMediaStreamAudioSink()); 25056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks const media::AudioParameters params = capturer_->source_audio_parameters(); 25156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks base::WaitableEvent event(false, false); 25256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_CALL(*sink, FormatIsSet()).Times(1); 25356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_CALL(*sink, 25456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks CaptureData(1, 0, 0, _, false)).Times(0); 25556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_EQ(sink->audio_params().frames_per_buffer(), 25656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks params.sample_rate() / 100); 25756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks track->AddSink(sink.get()); 25856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_FALSE(event.TimedWait(TestTimeouts::tiny_timeout())); 25956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 26056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks event.Reset(); 26156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_CALL(*sink, 26256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks CaptureData(1, 0, 0, _, false)).Times(AtLeast(1)) 26356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks .WillRepeatedly(SignalEvent(&event)); 26456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_TRUE(track->GetAudioAdapter()->set_enabled(true)); 26556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout())); 26656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks track->RemoveSink(sink.get()); 26756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 26856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_CALL(*capturer_source_.get(), OnStop()).WillOnce(Return()); 26956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks capturer_->Stop(); 27056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks track.reset(); 27156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks} 27256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 27356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// Create multiple audio tracks and enable/disable them, verify that the audio 27456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// callbacks appear/disappear. 27556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// Flaky due to a data race, see http://crbug.com/295418 27656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave SparksTEST_F(WebRtcLocalAudioTrackTest, DISABLED_MultipleAudioTracks) { 27756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_CALL(*capturer_source_.get(), SetAutomaticGainControl(true)); 27856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_CALL(*capturer_source_.get(), OnStart()); 27956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter_1( 28056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL)); 28156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks scoped_ptr<WebRtcLocalAudioTrack> track_1( 28256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks new WebRtcLocalAudioTrack(adapter_1, capturer_, NULL)); 28356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks static_cast<WebRtcLocalAudioSourceProvider*>( 28456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks track_1->audio_source_provider())->SetSinkParamsForTesting(params_); 28556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks track_1->Start(); 28656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks static_cast<webrtc::AudioTrackInterface*>( 28756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks adapter_1.get())->GetRenderer()->AddChannel(0); 28856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_TRUE(track_1->GetAudioAdapter()->enabled()); 28956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks scoped_ptr<MockMediaStreamAudioSink> sink_1(new MockMediaStreamAudioSink()); 29056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks const media::AudioParameters params = capturer_->source_audio_parameters(); 29156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks base::WaitableEvent event_1(false, false); 29256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_CALL(*sink_1, FormatIsSet()).WillOnce(Return()); 29356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_CALL(*sink_1, 29456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks CaptureData(1, 0, 0, _, false)).Times(AtLeast(1)) 29556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks .WillRepeatedly(SignalEvent(&event_1)); 29656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_EQ(sink_1->audio_params().frames_per_buffer(), 29756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks params.sample_rate() / 100); 29856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks track_1->AddSink(sink_1.get()); 29956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_TRUE(event_1.TimedWait(TestTimeouts::tiny_timeout())); 30056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 30156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter_2( 30256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL)); 30356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks scoped_ptr<WebRtcLocalAudioTrack> track_2( 30456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks new WebRtcLocalAudioTrack(adapter_2, capturer_, NULL)); 30556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks static_cast<WebRtcLocalAudioSourceProvider*>( 30656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks track_2->audio_source_provider())->SetSinkParamsForTesting(params_); 30756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks track_2->Start(); 30856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks static_cast<webrtc::AudioTrackInterface*>( 30956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks adapter_2.get())->GetRenderer()->AddChannel(1); 31056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_TRUE(track_2->GetAudioAdapter()->enabled()); 31156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 31256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks // Verify both |sink_1| and |sink_2| get data. 31356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks event_1.Reset(); 31456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks base::WaitableEvent event_2(false, false); 31556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 31656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks scoped_ptr<MockMediaStreamAudioSink> sink_2(new MockMediaStreamAudioSink()); 31756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_CALL(*sink_2, FormatIsSet()).WillOnce(Return()); 31856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_CALL(*sink_1, CaptureData(1, 0, 0, _, false)).Times(AtLeast(1)) 31956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks .WillRepeatedly(SignalEvent(&event_1)); 32056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_EQ(sink_1->audio_params().frames_per_buffer(), 32156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks params.sample_rate() / 100); 32256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_CALL(*sink_2, CaptureData(1, 0, 0, _, false)).Times(AtLeast(1)) 32356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks .WillRepeatedly(SignalEvent(&event_2)); 32456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_EQ(sink_2->audio_params().frames_per_buffer(), 32556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks params.sample_rate() / 100); 32656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks track_2->AddSink(sink_2.get()); 32756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_TRUE(event_1.TimedWait(TestTimeouts::tiny_timeout())); 32856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_TRUE(event_2.TimedWait(TestTimeouts::tiny_timeout())); 32956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 33056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks track_1->RemoveSink(sink_1.get()); 33156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks track_1->Stop(); 33256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks track_1.reset(); 33356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 33456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_CALL(*capturer_source_.get(), OnStop()).WillOnce(Return()); 33556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks track_2->RemoveSink(sink_2.get()); 33656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks track_2->Stop(); 33756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks track_2.reset(); 33856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 33956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks capturer_->Stop(); 34056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks} 34156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 34256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 34356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// Start one track and verify the capturer is correctly starting its source. 34456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// And it should be fine to not to call Stop() explicitly. 34556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave SparksTEST_F(WebRtcLocalAudioTrackTest, StartOneAudioTrack) { 34656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_CALL(*capturer_source_.get(), SetAutomaticGainControl(true)); 34756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_CALL(*capturer_source_.get(), OnStart()); 34856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter( 34956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL)); 35056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks scoped_ptr<WebRtcLocalAudioTrack> track( 35156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks new WebRtcLocalAudioTrack(adapter, capturer_, NULL)); 35256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks static_cast<WebRtcLocalAudioSourceProvider*>( 35356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks track->audio_source_provider())->SetSinkParamsForTesting(params_); 35456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks track->Start(); 35556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 35656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks // When the track goes away, it will automatically stop the 35756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks // |capturer_source_|. 35856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_CALL(*capturer_source_.get(), OnStop()); 35956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks capturer_->Stop(); 36056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks track.reset(); 36156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks} 36256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 36356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// Start/Stop tracks and verify the capturer is correctly starting/stopping 36456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// its source. 36556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave SparksTEST_F(WebRtcLocalAudioTrackTest, StartAndStopAudioTracks) { 36656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks // Starting the first audio track will start the |capturer_source_|. 36756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks base::WaitableEvent event(false, false); 36856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_CALL(*capturer_source_.get(), SetAutomaticGainControl(true)); 36956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_CALL(*capturer_source_.get(), OnStart()).WillOnce(SignalEvent(&event)); 37056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter_1( 37156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL)); 37256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks scoped_ptr<WebRtcLocalAudioTrack> track_1( 37356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks new WebRtcLocalAudioTrack(adapter_1, capturer_, NULL)); 37456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks static_cast<webrtc::AudioTrackInterface*>( 37556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks adapter_1.get())->GetRenderer()->AddChannel(0); 37656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks static_cast<WebRtcLocalAudioSourceProvider*>( 37756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks track_1->audio_source_provider())->SetSinkParamsForTesting(params_); 37856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks track_1->Start(); 37956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout())); 38056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 38156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks // Verify the data flow by connecting the sink to |track_1|. 38256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks scoped_ptr<MockMediaStreamAudioSink> sink(new MockMediaStreamAudioSink()); 38356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks event.Reset(); 38456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_CALL(*sink, FormatIsSet()).WillOnce(SignalEvent(&event)); 38556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_CALL(*sink, CaptureData(_, 0, 0, _, false)) 38656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks .Times(AnyNumber()).WillRepeatedly(Return()); 38756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks track_1->AddSink(sink.get()); 38856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout())); 38956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 39056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks // Start the second audio track will not start the |capturer_source_| 39156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks // since it has been started. 39256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_CALL(*capturer_source_.get(), OnStart()).Times(0); 39356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter_2( 39456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL)); 39556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks scoped_ptr<WebRtcLocalAudioTrack> track_2( 39656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks new WebRtcLocalAudioTrack(adapter_2, capturer_, NULL)); 39756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks static_cast<WebRtcLocalAudioSourceProvider*>( 39856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks track_2->audio_source_provider())->SetSinkParamsForTesting(params_); 39956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks track_2->Start(); 40056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks static_cast<webrtc::AudioTrackInterface*>( 40156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks adapter_2.get())->GetRenderer()->AddChannel(1); 40256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 40356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks // Stop the capturer will clear up the track lists in the capturer. 40456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_CALL(*capturer_source_.get(), OnStop()); 40556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks capturer_->Stop(); 40656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 40756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks // Adding a new track to the capturer. 40856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks track_2->AddSink(sink.get()); 40956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_CALL(*sink, FormatIsSet()).Times(0); 41056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 41156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks // Stop the capturer again will not trigger stopping the source of the 41256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks // capturer again.. 41356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks event.Reset(); 41456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_CALL(*capturer_source_.get(), OnStop()).Times(0); 41556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks capturer_->Stop(); 41656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks} 41756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 41856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// Create a new capturer with new source, connect it to a new audio track. 41956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave SparksTEST_F(WebRtcLocalAudioTrackTest, ConnectTracksToDifferentCapturers) { 42056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks // Setup the first audio track and start it. 42156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_CALL(*capturer_source_.get(), SetAutomaticGainControl(true)); 42256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_CALL(*capturer_source_.get(), OnStart()); 42356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter_1( 42456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL)); 42556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks scoped_ptr<WebRtcLocalAudioTrack> track_1( 42656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks new WebRtcLocalAudioTrack(adapter_1, capturer_, NULL)); 42756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks static_cast<WebRtcLocalAudioSourceProvider*>( 42856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks track_1->audio_source_provider())->SetSinkParamsForTesting(params_); 42956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks track_1->Start(); 43056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 43156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks // Connect a number of network channels to the |track_1|. 43256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks static const int kNumberOfNetworkChannelsForTrack1 = 2; 43356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks for (int i = 0; i < kNumberOfNetworkChannelsForTrack1; ++i) { 43456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks static_cast<webrtc::AudioTrackInterface*>( 43556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks adapter_1.get())->GetRenderer()->AddChannel(i); 43656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks } 43756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks // Verify the data flow by connecting the |sink_1| to |track_1|. 43856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks scoped_ptr<MockMediaStreamAudioSink> sink_1(new MockMediaStreamAudioSink()); 43956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_CALL(*sink_1.get(), 44056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks CaptureData(kNumberOfNetworkChannelsForTrack1, 44156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 0, 0, _, false)) 44256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks .Times(AnyNumber()).WillRepeatedly(Return()); 44356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_CALL(*sink_1.get(), FormatIsSet()).Times(AnyNumber()); 44456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks track_1->AddSink(sink_1.get()); 44556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 44656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks // Create a new capturer with new source with different audio format. 44756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks blink::WebMediaConstraints constraints; 44856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks StreamDeviceInfo device(MEDIA_DEVICE_AUDIO_CAPTURE, 44956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks std::string(), std::string()); 45056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks scoped_refptr<WebRtcAudioCapturer> new_capturer( 45156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks WebRtcAudioCapturer::CreateCapturer(-1, device, constraints, NULL)); 45256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks scoped_refptr<MockCapturerSource> new_source( 45356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks new MockCapturerSource(new_capturer.get())); 45456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_CALL(*new_source.get(), OnInitialize(_, new_capturer.get(), -1)); 45556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks media::AudioParameters new_param( 45656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks media::AudioParameters::AUDIO_PCM_LOW_LATENCY, 45756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks media::CHANNEL_LAYOUT_MONO, 44100, 16, 441); 45856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks new_capturer->SetCapturerSourceForTesting(new_source, new_param); 45956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 46056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks // Setup the second audio track, connect it to the new capturer and start it. 46156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_CALL(*new_source.get(), SetAutomaticGainControl(true)); 46256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_CALL(*new_source.get(), OnStart()); 46356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter_2( 46456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL)); 46556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks scoped_ptr<WebRtcLocalAudioTrack> track_2( 46656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks new WebRtcLocalAudioTrack(adapter_2, new_capturer, NULL)); 46756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks static_cast<WebRtcLocalAudioSourceProvider*>( 46856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks track_2->audio_source_provider())->SetSinkParamsForTesting(params_); 46956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks track_2->Start(); 47056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 47156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks // Connect a number of network channels to the |track_2|. 47256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks static const int kNumberOfNetworkChannelsForTrack2 = 3; 47356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks for (int i = 0; i < kNumberOfNetworkChannelsForTrack2; ++i) { 47456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks static_cast<webrtc::AudioTrackInterface*>( 47556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks adapter_2.get())->GetRenderer()->AddChannel(i); 47656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks } 47756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks // Verify the data flow by connecting the |sink_2| to |track_2|. 47856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks scoped_ptr<MockMediaStreamAudioSink> sink_2(new MockMediaStreamAudioSink()); 47956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks base::WaitableEvent event(false, false); 48056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_CALL(*sink_2, 48156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks CaptureData(kNumberOfNetworkChannelsForTrack2, 0, 0, _, false)) 48256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks .Times(AnyNumber()).WillRepeatedly(Return()); 48356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_CALL(*sink_2, FormatIsSet()).WillOnce(SignalEvent(&event)); 48456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks track_2->AddSink(sink_2.get()); 48556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout())); 48656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 48756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks // Stopping the new source will stop the second track. 48856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks event.Reset(); 48956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_CALL(*new_source.get(), OnStop()) 49056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks .Times(1).WillOnce(SignalEvent(&event)); 49156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks new_capturer->Stop(); 49256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout())); 49356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 49456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks // Stop the capturer of the first audio track. 49556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_CALL(*capturer_source_.get(), OnStop()); 49656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks capturer_->Stop(); 49756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks} 49856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 49956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 50056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// Make sure a audio track can deliver packets with a buffer size smaller than 50156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// 10ms when it is not connected with a peer connection. 50256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave SparksTEST_F(WebRtcLocalAudioTrackTest, TrackWorkWithSmallBufferSize) { 50356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks // Setup a capturer which works with a buffer size smaller than 10ms. 50456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks media::AudioParameters params(media::AudioParameters::AUDIO_PCM_LOW_LATENCY, 50556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks media::CHANNEL_LAYOUT_STEREO, 48000, 16, 128); 50656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 50756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks // Create a capturer with new source which works with the format above. 50856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks MockMediaConstraintFactory factory; 50956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks factory.DisableDefaultAudioConstraints(); 51056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks scoped_refptr<WebRtcAudioCapturer> capturer( 51156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks WebRtcAudioCapturer::CreateCapturer( 51256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks -1, 51356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks StreamDeviceInfo(MEDIA_DEVICE_AUDIO_CAPTURE, 51456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks "", "", params.sample_rate(), 51556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks params.channel_layout(), 51656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks params.frames_per_buffer()), 51756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks factory.CreateWebMediaConstraints(), 51856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks NULL)); 51956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks scoped_refptr<MockCapturerSource> source( 52056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks new MockCapturerSource(capturer.get())); 52156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_CALL(*source.get(), OnInitialize(_, capturer.get(), -1)); 52256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks capturer->SetCapturerSourceForTesting(source, params); 52356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 52456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks // Setup a audio track, connect it to the capturer and start it. 52556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_CALL(*source.get(), SetAutomaticGainControl(true)); 52656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_CALL(*source.get(), OnStart()); 52756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter( 52856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL)); 52956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks scoped_ptr<WebRtcLocalAudioTrack> track( 53056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks new WebRtcLocalAudioTrack(adapter, capturer, NULL)); 53156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks static_cast<WebRtcLocalAudioSourceProvider*>( 53256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks track->audio_source_provider())->SetSinkParamsForTesting(params); 53356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks track->Start(); 53456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 53556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks // Verify the data flow by connecting the |sink| to |track|. 53656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks scoped_ptr<MockMediaStreamAudioSink> sink(new MockMediaStreamAudioSink()); 53756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks base::WaitableEvent event(false, false); 53856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_CALL(*sink, FormatIsSet()).Times(1); 53956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks // Verify the sinks are getting the packets with an expecting buffer size. 54056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#if defined(OS_ANDROID) 54156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks const int expected_buffer_size = params.sample_rate() / 100; 54256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#else 54356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks const int expected_buffer_size = params.frames_per_buffer(); 54456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif 54556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_CALL(*sink, CaptureData( 54656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 0, 0, 0, _, false)) 54756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event)); 54856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks track->AddSink(sink.get()); 54956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout())); 55056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_EQ(expected_buffer_size, sink->audio_params().frames_per_buffer()); 55156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 55256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks // Stopping the new source will stop the second track. 55356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EXPECT_CALL(*source, OnStop()).Times(1); 55456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks capturer->Stop(); 55556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks} 55656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 55756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks} // namespace content 55856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks