webrtc_local_audio_track_unittest.cc revision cedac228d2dd51db4b79ea1e72c7f249408ee061
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" 70529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "content/renderer/media/media_stream_audio_source.h" 8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/renderer/media/mock_media_constraint_factory.h" 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/renderer/media/webrtc/webrtc_local_audio_track_adapter.h" 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/renderer/media/webrtc_audio_capturer.h" 11a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/renderer/media/webrtc_audio_device_impl.h" 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/renderer/media/webrtc_local_audio_track.h" 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "media/audio/audio_parameters.h" 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "media/base/audio_bus.h" 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "media/base/audio_capturer_source.h" 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h" 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebMediaConstraints.h" 19bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "third_party/libjingle/source/talk/app/webrtc/mediastreaminterface.h" 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using ::testing::_; 227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)using ::testing::AnyNumber; 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using ::testing::AtLeast; 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using ::testing::Return; 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace content { 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace { 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ACTION_P(SignalEvent, event) { 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) event->Signal(); 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// A simple thread that we use to fake the audio thread which provides data to 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// the |WebRtcAudioCapturer|. 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class FakeAudioThread : public base::PlatformThread::Delegate { 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch FakeAudioThread(WebRtcAudioCapturer* capturer, 39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const media::AudioParameters& params) 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : capturer_(capturer), 4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) thread_(), 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) closure_(false, false) { 430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DCHECK(capturer); 44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) audio_bus_ = media::AudioBus::Create(params); 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual ~FakeAudioThread() { DCHECK(thread_.is_null()); } 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // base::PlatformThread::Delegate: 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void ThreadMain() OVERRIDE { 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) while (true) { 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (closure_.IsSignaled()) 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) media::AudioCapturerSource::CaptureCallback* callback = 56868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) static_cast<media::AudioCapturerSource::CaptureCallback*>( 570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch capturer_); 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) audio_bus_->Zero(); 593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callback->Capture(audio_bus_.get(), 0, 0, false); 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Sleep 1ms to yield the resource for the main thread. 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1)); 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void Start() { 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::PlatformThread::CreateWithPriority( 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 0, this, &thread_, base::kThreadPriority_RealtimeAudio); 6990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CHECK(!thread_.is_null()); 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void Stop() { 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) closure_.Signal(); 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::PlatformThread::Join(thread_); 7590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) thread_ = base::PlatformThreadHandle(); 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private: 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<media::AudioBus> audio_bus_; 800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch WebRtcAudioCapturer* capturer_; 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::PlatformThreadHandle thread_; 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::WaitableEvent closure_; 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(FakeAudioThread); 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class MockCapturerSource : public media::AudioCapturerSource { 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) explicit MockCapturerSource(WebRtcAudioCapturer* capturer) 89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) : capturer_(capturer) {} 90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) MOCK_METHOD3(OnInitialize, void(const media::AudioParameters& params, 91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CaptureCallback* callback, 92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int session_id)); 93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) MOCK_METHOD0(OnStart, void()); 94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) MOCK_METHOD0(OnStop, void()); 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MOCK_METHOD1(SetVolume, void(double volume)); 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MOCK_METHOD1(SetAutomaticGainControl, void(bool enable)); 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual void Initialize(const media::AudioParameters& params, 99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CaptureCallback* callback, 100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int session_id) OVERRIDE { 101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(params.IsValid()); 102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) params_ = params; 103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) OnInitialize(params, callback, session_id); 104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual void Start() OVERRIDE { 106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) audio_thread_.reset(new FakeAudioThread(capturer_, params_)); 107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) audio_thread_->Start(); 108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) OnStart(); 109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual void Stop() OVERRIDE { 111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) audio_thread_->Stop(); 112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) audio_thread_.reset(); 113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) OnStop(); 114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected: 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual ~MockCapturerSource() {} 117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) private: 119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<FakeAudioThread> audio_thread_; 120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) WebRtcAudioCapturer* capturer_; 121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) media::AudioParameters params_; 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 124a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// TODO(xians): Use MediaStreamAudioSink. 125a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class MockMediaStreamAudioSink : public PeerConnectionAudioSink { 126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 127a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) MockMediaStreamAudioSink() {} 128a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ~MockMediaStreamAudioSink() {} 129a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int OnData(const int16* audio_data, 130a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int sample_rate, 131a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int number_of_channels, 132a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int number_of_frames, 133a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const std::vector<int>& channels, 134a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int audio_delay_milliseconds, 135a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int current_volume, 136a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool need_audio_processing, 137a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool key_pressed) OVERRIDE { 138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(params_.sample_rate(), sample_rate); 139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(params_.channels(), number_of_channels); 140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(params_.frames_per_buffer(), number_of_frames); 1413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) CaptureData(channels.size(), 1423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) audio_delay_milliseconds, 1433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) current_volume, 1443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) need_audio_processing, 1453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) key_pressed); 146bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return 0; 147bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MOCK_METHOD5(CaptureData, 1493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) void(int number_of_network_channels, 1503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int audio_delay_milliseconds, 1513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int current_volume, 1523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) bool need_audio_processing, 1533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) bool key_pressed)); 154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void OnSetFormat(const media::AudioParameters& params) { 155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) params_ = params; 156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) FormatIsSet(); 157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MOCK_METHOD0(FormatIsSet, void()); 159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const media::AudioParameters& audio_params() const { return params_; } 161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) private: 163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) media::AudioParameters params_; 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace 167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class WebRtcLocalAudioTrackTest : public ::testing::Test { 169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected: 170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void SetUp() OVERRIDE { 171d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) params_.Reset(media::AudioParameters::AUDIO_PCM_LOW_LATENCY, 172d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) media::CHANNEL_LAYOUT_STEREO, 2, 0, 48000, 16, 480); 173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MockMediaConstraintFactory constraint_factory; 1740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch blink_source_.initialize("dummy", blink::WebMediaStreamSource::TypeAudio, 1750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch "dummy"); 1760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch MediaStreamAudioSource* audio_source = new MediaStreamAudioSource(); 1770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch blink_source_.setExtraData(audio_source); 1780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) StreamDeviceInfo device(MEDIA_DEVICE_AUDIO_CAPTURE, 180a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string(), std::string()); 181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) capturer_ = WebRtcAudioCapturer::CreateCapturer( 182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) -1, device, constraint_factory.CreateWebMediaConstraints(), NULL, 183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) audio_source); 1840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch audio_source->SetAudioCapturer(capturer_); 185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) capturer_source_ = new MockCapturerSource(capturer_.get()); 1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_CALL(*capturer_source_.get(), OnInitialize(_, capturer_.get(), -1)) 187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) .WillOnce(Return()); 1880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EXPECT_CALL(*capturer_source_.get(), SetAutomaticGainControl(true)); 1890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EXPECT_CALL(*capturer_source_.get(), OnStart()); 1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) capturer_->SetCapturerSourceForTesting(capturer_source_, params_); 191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 193d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) media::AudioParameters params_; 1940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch blink::WebMediaStreamSource blink_source_; 195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_refptr<MockCapturerSource> capturer_source_; 196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_refptr<WebRtcAudioCapturer> capturer_; 197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Creates a capturer and audio track, fakes its audio thread, and 200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// connect/disconnect the sink to the audio track on the fly, the sink should 201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// get data callback when the track is connected to the capturer but not when 202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// the track is disconnected from the capturer. 203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(WebRtcLocalAudioTrackTest, ConnectAndDisconnectOneSink) { 2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter( 2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL)); 2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<WebRtcLocalAudioTrack> track( 2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new WebRtcLocalAudioTrack(adapter, capturer_, NULL)); 2087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) track->Start(); 209a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_TRUE(track->GetAudioAdapter()->enabled()); 210bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 211bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // Connect a number of network channels to the audio track. 212bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch static const int kNumberOfNetworkChannels = 4; 213bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch for (int i = 0; i < kNumberOfNetworkChannels; ++i) { 2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static_cast<webrtc::AudioTrackInterface*>( 2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) adapter.get())->GetRenderer()->AddChannel(i); 216bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 217a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<MockMediaStreamAudioSink> sink(new MockMediaStreamAudioSink()); 218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::WaitableEvent event(false, false); 219a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_CALL(*sink, FormatIsSet()); 2203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_CALL(*sink, 22158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) CaptureData(kNumberOfNetworkChannels, 22258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 0, 22358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 0, 224a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) _, 22558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) false)).Times(AtLeast(1)) 2263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) .WillRepeatedly(SignalEvent(&event)); 227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) track->AddSink(sink.get()); 228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout())); 229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) track->RemoveSink(sink.get()); 2307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 231f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(*capturer_source_.get(), OnStop()).WillOnce(Return()); 232f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) capturer_->Stop(); 233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// The same setup as ConnectAndDisconnectOneSink, but enable and disable the 236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// audio track on the fly. When the audio track is disabled, there is no data 237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// callback to the sink; when the audio track is enabled, there comes data 238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// callback. 239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// TODO(xians): Enable this test after resolving the racing issue that TSAN 240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// reports on MediaStreamTrack::enabled(); 241f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(WebRtcLocalAudioTrackTest, DISABLED_DisableEnableAudioTrack) { 242f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(*capturer_source_.get(), SetAutomaticGainControl(true)); 243f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(*capturer_source_.get(), OnStart()); 2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter( 2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL)); 2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<WebRtcLocalAudioTrack> track( 2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new WebRtcLocalAudioTrack(adapter, capturer_, NULL)); 2487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) track->Start(); 2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static_cast<webrtc::AudioTrackInterface*>( 2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) adapter.get())->GetRenderer()->AddChannel(0); 251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_TRUE(track->GetAudioAdapter()->enabled()); 252a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_TRUE(track->GetAudioAdapter()->set_enabled(false)); 253a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<MockMediaStreamAudioSink> sink(new MockMediaStreamAudioSink()); 2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const media::AudioParameters params = capturer_->source_audio_parameters(); 255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::WaitableEvent event(false, false); 256a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_CALL(*sink, FormatIsSet()).Times(1); 2573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_CALL(*sink, 258a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CaptureData(1, 0, 0, _, false)).Times(0); 259a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(sink->audio_params().frames_per_buffer(), 260a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) params.sample_rate() / 100); 261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) track->AddSink(sink.get()); 262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_FALSE(event.TimedWait(TestTimeouts::tiny_timeout())); 263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) event.Reset(); 2653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_CALL(*sink, 266a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CaptureData(1, 0, 0, _, false)).Times(AtLeast(1)) 2673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) .WillRepeatedly(SignalEvent(&event)); 268a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_TRUE(track->GetAudioAdapter()->set_enabled(true)); 269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout())); 270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) track->RemoveSink(sink.get()); 2717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 272f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(*capturer_source_.get(), OnStop()).WillOnce(Return()); 273f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) capturer_->Stop(); 2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) track.reset(); 275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Create multiple audio tracks and enable/disable them, verify that the audio 278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// callbacks appear/disappear. 27968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// Flaky due to a data race, see http://crbug.com/295418 28068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)TEST_F(WebRtcLocalAudioTrackTest, DISABLED_MultipleAudioTracks) { 2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter_1( 2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL)); 2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<WebRtcLocalAudioTrack> track_1( 2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new WebRtcLocalAudioTrack(adapter_1, capturer_, NULL)); 2857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) track_1->Start(); 2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static_cast<webrtc::AudioTrackInterface*>( 2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) adapter_1.get())->GetRenderer()->AddChannel(0); 288a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_TRUE(track_1->GetAudioAdapter()->enabled()); 289a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<MockMediaStreamAudioSink> sink_1(new MockMediaStreamAudioSink()); 2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const media::AudioParameters params = capturer_->source_audio_parameters(); 291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::WaitableEvent event_1(false, false); 292a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_CALL(*sink_1, FormatIsSet()).WillOnce(Return()); 2933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_CALL(*sink_1, 294a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CaptureData(1, 0, 0, _, false)).Times(AtLeast(1)) 2953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) .WillRepeatedly(SignalEvent(&event_1)); 296a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(sink_1->audio_params().frames_per_buffer(), 297a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) params.sample_rate() / 100); 298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) track_1->AddSink(sink_1.get()); 2997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) EXPECT_TRUE(event_1.TimedWait(TestTimeouts::tiny_timeout())); 300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter_2( 3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL)); 3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<WebRtcLocalAudioTrack> track_2( 3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new WebRtcLocalAudioTrack(adapter_2, capturer_, NULL)); 3057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) track_2->Start(); 3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static_cast<webrtc::AudioTrackInterface*>( 3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) adapter_2.get())->GetRenderer()->AddChannel(1); 308a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_TRUE(track_2->GetAudioAdapter()->enabled()); 309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Verify both |sink_1| and |sink_2| get data. 311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) event_1.Reset(); 312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::WaitableEvent event_2(false, false); 3137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 314a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<MockMediaStreamAudioSink> sink_2(new MockMediaStreamAudioSink()); 315a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_CALL(*sink_2, FormatIsSet()).WillOnce(Return()); 316a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_CALL(*sink_1, CaptureData(1, 0, 0, _, false)).Times(AtLeast(1)) 3173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) .WillRepeatedly(SignalEvent(&event_1)); 318a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(sink_1->audio_params().frames_per_buffer(), 319a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) params.sample_rate() / 100); 320a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_CALL(*sink_2, CaptureData(1, 0, 0, _, false)).Times(AtLeast(1)) 3213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) .WillRepeatedly(SignalEvent(&event_2)); 322a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(sink_2->audio_params().frames_per_buffer(), 323a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) params.sample_rate() / 100); 3247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) track_2->AddSink(sink_2.get()); 325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(event_1.TimedWait(TestTimeouts::tiny_timeout())); 326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(event_2.TimedWait(TestTimeouts::tiny_timeout())); 327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) track_1->RemoveSink(sink_1.get()); 3297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) track_1->Stop(); 3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) track_1.reset(); 3317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 332f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(*capturer_source_.get(), OnStop()).WillOnce(Return()); 333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) track_2->RemoveSink(sink_2.get()); 3347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) track_2->Stop(); 3355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) track_2.reset(); 3367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 3377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 3387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 3397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Start one track and verify the capturer is correctly starting its source. 3407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// And it should be fine to not to call Stop() explicitly. 3417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(WebRtcLocalAudioTrackTest, StartOneAudioTrack) { 3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter( 3435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL)); 3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<WebRtcLocalAudioTrack> track( 3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new WebRtcLocalAudioTrack(adapter, capturer_, NULL)); 3467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) track->Start(); 3477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 3487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // When the track goes away, it will automatically stop the 3497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // |capturer_source_|. 350f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(*capturer_source_.get(), OnStop()); 3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) track.reset(); 3527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 3537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 3540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Start two tracks and verify the capturer is correctly starting its source. 3550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// When the last track connected to the capturer is stopped, the source is 3560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// stopped. 3570529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_F(WebRtcLocalAudioTrackTest, StartTwoAudioTracks) { 3580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter1( 3590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL)); 3600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch scoped_ptr<WebRtcLocalAudioTrack> track1( 3610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch new WebRtcLocalAudioTrack(adapter1, capturer_, NULL)); 3620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch track1->Start(); 3630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 3640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter2( 3650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL)); 3660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch scoped_ptr<WebRtcLocalAudioTrack> track2( 3670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch new WebRtcLocalAudioTrack(adapter2, capturer_, NULL)); 3680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch track2->Start(); 3690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 3700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch track1->Stop(); 3710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // When the last track is stopped, it will automatically stop the 3720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // |capturer_source_|. 3730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EXPECT_CALL(*capturer_source_.get(), OnStop()); 3740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch track2->Stop(); 3750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 3760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 3777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Start/Stop tracks and verify the capturer is correctly starting/stopping 3787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// its source. 3797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(WebRtcLocalAudioTrackTest, StartAndStopAudioTracks) { 380bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch base::WaitableEvent event(false, false); 3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter_1( 3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL)); 3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<WebRtcLocalAudioTrack> track_1( 3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new WebRtcLocalAudioTrack(adapter_1, capturer_, NULL)); 3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static_cast<webrtc::AudioTrackInterface*>( 3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) adapter_1.get())->GetRenderer()->AddChannel(0); 3877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) track_1->Start(); 3887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 389bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // Verify the data flow by connecting the sink to |track_1|. 390a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<MockMediaStreamAudioSink> sink(new MockMediaStreamAudioSink()); 391bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch event.Reset(); 392a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_CALL(*sink, FormatIsSet()).WillOnce(SignalEvent(&event)); 393a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_CALL(*sink, CaptureData(_, 0, 0, _, false)) 394bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch .Times(AnyNumber()).WillRepeatedly(Return()); 395bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch track_1->AddSink(sink.get()); 396f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout())); 397bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 3987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Start the second audio track will not start the |capturer_source_| 3997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // since it has been started. 400f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(*capturer_source_.get(), OnStart()).Times(0); 4015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter_2( 4025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL)); 4035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<WebRtcLocalAudioTrack> track_2( 4045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new WebRtcLocalAudioTrack(adapter_2, capturer_, NULL)); 4057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) track_2->Start(); 4065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static_cast<webrtc::AudioTrackInterface*>( 4075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) adapter_2.get())->GetRenderer()->AddChannel(1); 4087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 409f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Stop the capturer will clear up the track lists in the capturer. 410f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(*capturer_source_.get(), OnStop()); 411f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) capturer_->Stop(); 4127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 413f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Adding a new track to the capturer. 414bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch track_2->AddSink(sink.get()); 415a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_CALL(*sink, FormatIsSet()).Times(0); 416bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 417f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Stop the capturer again will not trigger stopping the source of the 418f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // capturer again.. 4197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) event.Reset(); 420f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(*capturer_source_.get(), OnStop()).Times(0); 421f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) capturer_->Stop(); 4227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 4237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 424bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// Create a new capturer with new source, connect it to a new audio track. 425bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben MurdochTEST_F(WebRtcLocalAudioTrackTest, ConnectTracksToDifferentCapturers) { 426bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // Setup the first audio track and start it. 4275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter_1( 4285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL)); 4295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<WebRtcLocalAudioTrack> track_1( 4305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new WebRtcLocalAudioTrack(adapter_1, capturer_, NULL)); 431bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch track_1->Start(); 432bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 433bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // Connect a number of network channels to the |track_1|. 434bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch static const int kNumberOfNetworkChannelsForTrack1 = 2; 435bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch for (int i = 0; i < kNumberOfNetworkChannelsForTrack1; ++i) { 4365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static_cast<webrtc::AudioTrackInterface*>( 4375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) adapter_1.get())->GetRenderer()->AddChannel(i); 438bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 439bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // Verify the data flow by connecting the |sink_1| to |track_1|. 440a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<MockMediaStreamAudioSink> sink_1(new MockMediaStreamAudioSink()); 441a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_CALL(*sink_1.get(), 442a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CaptureData(kNumberOfNetworkChannelsForTrack1, 443a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 0, 0, _, false)) 444bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch .Times(AnyNumber()).WillRepeatedly(Return()); 445a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_CALL(*sink_1.get(), FormatIsSet()).Times(AnyNumber()); 446bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch track_1->AddSink(sink_1.get()); 447bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 448bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // Create a new capturer with new source with different audio format. 449cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MockMediaConstraintFactory constraint_factory; 450a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) StreamDeviceInfo device(MEDIA_DEVICE_AUDIO_CAPTURE, 451a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string(), std::string()); 452bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch scoped_refptr<WebRtcAudioCapturer> new_capturer( 453cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) WebRtcAudioCapturer::CreateCapturer( 454cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) -1, device, constraint_factory.CreateWebMediaConstraints(), NULL, 455cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NULL)); 456f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_refptr<MockCapturerSource> new_source( 457f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) new MockCapturerSource(new_capturer.get())); 4585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_CALL(*new_source.get(), OnInitialize(_, new_capturer.get(), -1)); 4590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EXPECT_CALL(*new_source.get(), SetAutomaticGainControl(true)); 4600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EXPECT_CALL(*new_source.get(), OnStart()); 4610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 4625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) media::AudioParameters new_param( 4635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) media::AudioParameters::AUDIO_PCM_LOW_LATENCY, 4645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) media::CHANNEL_LAYOUT_MONO, 44100, 16, 441); 4655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new_capturer->SetCapturerSourceForTesting(new_source, new_param); 466bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 467bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // Setup the second audio track, connect it to the new capturer and start it. 4685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter_2( 4695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL)); 4705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<WebRtcLocalAudioTrack> track_2( 4715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new WebRtcLocalAudioTrack(adapter_2, new_capturer, NULL)); 472bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch track_2->Start(); 473bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 474bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // Connect a number of network channels to the |track_2|. 475bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch static const int kNumberOfNetworkChannelsForTrack2 = 3; 476bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch for (int i = 0; i < kNumberOfNetworkChannelsForTrack2; ++i) { 4775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static_cast<webrtc::AudioTrackInterface*>( 4785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) adapter_2.get())->GetRenderer()->AddChannel(i); 479bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 480bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // Verify the data flow by connecting the |sink_2| to |track_2|. 481a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<MockMediaStreamAudioSink> sink_2(new MockMediaStreamAudioSink()); 482f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::WaitableEvent event(false, false); 483a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_CALL(*sink_2, 484a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CaptureData(kNumberOfNetworkChannelsForTrack2, 0, 0, _, false)) 485bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch .Times(AnyNumber()).WillRepeatedly(Return()); 486a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_CALL(*sink_2, FormatIsSet()).WillOnce(SignalEvent(&event)); 487bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch track_2->AddSink(sink_2.get()); 488f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout())); 489f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 490f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Stopping the new source will stop the second track. 491f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) event.Reset(); 492f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(*new_source.get(), OnStop()) 493f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) .Times(1).WillOnce(SignalEvent(&event)); 494f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) new_capturer->Stop(); 495f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout())); 496f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 497f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Stop the capturer of the first audio track. 498f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(*capturer_source_.get(), OnStop()); 499f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) capturer_->Stop(); 500f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 501f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 502f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Make sure a audio track can deliver packets with a buffer size smaller than 503f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// 10ms when it is not connected with a peer connection. 504f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(WebRtcLocalAudioTrackTest, TrackWorkWithSmallBufferSize) { 505f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Setup a capturer which works with a buffer size smaller than 10ms. 506f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) media::AudioParameters params(media::AudioParameters::AUDIO_PCM_LOW_LATENCY, 507f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) media::CHANNEL_LAYOUT_STEREO, 48000, 16, 128); 508f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 509f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Create a capturer with new source which works with the format above. 510a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MockMediaConstraintFactory factory; 511a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) factory.DisableDefaultAudioConstraints(); 512f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_refptr<WebRtcAudioCapturer> capturer( 5135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) WebRtcAudioCapturer::CreateCapturer( 5145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) -1, 5155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) StreamDeviceInfo(MEDIA_DEVICE_AUDIO_CAPTURE, 5165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "", "", params.sample_rate(), 5175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) params.channel_layout(), 5185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) params.frames_per_buffer()), 519a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) factory.CreateWebMediaConstraints(), 5200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch NULL, NULL)); 521f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_refptr<MockCapturerSource> source( 522f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) new MockCapturerSource(capturer.get())); 5235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_CALL(*source.get(), OnInitialize(_, capturer.get(), -1)); 5240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EXPECT_CALL(*source.get(), SetAutomaticGainControl(true)); 5250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EXPECT_CALL(*source.get(), OnStart()); 5265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) capturer->SetCapturerSourceForTesting(source, params); 527f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 528f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Setup a audio track, connect it to the capturer and start it. 5295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter( 5305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL)); 5315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<WebRtcLocalAudioTrack> track( 5325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new WebRtcLocalAudioTrack(adapter, capturer, NULL)); 533f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) track->Start(); 534f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 535f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Verify the data flow by connecting the |sink| to |track|. 536a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<MockMediaStreamAudioSink> sink(new MockMediaStreamAudioSink()); 537bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch base::WaitableEvent event(false, false); 538a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_CALL(*sink, FormatIsSet()).Times(1); 539f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Verify the sinks are getting the packets with an expecting buffer size. 540f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(OS_ANDROID) 541f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const int expected_buffer_size = params.sample_rate() / 100; 542f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#else 543f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const int expected_buffer_size = params.frames_per_buffer(); 544f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif 545f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(*sink, CaptureData( 546a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 0, 0, 0, _, false)) 547f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event)); 548f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) track->AddSink(sink.get()); 549bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout())); 550a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(expected_buffer_size, sink->audio_params().frames_per_buffer()); 551bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 552f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Stopping the new source will stop the second track. 553f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(*source, OnStop()).Times(1); 554f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) capturer->Stop(); 5550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 5560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Even though this test don't use |capturer_source_| it will be stopped 5570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // during teardown of the test harness. 5580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EXPECT_CALL(*capturer_source_.get(), OnStop()); 559bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} 560bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 561c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace content 562