webrtc_local_audio_track_unittest.cc revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file. 4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/synchronization/waitable_event.h" 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/test/test_timeouts.h" 758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "content/renderer/media/rtc_media_constraints.h" 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/renderer/media/webrtc_audio_capturer.h" 9a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/renderer/media/webrtc_audio_device_impl.h" 10d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "content/renderer/media/webrtc_local_audio_source_provider.h" 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/renderer/media/webrtc_local_audio_track.h" 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "media/audio/audio_parameters.h" 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "media/base/audio_bus.h" 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "media/base/audio_capturer_source.h" 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h" 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 17bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "third_party/libjingle/source/talk/app/webrtc/mediastreaminterface.h" 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using ::testing::_; 207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)using ::testing::AnyNumber; 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using ::testing::AtLeast; 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using ::testing::Return; 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace content { 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace { 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ACTION_P(SignalEvent, event) { 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) event->Signal(); 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// A simple thread that we use to fake the audio thread which provides data to 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// the |WebRtcAudioCapturer|. 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class FakeAudioThread : public base::PlatformThread::Delegate { 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) FakeAudioThread(const scoped_refptr<WebRtcAudioCapturer>& capturer, 37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const media::AudioParameters& params) 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : capturer_(capturer), 3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) thread_(), 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) closure_(false, false) { 41868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(capturer.get()); 42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) audio_bus_ = media::AudioBus::Create(params); 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual ~FakeAudioThread() { DCHECK(thread_.is_null()); } 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // base::PlatformThread::Delegate: 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void ThreadMain() OVERRIDE { 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) while (true) { 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (closure_.IsSignaled()) 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) media::AudioCapturerSource::CaptureCallback* callback = 54868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) static_cast<media::AudioCapturerSource::CaptureCallback*>( 55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) capturer_.get()); 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) audio_bus_->Zero(); 573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callback->Capture(audio_bus_.get(), 0, 0, false); 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Sleep 1ms to yield the resource for the main thread. 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1)); 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void Start() { 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::PlatformThread::CreateWithPriority( 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 0, this, &thread_, base::kThreadPriority_RealtimeAudio); 6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CHECK(!thread_.is_null()); 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void Stop() { 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) closure_.Signal(); 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::PlatformThread::Join(thread_); 7390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) thread_ = base::PlatformThreadHandle(); 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private: 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<media::AudioBus> audio_bus_; 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_refptr<WebRtcAudioCapturer> capturer_; 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::PlatformThreadHandle thread_; 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::WaitableEvent closure_; 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(FakeAudioThread); 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class MockCapturerSource : public media::AudioCapturerSource { 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) explicit MockCapturerSource(WebRtcAudioCapturer* capturer) 87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) : capturer_(capturer) {} 88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) MOCK_METHOD3(OnInitialize, void(const media::AudioParameters& params, 89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CaptureCallback* callback, 90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int session_id)); 91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) MOCK_METHOD0(OnStart, void()); 92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) MOCK_METHOD0(OnStop, void()); 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MOCK_METHOD1(SetVolume, void(double volume)); 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MOCK_METHOD1(SetAutomaticGainControl, void(bool enable)); 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual void Initialize(const media::AudioParameters& params, 97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CaptureCallback* callback, 98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int session_id) OVERRIDE { 99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(params.IsValid()); 100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) params_ = params; 101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) OnInitialize(params, callback, session_id); 102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual void Start() OVERRIDE { 104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) audio_thread_.reset(new FakeAudioThread(capturer_, params_)); 105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) audio_thread_->Start(); 106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) OnStart(); 107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual void Stop() OVERRIDE { 109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) audio_thread_->Stop(); 110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) audio_thread_.reset(); 111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) OnStop(); 112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected: 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual ~MockCapturerSource() {} 115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) private: 117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<FakeAudioThread> audio_thread_; 118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) WebRtcAudioCapturer* capturer_; 119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) media::AudioParameters params_; 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 122a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// TODO(xians): Use MediaStreamAudioSink. 123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class MockMediaStreamAudioSink : public PeerConnectionAudioSink { 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 125a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) MockMediaStreamAudioSink() {} 126a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ~MockMediaStreamAudioSink() {} 127a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int OnData(const int16* audio_data, 128a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int sample_rate, 129a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int number_of_channels, 130a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int number_of_frames, 131a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const std::vector<int>& channels, 132a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int audio_delay_milliseconds, 133a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int current_volume, 134a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool need_audio_processing, 135a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool key_pressed) OVERRIDE { 1363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) CaptureData(channels.size(), 1373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) sample_rate, 1383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) number_of_channels, 1393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) number_of_frames, 1403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) audio_delay_milliseconds, 1413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) current_volume, 1423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) need_audio_processing, 1433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) key_pressed); 144bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return 0; 145bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 1463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) MOCK_METHOD8(CaptureData, 1473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) void(int number_of_network_channels, 1483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int sample_rate, 1493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int number_of_channels, 1503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int number_of_frames, 1513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int audio_delay_milliseconds, 1523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int current_volume, 1533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) bool need_audio_processing, 1543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) bool key_pressed)); 155a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) MOCK_METHOD1(OnSetFormat, void(const media::AudioParameters& params)); 156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace 159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class WebRtcLocalAudioTrackTest : public ::testing::Test { 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected: 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void SetUp() OVERRIDE { 163d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) params_.Reset(media::AudioParameters::AUDIO_PCM_LOW_LATENCY, 164d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) media::CHANNEL_LAYOUT_STEREO, 2, 0, 48000, 16, 480); 165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) capturer_ = WebRtcAudioCapturer::CreateCapturer(); 166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) capturer_source_ = new MockCapturerSource(capturer_.get()); 167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(*capturer_source_.get(), OnInitialize(_, capturer_.get(), 0)) 168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) .WillOnce(Return()); 169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) capturer_->SetCapturerSource(capturer_source_, 170d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) params_.channel_layout(), 171d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) params_.sample_rate()); 172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 174d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) media::AudioParameters params_; 175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_refptr<MockCapturerSource> capturer_source_; 176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_refptr<WebRtcAudioCapturer> capturer_; 177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Creates a capturer and audio track, fakes its audio thread, and 180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// connect/disconnect the sink to the audio track on the fly, the sink should 181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// get data callback when the track is connected to the capturer but not when 182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// the track is disconnected from the capturer. 183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(WebRtcLocalAudioTrackTest, ConnectAndDisconnectOneSink) { 184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(*capturer_source_.get(), SetAutomaticGainControl(true)); 185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(*capturer_source_.get(), OnStart()); 18658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) RTCMediaConstraints constraints; 187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_refptr<WebRtcLocalAudioTrack> track = 188d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL, NULL, 18958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) &constraints); 190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) static_cast<WebRtcLocalAudioSourceProvider*>( 191f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) track->audio_source_provider())->SetSinkParamsForTesting(params_); 1927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) track->Start(); 193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(track->enabled()); 194bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 195bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // Connect a number of network channels to the audio track. 196bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch static const int kNumberOfNetworkChannels = 4; 197bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch for (int i = 0; i < kNumberOfNetworkChannels; ++i) { 198bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch static_cast<webrtc::AudioTrackInterface*>(track.get())-> 199bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch GetRenderer()->AddChannel(i); 200bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 201a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<MockMediaStreamAudioSink> sink(new MockMediaStreamAudioSink()); 202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const media::AudioParameters params = capturer_->audio_parameters(); 203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::WaitableEvent event(false, false); 204a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) EXPECT_CALL(*sink, OnSetFormat(_)).WillOnce(Return()); 2053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_CALL(*sink, 20658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) CaptureData(kNumberOfNetworkChannels, 20758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) params.sample_rate(), 20858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) params.channels(), 209d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) params.sample_rate() / 100, 21058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 0, 21158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 0, 21258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) false, 21358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) false)).Times(AtLeast(1)) 2143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) .WillRepeatedly(SignalEvent(&event)); 215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) track->AddSink(sink.get()); 216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout())); 218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) track->RemoveSink(sink.get()); 2197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 220f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(*capturer_source_.get(), OnStop()).WillOnce(Return()); 221f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) capturer_->Stop(); 222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// The same setup as ConnectAndDisconnectOneSink, but enable and disable the 225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// audio track on the fly. When the audio track is disabled, there is no data 226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// callback to the sink; when the audio track is enabled, there comes data 227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// callback. 228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// TODO(xians): Enable this test after resolving the racing issue that TSAN 229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// reports on MediaStreamTrack::enabled(); 230f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(WebRtcLocalAudioTrackTest, DISABLED_DisableEnableAudioTrack) { 231f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(*capturer_source_.get(), SetAutomaticGainControl(true)); 232f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(*capturer_source_.get(), OnStart()); 23358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) RTCMediaConstraints constraints; 234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_refptr<WebRtcLocalAudioTrack> track = 235d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL, NULL, 23658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) &constraints); 237f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) static_cast<WebRtcLocalAudioSourceProvider*>( 238f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) track->audio_source_provider())->SetSinkParamsForTesting(params_); 2397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) track->Start(); 240bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch static_cast<webrtc::AudioTrackInterface*>(track.get())-> 241bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch GetRenderer()->AddChannel(0); 242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(track->enabled()); 243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(track->set_enabled(false)); 244a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<MockMediaStreamAudioSink> sink(new MockMediaStreamAudioSink()); 245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const media::AudioParameters params = capturer_->audio_parameters(); 246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::WaitableEvent event(false, false); 247a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) EXPECT_CALL(*sink, OnSetFormat(_)).Times(1); 2483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_CALL(*sink, 2493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) CaptureData(1, 2503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params.sample_rate(), 2513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params.channels(), 252d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) params.sample_rate() / 100, 2533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 0, 2543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 0, 2553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) false, 2563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) false)).Times(0); 257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) track->AddSink(sink.get()); 258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_FALSE(event.TimedWait(TestTimeouts::tiny_timeout())); 259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) event.Reset(); 2613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_CALL(*sink, 2623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) CaptureData(1, 2633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params.sample_rate(), 2643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params.channels(), 265d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) params.sample_rate() / 100, 2663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 0, 2673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 0, 2683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) false, 2693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) false)).Times(AtLeast(1)) 2703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) .WillRepeatedly(SignalEvent(&event)); 271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(track->set_enabled(true)); 272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout())); 273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) track->RemoveSink(sink.get()); 2747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 275f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(*capturer_source_.get(), OnStop()).WillOnce(Return()); 276f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) capturer_->Stop(); 277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) track = NULL; 278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Create multiple audio tracks and enable/disable them, verify that the audio 281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// callbacks appear/disappear. 28268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// Flaky due to a data race, see http://crbug.com/295418 28368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)TEST_F(WebRtcLocalAudioTrackTest, DISABLED_MultipleAudioTracks) { 284f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(*capturer_source_.get(), SetAutomaticGainControl(true)); 285f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(*capturer_source_.get(), OnStart()); 28658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) RTCMediaConstraints constraints; 287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_refptr<WebRtcLocalAudioTrack> track_1 = 288d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL, NULL, 28958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) &constraints); 290f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) static_cast<WebRtcLocalAudioSourceProvider*>( 291f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) track_1->audio_source_provider())->SetSinkParamsForTesting(params_); 2927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) track_1->Start(); 293bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch static_cast<webrtc::AudioTrackInterface*>(track_1.get())-> 294bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch GetRenderer()->AddChannel(0); 295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(track_1->enabled()); 296a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<MockMediaStreamAudioSink> sink_1(new MockMediaStreamAudioSink()); 297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const media::AudioParameters params = capturer_->audio_parameters(); 298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::WaitableEvent event_1(false, false); 299a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) EXPECT_CALL(*sink_1, OnSetFormat(_)).WillOnce(Return()); 3003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_CALL(*sink_1, 30158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) CaptureData(1, 30258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) params.sample_rate(), 30358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) params.channels(), 304d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) params.sample_rate() / 100, 30558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 0, 30658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 0, 30758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) false, 30858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) false)).Times(AtLeast(1)) 3093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) .WillRepeatedly(SignalEvent(&event_1)); 310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) track_1->AddSink(sink_1.get()); 3117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) EXPECT_TRUE(event_1.TimedWait(TestTimeouts::tiny_timeout())); 312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_refptr<WebRtcLocalAudioTrack> track_2 = 314d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL, NULL, 31558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) &constraints); 316f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) static_cast<WebRtcLocalAudioSourceProvider*>( 317f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) track_2->audio_source_provider())->SetSinkParamsForTesting(params_); 3187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) track_2->Start(); 319bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch static_cast<webrtc::AudioTrackInterface*>(track_2.get())-> 320bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch GetRenderer()->AddChannel(1); 3217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) EXPECT_TRUE(track_2->enabled()); 322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Verify both |sink_1| and |sink_2| get data. 324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) event_1.Reset(); 325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::WaitableEvent event_2(false, false); 3267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 327a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<MockMediaStreamAudioSink> sink_2(new MockMediaStreamAudioSink()); 328a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) EXPECT_CALL(*sink_2, OnSetFormat(_)).WillOnce(Return()); 3293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_CALL(*sink_1, 33058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) CaptureData(1, 33158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) params.sample_rate(), 33258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) params.channels(), 333d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) params.sample_rate() / 100, 33458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 0, 33558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 0, 33658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) false, 33758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) false)).Times(AtLeast(1)) 3383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) .WillRepeatedly(SignalEvent(&event_1)); 3393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_CALL(*sink_2, 34058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) CaptureData(1, 34158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) params.sample_rate(), 34258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) params.channels(), 343d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) params.sample_rate() / 100, 34458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 0, 34558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 0, 34658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) false, 34758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) false)).Times(AtLeast(1)) 3483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) .WillRepeatedly(SignalEvent(&event_2)); 3497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) track_2->AddSink(sink_2.get()); 350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(event_1.TimedWait(TestTimeouts::tiny_timeout())); 351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(event_2.TimedWait(TestTimeouts::tiny_timeout())); 352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) track_1->RemoveSink(sink_1.get()); 3547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) track_1->Stop(); 3557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) track_1 = NULL; 3567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 357f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(*capturer_source_.get(), OnStop()).WillOnce(Return()); 358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) track_2->RemoveSink(sink_2.get()); 3597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) track_2->Stop(); 3607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) track_2 = NULL; 361f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 362f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) capturer_->Stop(); 3637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 3647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 3657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 3667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Start one track and verify the capturer is correctly starting its source. 3677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// And it should be fine to not to call Stop() explicitly. 3687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(WebRtcLocalAudioTrackTest, StartOneAudioTrack) { 369f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(*capturer_source_.get(), SetAutomaticGainControl(true)); 370f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(*capturer_source_.get(), OnStart()); 37158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) RTCMediaConstraints constraints; 3727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_refptr<WebRtcLocalAudioTrack> track = 373d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL, NULL, 37458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) &constraints); 375f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) static_cast<WebRtcLocalAudioSourceProvider*>( 376f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) track->audio_source_provider())->SetSinkParamsForTesting(params_); 3777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) track->Start(); 3787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 3797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // When the track goes away, it will automatically stop the 3807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // |capturer_source_|. 381f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(*capturer_source_.get(), OnStop()); 382f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) capturer_->Stop(); 3837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) track = NULL; 3847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 3857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 3867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Start/Stop tracks and verify the capturer is correctly starting/stopping 3877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// its source. 3887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(WebRtcLocalAudioTrackTest, StartAndStopAudioTracks) { 3897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Starting the first audio track will start the |capturer_source_|. 390bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch base::WaitableEvent event(false, false); 391f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(*capturer_source_.get(), SetAutomaticGainControl(true)); 392f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(*capturer_source_.get(), OnStart()).WillOnce(SignalEvent(&event)); 39358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) RTCMediaConstraints constraints; 3947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_refptr<WebRtcLocalAudioTrack> track_1 = 395d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL, NULL, 39658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) &constraints); 397bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch static_cast<webrtc::AudioTrackInterface*>(track_1.get())-> 398bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch GetRenderer()->AddChannel(0); 399f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) static_cast<WebRtcLocalAudioSourceProvider*>( 400f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) track_1->audio_source_provider())->SetSinkParamsForTesting(params_); 4017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) track_1->Start(); 4027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout())); 4037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 404bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // Verify the data flow by connecting the sink to |track_1|. 405a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<MockMediaStreamAudioSink> sink(new MockMediaStreamAudioSink()); 406bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch event.Reset(); 407a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) EXPECT_CALL(*sink, OnSetFormat(_)).WillOnce(SignalEvent(&event)); 4083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_CALL(*sink, CaptureData(_, _, _, _, 0, 0, false, false)) 409bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch .Times(AnyNumber()).WillRepeatedly(Return()); 410bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch track_1->AddSink(sink.get()); 411f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout())); 412bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 4137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Start the second audio track will not start the |capturer_source_| 4147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // since it has been started. 415f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(*capturer_source_.get(), OnStart()).Times(0); 4167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_refptr<WebRtcLocalAudioTrack> track_2 = 417d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL, NULL, 41858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) &constraints); 419f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) static_cast<WebRtcLocalAudioSourceProvider*>( 420f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) track_2->audio_source_provider())->SetSinkParamsForTesting(params_); 4217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) track_2->Start(); 422bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch static_cast<webrtc::AudioTrackInterface*>(track_2.get())-> 423bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch GetRenderer()->AddChannel(1); 4247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 425f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Stop the capturer will clear up the track lists in the capturer. 426f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(*capturer_source_.get(), OnStop()); 427f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) capturer_->Stop(); 4287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 429f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Adding a new track to the capturer. 430bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch track_2->AddSink(sink.get()); 431a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) EXPECT_CALL(*sink, OnSetFormat(_)).Times(0); 432bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 433f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Stop the capturer again will not trigger stopping the source of the 434f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // capturer again.. 4357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) event.Reset(); 436f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(*capturer_source_.get(), OnStop()).Times(0); 437f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) capturer_->Stop(); 4387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 4397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 440bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// Set new source to the existing capturer. 4417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(WebRtcLocalAudioTrackTest, SetNewSourceForCapturerAfterStartTrack) { 4427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Setup the audio track and start the track. 443f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(*capturer_source_.get(), SetAutomaticGainControl(true)); 444f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(*capturer_source_.get(), OnStart()); 44558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) RTCMediaConstraints constraints; 4467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_refptr<WebRtcLocalAudioTrack> track = 447d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL, NULL, 44858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) &constraints); 449f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) static_cast<WebRtcLocalAudioSourceProvider*>( 450f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) track->audio_source_provider())->SetSinkParamsForTesting(params_); 4517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) track->Start(); 4527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 4537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Setting new source to the capturer and the track should still get packets. 454f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_refptr<MockCapturerSource> new_source( 455f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) new MockCapturerSource(capturer_.get())); 456f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(*capturer_source_.get(), OnStop()); 4570f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) EXPECT_CALL(*new_source.get(), SetAutomaticGainControl(true)); 458f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(*new_source.get(), OnInitialize(_, capturer_.get(), 0)) 4597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) .WillOnce(Return()); 460f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(*new_source.get(), OnStart()); 4617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) capturer_->SetCapturerSource(new_source, 462d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) params_.channel_layout(), 463d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) params_.sample_rate()); 4647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 4657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Stop the track. 466f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(*new_source.get(), OnStop()); 467f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) capturer_->Stop(); 468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 470bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// Create a new capturer with new source, connect it to a new audio track. 471bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben MurdochTEST_F(WebRtcLocalAudioTrackTest, ConnectTracksToDifferentCapturers) { 472bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // Setup the first audio track and start it. 473f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(*capturer_source_.get(), SetAutomaticGainControl(true)); 474f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(*capturer_source_.get(), OnStart()); 47558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) RTCMediaConstraints constraints; 476bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch scoped_refptr<WebRtcLocalAudioTrack> track_1 = 477d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL, NULL, 47858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) &constraints); 479f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) static_cast<WebRtcLocalAudioSourceProvider*>( 480f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) track_1->audio_source_provider())->SetSinkParamsForTesting(params_); 481bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch track_1->Start(); 482bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 483bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // Connect a number of network channels to the |track_1|. 484bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch static const int kNumberOfNetworkChannelsForTrack1 = 2; 485bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch for (int i = 0; i < kNumberOfNetworkChannelsForTrack1; ++i) { 486bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch static_cast<webrtc::AudioTrackInterface*>(track_1.get())-> 487bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch GetRenderer()->AddChannel(i); 488bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 489bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // Verify the data flow by connecting the |sink_1| to |track_1|. 490a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<MockMediaStreamAudioSink> sink_1(new MockMediaStreamAudioSink()); 4913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_CALL( 4923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *sink_1.get(), 4933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) CaptureData( 4943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) kNumberOfNetworkChannelsForTrack1, 48000, 2, _, 0, 0, false, false)) 495bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch .Times(AnyNumber()).WillRepeatedly(Return()); 496a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) EXPECT_CALL(*sink_1.get(), OnSetFormat(_)).Times(AnyNumber()); 497bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch track_1->AddSink(sink_1.get()); 498bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 499bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // Create a new capturer with new source with different audio format. 500bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch scoped_refptr<WebRtcAudioCapturer> new_capturer( 501bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch WebRtcAudioCapturer::CreateCapturer()); 502f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_refptr<MockCapturerSource> new_source( 503f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) new MockCapturerSource(new_capturer.get())); 504f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(*new_source.get(), OnInitialize(_, new_capturer.get(), 0)); 505bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch new_capturer->SetCapturerSource(new_source, 506bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch media::CHANNEL_LAYOUT_MONO, 507bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 44100); 508bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 509bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // Setup the second audio track, connect it to the new capturer and start it. 510f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(*new_source.get(), SetAutomaticGainControl(true)); 511f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(*new_source.get(), OnStart()); 512bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch scoped_refptr<WebRtcLocalAudioTrack> track_2 = 513d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) WebRtcLocalAudioTrack::Create(std::string(), new_capturer, NULL, NULL, 51458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) &constraints); 515f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) static_cast<WebRtcLocalAudioSourceProvider*>( 516f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) track_2->audio_source_provider())->SetSinkParamsForTesting(params_); 517bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch track_2->Start(); 518bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 519bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // Connect a number of network channels to the |track_2|. 520bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch static const int kNumberOfNetworkChannelsForTrack2 = 3; 521bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch for (int i = 0; i < kNumberOfNetworkChannelsForTrack2; ++i) { 522bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch static_cast<webrtc::AudioTrackInterface*>(track_2.get())-> 523bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch GetRenderer()->AddChannel(i); 524bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 525bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // Verify the data flow by connecting the |sink_2| to |track_2|. 526a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<MockMediaStreamAudioSink> sink_2(new MockMediaStreamAudioSink()); 527f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::WaitableEvent event(false, false); 5283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_CALL( 5293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *sink_2, 5303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) CaptureData( 5313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) kNumberOfNetworkChannelsForTrack2, 44100, 1, _, 0, 0, false, false)) 532bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch .Times(AnyNumber()).WillRepeatedly(Return()); 533a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) EXPECT_CALL(*sink_2, OnSetFormat(_)).WillOnce(SignalEvent(&event)); 534bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch track_2->AddSink(sink_2.get()); 535f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout())); 536f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 537f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Stopping the new source will stop the second track. 538f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) event.Reset(); 539f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(*new_source.get(), OnStop()) 540f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) .Times(1).WillOnce(SignalEvent(&event)); 541f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) new_capturer->Stop(); 542f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout())); 543f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 544f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Stop the capturer of the first audio track. 545f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(*capturer_source_.get(), OnStop()); 546f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) capturer_->Stop(); 547f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 548f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 549bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 550f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Make sure a audio track can deliver packets with a buffer size smaller than 551f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// 10ms when it is not connected with a peer connection. 552f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(WebRtcLocalAudioTrackTest, TrackWorkWithSmallBufferSize) { 553f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Setup a capturer which works with a buffer size smaller than 10ms. 554f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) media::AudioParameters params(media::AudioParameters::AUDIO_PCM_LOW_LATENCY, 555f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) media::CHANNEL_LAYOUT_STEREO, 48000, 16, 128); 556f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 557f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Create a capturer with new source which works with the format above. 558f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_refptr<WebRtcAudioCapturer> capturer( 559f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) WebRtcAudioCapturer::CreateCapturer()); 560f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_refptr<MockCapturerSource> source( 561f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) new MockCapturerSource(capturer.get())); 562f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) capturer->Initialize(-1, params.channel_layout(), params.sample_rate(), 563f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) params.frames_per_buffer(), 0, std::string(), 0, 0); 564f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 565f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(*source.get(), OnInitialize(_, capturer.get(), 0)); 566f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) capturer->SetCapturerSource(source, params.channel_layout(), 567f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) params.sample_rate()); 568f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 569f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Setup a audio track, connect it to the capturer and start it. 570f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(*source.get(), SetAutomaticGainControl(true)); 571f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(*source.get(), OnStart()); 572f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) RTCMediaConstraints constraints; 573f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_refptr<WebRtcLocalAudioTrack> track = 574f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) WebRtcLocalAudioTrack::Create(std::string(), capturer, NULL, NULL, 575f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) &constraints); 576f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) static_cast<WebRtcLocalAudioSourceProvider*>( 577f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) track->audio_source_provider())->SetSinkParamsForTesting(params); 578f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) track->Start(); 579f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 580f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Verify the data flow by connecting the |sink| to |track|. 581a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<MockMediaStreamAudioSink> sink(new MockMediaStreamAudioSink()); 582bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch base::WaitableEvent event(false, false); 583a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) EXPECT_CALL(*sink, OnSetFormat(_)).Times(1); 584f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Verify the sinks are getting the packets with an expecting buffer size. 585f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(OS_ANDROID) 586f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const int expected_buffer_size = params.sample_rate() / 100; 587f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#else 588f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const int expected_buffer_size = params.frames_per_buffer(); 589f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif 590f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(*sink, CaptureData( 591f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 0, params.sample_rate(), params.channels(), expected_buffer_size, 592f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 0, 0, false, false)) 593f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event)); 594f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) track->AddSink(sink.get()); 595bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout())); 596bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 597f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Stopping the new source will stop the second track. 598f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(*source, OnStop()).Times(1); 599f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) capturer->Stop(); 600bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} 601bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 602c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace content 603