| OLD | NEW | 
|---|
|  | (Empty) | 
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. |  | 
| 2 // Use of this source code is governed by a BSD-style license that can be |  | 
| 3 // found in the LICENSE file. |  | 
| 4 |  | 
| 5 #include "base/macros.h" |  | 
| 6 #include "base/synchronization/waitable_event.h" |  | 
| 7 #include "base/test/test_timeouts.h" |  | 
| 8 #include "build/build_config.h" |  | 
| 9 #include "content/public/renderer/media_stream_audio_sink.h" |  | 
| 10 #include "content/renderer/media/media_stream_audio_source.h" |  | 
| 11 #include "content/renderer/media/mock_constraint_factory.h" |  | 
| 12 #include "content/renderer/media/webrtc/webrtc_local_audio_track_adapter.h" |  | 
| 13 #include "content/renderer/media/webrtc_audio_capturer.h" |  | 
| 14 #include "content/renderer/media/webrtc_local_audio_track.h" |  | 
| 15 #include "media/base/audio_bus.h" |  | 
| 16 #include "media/base/audio_capturer_source.h" |  | 
| 17 #include "media/base/audio_parameters.h" |  | 
| 18 #include "testing/gmock/include/gmock/gmock.h" |  | 
| 19 #include "testing/gtest/include/gtest/gtest.h" |  | 
| 20 #include "third_party/WebKit/public/platform/WebMediaConstraints.h" |  | 
| 21 #include "third_party/WebKit/public/web/WebHeap.h" |  | 
| 22 #include "third_party/webrtc/api/mediastreaminterface.h" |  | 
| 23 |  | 
| 24 using ::testing::_; |  | 
| 25 using ::testing::AnyNumber; |  | 
| 26 using ::testing::AtLeast; |  | 
| 27 using ::testing::Return; |  | 
| 28 |  | 
| 29 namespace content { |  | 
| 30 |  | 
| 31 namespace { |  | 
| 32 |  | 
| 33 ACTION_P(SignalEvent, event) { |  | 
| 34   event->Signal(); |  | 
| 35 } |  | 
| 36 |  | 
| 37 // A simple thread that we use to fake the audio thread which provides data to |  | 
| 38 // the |WebRtcAudioCapturer|. |  | 
| 39 class FakeAudioThread : public base::PlatformThread::Delegate { |  | 
| 40  public: |  | 
| 41   FakeAudioThread(WebRtcAudioCapturer* capturer, |  | 
| 42                   const media::AudioParameters& params) |  | 
| 43     : capturer_(capturer), |  | 
| 44       thread_(), |  | 
| 45       closure_(false, false) { |  | 
| 46     DCHECK(capturer); |  | 
| 47     audio_bus_ = media::AudioBus::Create(params); |  | 
| 48   } |  | 
| 49 |  | 
| 50   ~FakeAudioThread() override { DCHECK(thread_.is_null()); } |  | 
| 51 |  | 
| 52   // base::PlatformThread::Delegate: |  | 
| 53   void ThreadMain() override { |  | 
| 54     while (true) { |  | 
| 55       if (closure_.IsSignaled()) |  | 
| 56         return; |  | 
| 57 |  | 
| 58       media::AudioCapturerSource::CaptureCallback* callback = |  | 
| 59           static_cast<media::AudioCapturerSource::CaptureCallback*>( |  | 
| 60               capturer_); |  | 
| 61       audio_bus_->Zero(); |  | 
| 62       callback->Capture(audio_bus_.get(), 0, 0, false); |  | 
| 63 |  | 
| 64       // Sleep 1ms to yield the resource for the main thread. |  | 
| 65       base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1)); |  | 
| 66     } |  | 
| 67   } |  | 
| 68 |  | 
| 69   void Start() { |  | 
| 70     base::PlatformThread::CreateWithPriority( |  | 
| 71         0, this, &thread_, base::ThreadPriority::REALTIME_AUDIO); |  | 
| 72     CHECK(!thread_.is_null()); |  | 
| 73   } |  | 
| 74 |  | 
| 75   void Stop() { |  | 
| 76     closure_.Signal(); |  | 
| 77     base::PlatformThread::Join(thread_); |  | 
| 78     thread_ = base::PlatformThreadHandle(); |  | 
| 79   } |  | 
| 80 |  | 
| 81  private: |  | 
| 82   std::unique_ptr<media::AudioBus> audio_bus_; |  | 
| 83   WebRtcAudioCapturer* capturer_; |  | 
| 84   base::PlatformThreadHandle thread_; |  | 
| 85   base::WaitableEvent closure_; |  | 
| 86   DISALLOW_COPY_AND_ASSIGN(FakeAudioThread); |  | 
| 87 }; |  | 
| 88 |  | 
| 89 class MockCapturerSource : public media::AudioCapturerSource { |  | 
| 90  public: |  | 
| 91   explicit MockCapturerSource(WebRtcAudioCapturer* capturer) |  | 
| 92       : capturer_(capturer) {} |  | 
| 93   MOCK_METHOD3(OnInitialize, void(const media::AudioParameters& params, |  | 
| 94                                   CaptureCallback* callback, |  | 
| 95                                   int session_id)); |  | 
| 96   MOCK_METHOD0(OnStart, void()); |  | 
| 97   MOCK_METHOD0(OnStop, void()); |  | 
| 98   void SetVolume(double volume) final {} |  | 
| 99   MOCK_METHOD1(SetAutomaticGainControl, void(bool enable)); |  | 
| 100 |  | 
| 101   void Initialize(const media::AudioParameters& params, |  | 
| 102                   CaptureCallback* callback, |  | 
| 103                   int session_id) override { |  | 
| 104     DCHECK(params.IsValid()); |  | 
| 105     params_ = params; |  | 
| 106     OnInitialize(params, callback, session_id); |  | 
| 107   } |  | 
| 108   void Start() override { |  | 
| 109     audio_thread_.reset(new FakeAudioThread(capturer_, params_)); |  | 
| 110     audio_thread_->Start(); |  | 
| 111     OnStart(); |  | 
| 112   } |  | 
| 113   void Stop() override { |  | 
| 114     audio_thread_->Stop(); |  | 
| 115     audio_thread_.reset(); |  | 
| 116     OnStop(); |  | 
| 117   } |  | 
| 118 |  | 
| 119  protected: |  | 
| 120   ~MockCapturerSource() override {} |  | 
| 121 |  | 
| 122  private: |  | 
| 123   std::unique_ptr<FakeAudioThread> audio_thread_; |  | 
| 124   WebRtcAudioCapturer* capturer_; |  | 
| 125   media::AudioParameters params_; |  | 
| 126 }; |  | 
| 127 |  | 
| 128 class MockMediaStreamAudioSink : public MediaStreamAudioSink { |  | 
| 129  public: |  | 
| 130   MockMediaStreamAudioSink() {} |  | 
| 131   ~MockMediaStreamAudioSink() {} |  | 
| 132   void OnData(const media::AudioBus& audio_bus, |  | 
| 133               base::TimeTicks estimated_capture_time) override { |  | 
| 134     EXPECT_EQ(params_.channels(), audio_bus.channels()); |  | 
| 135     EXPECT_EQ(params_.frames_per_buffer(), audio_bus.frames()); |  | 
| 136     EXPECT_FALSE(estimated_capture_time.is_null()); |  | 
| 137     CaptureData(); |  | 
| 138   } |  | 
| 139   MOCK_METHOD0(CaptureData, void()); |  | 
| 140   void OnSetFormat(const media::AudioParameters& params) { |  | 
| 141     params_ = params; |  | 
| 142     FormatIsSet(); |  | 
| 143   } |  | 
| 144   MOCK_METHOD0(FormatIsSet, void()); |  | 
| 145 |  | 
| 146   const media::AudioParameters& audio_params() const { return params_; } |  | 
| 147 |  | 
| 148  private: |  | 
| 149   media::AudioParameters params_; |  | 
| 150 }; |  | 
| 151 |  | 
| 152 }  // namespace |  | 
| 153 |  | 
| 154 class WebRtcLocalAudioTrackTest : public ::testing::Test { |  | 
| 155  protected: |  | 
| 156   void SetUp() override { |  | 
| 157     params_.Reset(media::AudioParameters::AUDIO_PCM_LOW_LATENCY, |  | 
| 158                   media::CHANNEL_LAYOUT_STEREO, 48000, 16, 480); |  | 
| 159     MockConstraintFactory constraint_factory; |  | 
| 160     blink_source_.initialize("dummy", blink::WebMediaStreamSource::TypeAudio, |  | 
| 161                              "dummy", |  | 
| 162                              false /* remote */); |  | 
| 163     MediaStreamAudioSource* audio_source = new MediaStreamAudioSource(); |  | 
| 164     blink_source_.setExtraData(audio_source); |  | 
| 165 |  | 
| 166     StreamDeviceInfo device(MEDIA_DEVICE_AUDIO_CAPTURE, |  | 
| 167                             std::string(), std::string()); |  | 
| 168     { |  | 
| 169       std::unique_ptr<WebRtcAudioCapturer> capturer = |  | 
| 170           WebRtcAudioCapturer::CreateCapturer( |  | 
| 171               -1, device, constraint_factory.CreateWebMediaConstraints(), |  | 
| 172               nullptr, audio_source); |  | 
| 173       capturer_ = capturer.get(); |  | 
| 174       audio_source->SetAudioCapturer(std::move(capturer)); |  | 
| 175     } |  | 
| 176     capturer_source_ = new MockCapturerSource(capturer_); |  | 
| 177     EXPECT_CALL(*capturer_source_.get(), OnInitialize(_, capturer_, -1)) |  | 
| 178         .WillOnce(Return()); |  | 
| 179     EXPECT_CALL(*capturer_source_.get(), SetAutomaticGainControl(true)); |  | 
| 180     EXPECT_CALL(*capturer_source_.get(), OnStart()); |  | 
| 181     capturer_->SetCapturerSource(capturer_source_, params_); |  | 
| 182   } |  | 
| 183 |  | 
| 184   void TearDown() override { |  | 
| 185     blink_source_.reset(); |  | 
| 186     blink::WebHeap::collectAllGarbageForTesting(); |  | 
| 187   } |  | 
| 188 |  | 
| 189   media::AudioParameters params_; |  | 
| 190   blink::WebMediaStreamSource blink_source_; |  | 
| 191   WebRtcAudioCapturer* capturer_;  // Owned by |blink_source_|. |  | 
| 192   scoped_refptr<MockCapturerSource> capturer_source_; |  | 
| 193 }; |  | 
| 194 |  | 
| 195 // Creates a capturer and audio track, fakes its audio thread, and |  | 
| 196 // connect/disconnect the sink to the audio track on the fly, the sink should |  | 
| 197 // get data callback when the track is connected to the capturer but not when |  | 
| 198 // the track is disconnected from the capturer. |  | 
| 199 TEST_F(WebRtcLocalAudioTrackTest, ConnectAndDisconnectOneSink) { |  | 
| 200   scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter( |  | 
| 201       WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL)); |  | 
| 202   std::unique_ptr<WebRtcLocalAudioTrack> track( |  | 
| 203       new WebRtcLocalAudioTrack(adapter.get())); |  | 
| 204   track->Start( |  | 
| 205       base::Bind(&MediaStreamAudioSource::StopAudioDeliveryTo, |  | 
| 206                  MediaStreamAudioSource::From(blink_source_)->GetWeakPtr(), |  | 
| 207                  track.get())); |  | 
| 208   capturer_->AddTrack(track.get()); |  | 
| 209   EXPECT_TRUE(track->GetAudioAdapter()->enabled()); |  | 
| 210 |  | 
| 211   std::unique_ptr<MockMediaStreamAudioSink> sink( |  | 
| 212       new MockMediaStreamAudioSink()); |  | 
| 213   base::WaitableEvent event(false, false); |  | 
| 214   EXPECT_CALL(*sink, FormatIsSet()); |  | 
| 215   EXPECT_CALL(*sink, |  | 
| 216       CaptureData()).Times(AtLeast(1)) |  | 
| 217       .WillRepeatedly(SignalEvent(&event)); |  | 
| 218   track->AddSink(sink.get()); |  | 
| 219   EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout())); |  | 
| 220   track->RemoveSink(sink.get()); |  | 
| 221 |  | 
| 222   EXPECT_CALL(*capturer_source_.get(), OnStop()).WillOnce(Return()); |  | 
| 223   capturer_->Stop(); |  | 
| 224 } |  | 
| 225 |  | 
| 226 // The same setup as ConnectAndDisconnectOneSink, but enable and disable the |  | 
| 227 // audio track on the fly. When the audio track is disabled, there is no data |  | 
| 228 // callback to the sink; when the audio track is enabled, there comes data |  | 
| 229 // callback. |  | 
| 230 // TODO(xians): Enable this test after resolving the racing issue that TSAN |  | 
| 231 // reports on MediaStreamTrack::enabled(); |  | 
| 232 TEST_F(WebRtcLocalAudioTrackTest,  DISABLED_DisableEnableAudioTrack) { |  | 
| 233   EXPECT_CALL(*capturer_source_.get(), SetAutomaticGainControl(true)); |  | 
| 234   EXPECT_CALL(*capturer_source_.get(), OnStart()); |  | 
| 235   scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter( |  | 
| 236       WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL)); |  | 
| 237   std::unique_ptr<WebRtcLocalAudioTrack> track( |  | 
| 238       new WebRtcLocalAudioTrack(adapter.get())); |  | 
| 239   track->Start( |  | 
| 240       base::Bind(&MediaStreamAudioSource::StopAudioDeliveryTo, |  | 
| 241                  MediaStreamAudioSource::From(blink_source_)->GetWeakPtr(), |  | 
| 242                  track.get())); |  | 
| 243   capturer_->AddTrack(track.get()); |  | 
| 244   EXPECT_TRUE(track->GetAudioAdapter()->enabled()); |  | 
| 245   EXPECT_TRUE(track->GetAudioAdapter()->set_enabled(false)); |  | 
| 246   std::unique_ptr<MockMediaStreamAudioSink> sink( |  | 
| 247       new MockMediaStreamAudioSink()); |  | 
| 248   const media::AudioParameters params = capturer_->GetInputFormat(); |  | 
| 249   base::WaitableEvent event(false, false); |  | 
| 250   EXPECT_CALL(*sink, FormatIsSet()).Times(1); |  | 
| 251   EXPECT_CALL(*sink, CaptureData()).Times(0); |  | 
| 252   EXPECT_EQ(sink->audio_params().frames_per_buffer(), |  | 
| 253             params.sample_rate() / 100); |  | 
| 254   track->AddSink(sink.get()); |  | 
| 255   EXPECT_FALSE(event.TimedWait(TestTimeouts::tiny_timeout())); |  | 
| 256 |  | 
| 257   event.Reset(); |  | 
| 258   EXPECT_CALL(*sink, CaptureData()).Times(AtLeast(1)) |  | 
| 259       .WillRepeatedly(SignalEvent(&event)); |  | 
| 260   EXPECT_TRUE(track->GetAudioAdapter()->set_enabled(true)); |  | 
| 261   EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout())); |  | 
| 262   track->RemoveSink(sink.get()); |  | 
| 263 |  | 
| 264   EXPECT_CALL(*capturer_source_.get(), OnStop()).WillOnce(Return()); |  | 
| 265   capturer_->Stop(); |  | 
| 266   track.reset(); |  | 
| 267 } |  | 
| 268 |  | 
| 269 // Create multiple audio tracks and enable/disable them, verify that the audio |  | 
| 270 // callbacks appear/disappear. |  | 
| 271 // Flaky due to a data race, see http://crbug.com/295418 |  | 
| 272 TEST_F(WebRtcLocalAudioTrackTest, DISABLED_MultipleAudioTracks) { |  | 
| 273   scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter_1( |  | 
| 274       WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL)); |  | 
| 275   std::unique_ptr<WebRtcLocalAudioTrack> track_1( |  | 
| 276       new WebRtcLocalAudioTrack(adapter_1.get())); |  | 
| 277   track_1->Start( |  | 
| 278       base::Bind(&MediaStreamAudioSource::StopAudioDeliveryTo, |  | 
| 279                  MediaStreamAudioSource::From(blink_source_)->GetWeakPtr(), |  | 
| 280                  track_1.get())); |  | 
| 281   capturer_->AddTrack(track_1.get()); |  | 
| 282   EXPECT_TRUE(track_1->GetAudioAdapter()->enabled()); |  | 
| 283   std::unique_ptr<MockMediaStreamAudioSink> sink_1( |  | 
| 284       new MockMediaStreamAudioSink()); |  | 
| 285   const media::AudioParameters params = capturer_->GetInputFormat(); |  | 
| 286   base::WaitableEvent event_1(false, false); |  | 
| 287   EXPECT_CALL(*sink_1, FormatIsSet()).WillOnce(Return()); |  | 
| 288   EXPECT_CALL(*sink_1, CaptureData()).Times(AtLeast(1)) |  | 
| 289       .WillRepeatedly(SignalEvent(&event_1)); |  | 
| 290   EXPECT_EQ(sink_1->audio_params().frames_per_buffer(), |  | 
| 291             params.sample_rate() / 100); |  | 
| 292   track_1->AddSink(sink_1.get()); |  | 
| 293   EXPECT_TRUE(event_1.TimedWait(TestTimeouts::tiny_timeout())); |  | 
| 294 |  | 
| 295   scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter_2( |  | 
| 296       WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL)); |  | 
| 297   std::unique_ptr<WebRtcLocalAudioTrack> track_2( |  | 
| 298       new WebRtcLocalAudioTrack(adapter_2.get())); |  | 
| 299   track_2->Start( |  | 
| 300       base::Bind(&MediaStreamAudioSource::StopAudioDeliveryTo, |  | 
| 301                  MediaStreamAudioSource::From(blink_source_)->GetWeakPtr(), |  | 
| 302                  track_2.get())); |  | 
| 303   capturer_->AddTrack(track_2.get()); |  | 
| 304   EXPECT_TRUE(track_2->GetAudioAdapter()->enabled()); |  | 
| 305 |  | 
| 306   // Verify both |sink_1| and |sink_2| get data. |  | 
| 307   event_1.Reset(); |  | 
| 308   base::WaitableEvent event_2(false, false); |  | 
| 309 |  | 
| 310   std::unique_ptr<MockMediaStreamAudioSink> sink_2( |  | 
| 311       new MockMediaStreamAudioSink()); |  | 
| 312   EXPECT_CALL(*sink_2, FormatIsSet()).WillOnce(Return()); |  | 
| 313   EXPECT_CALL(*sink_1, CaptureData()).Times(AtLeast(1)) |  | 
| 314       .WillRepeatedly(SignalEvent(&event_1)); |  | 
| 315   EXPECT_EQ(sink_1->audio_params().frames_per_buffer(), |  | 
| 316             params.sample_rate() / 100); |  | 
| 317   EXPECT_CALL(*sink_2, CaptureData()).Times(AtLeast(1)) |  | 
| 318       .WillRepeatedly(SignalEvent(&event_2)); |  | 
| 319   EXPECT_EQ(sink_2->audio_params().frames_per_buffer(), |  | 
| 320             params.sample_rate() / 100); |  | 
| 321   track_2->AddSink(sink_2.get()); |  | 
| 322   EXPECT_TRUE(event_1.TimedWait(TestTimeouts::tiny_timeout())); |  | 
| 323   EXPECT_TRUE(event_2.TimedWait(TestTimeouts::tiny_timeout())); |  | 
| 324 |  | 
| 325   track_1->RemoveSink(sink_1.get()); |  | 
| 326   track_1->Stop(); |  | 
| 327   track_1.reset(); |  | 
| 328 |  | 
| 329   EXPECT_CALL(*capturer_source_.get(), OnStop()).WillOnce(Return()); |  | 
| 330   track_2->RemoveSink(sink_2.get()); |  | 
| 331   track_2->Stop(); |  | 
| 332   track_2.reset(); |  | 
| 333 } |  | 
| 334 |  | 
| 335 |  | 
| 336 // Start one track and verify the capturer is correctly starting its source. |  | 
| 337 // And it should be fine to not to call Stop() explicitly. |  | 
| 338 TEST_F(WebRtcLocalAudioTrackTest, StartOneAudioTrack) { |  | 
| 339   scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter( |  | 
| 340       WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL)); |  | 
| 341   std::unique_ptr<WebRtcLocalAudioTrack> track( |  | 
| 342       new WebRtcLocalAudioTrack(adapter.get())); |  | 
| 343   track->Start( |  | 
| 344       base::Bind(&MediaStreamAudioSource::StopAudioDeliveryTo, |  | 
| 345                  MediaStreamAudioSource::From(blink_source_)->GetWeakPtr(), |  | 
| 346                  track.get())); |  | 
| 347   capturer_->AddTrack(track.get()); |  | 
| 348 |  | 
| 349   // When the track goes away, it will automatically stop the |  | 
| 350   // |capturer_source_|. |  | 
| 351   EXPECT_CALL(*capturer_source_.get(), OnStop()); |  | 
| 352   track.reset(); |  | 
| 353 } |  | 
| 354 |  | 
| 355 // Start two tracks and verify the capturer is correctly starting its source. |  | 
| 356 // When the last track connected to the capturer is stopped, the source is |  | 
| 357 // stopped. |  | 
| 358 TEST_F(WebRtcLocalAudioTrackTest, StartTwoAudioTracks) { |  | 
| 359   scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter1( |  | 
| 360       WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL)); |  | 
| 361   std::unique_ptr<WebRtcLocalAudioTrack> track1( |  | 
| 362       new WebRtcLocalAudioTrack(adapter1.get())); |  | 
| 363   track1->Start( |  | 
| 364       base::Bind(&MediaStreamAudioSource::StopAudioDeliveryTo, |  | 
| 365                  MediaStreamAudioSource::From(blink_source_)->GetWeakPtr(), |  | 
| 366                  track1.get())); |  | 
| 367   capturer_->AddTrack(track1.get()); |  | 
| 368 |  | 
| 369   scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter2( |  | 
| 370         WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL)); |  | 
| 371   std::unique_ptr<WebRtcLocalAudioTrack> track2( |  | 
| 372       new WebRtcLocalAudioTrack(adapter2.get())); |  | 
| 373   track2->Start( |  | 
| 374       base::Bind(&MediaStreamAudioSource::StopAudioDeliveryTo, |  | 
| 375                  MediaStreamAudioSource::From(blink_source_)->GetWeakPtr(), |  | 
| 376                  track2.get())); |  | 
| 377   capturer_->AddTrack(track2.get()); |  | 
| 378 |  | 
| 379   track1->Stop(); |  | 
| 380   // When the last track is stopped, it will automatically stop the |  | 
| 381   // |capturer_source_|. |  | 
| 382   EXPECT_CALL(*capturer_source_.get(), OnStop()); |  | 
| 383   track2->Stop(); |  | 
| 384 } |  | 
| 385 |  | 
| 386 // Start/Stop tracks and verify the capturer is correctly starting/stopping |  | 
| 387 // its source. |  | 
| 388 TEST_F(WebRtcLocalAudioTrackTest, StartAndStopAudioTracks) { |  | 
| 389   base::WaitableEvent event(false, false); |  | 
| 390   scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter_1( |  | 
| 391       WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL)); |  | 
| 392   std::unique_ptr<WebRtcLocalAudioTrack> track_1( |  | 
| 393       new WebRtcLocalAudioTrack(adapter_1.get())); |  | 
| 394   track_1->Start( |  | 
| 395       base::Bind(&MediaStreamAudioSource::StopAudioDeliveryTo, |  | 
| 396                  MediaStreamAudioSource::From(blink_source_)->GetWeakPtr(), |  | 
| 397                  track_1.get())); |  | 
| 398   capturer_->AddTrack(track_1.get()); |  | 
| 399 |  | 
| 400   // Verify the data flow by connecting the sink to |track_1|. |  | 
| 401   std::unique_ptr<MockMediaStreamAudioSink> sink( |  | 
| 402       new MockMediaStreamAudioSink()); |  | 
| 403   event.Reset(); |  | 
| 404   EXPECT_CALL(*sink, FormatIsSet()).WillOnce(SignalEvent(&event)); |  | 
| 405   EXPECT_CALL(*sink, CaptureData()) |  | 
| 406       .Times(AnyNumber()).WillRepeatedly(Return()); |  | 
| 407   track_1->AddSink(sink.get()); |  | 
| 408   EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout())); |  | 
| 409 |  | 
| 410   // Start the second audio track will not start the |capturer_source_| |  | 
| 411   // since it has been started. |  | 
| 412   EXPECT_CALL(*capturer_source_.get(), OnStart()).Times(0); |  | 
| 413   scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter_2( |  | 
| 414       WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL)); |  | 
| 415   std::unique_ptr<WebRtcLocalAudioTrack> track_2( |  | 
| 416       new WebRtcLocalAudioTrack(adapter_2.get())); |  | 
| 417   track_2->Start( |  | 
| 418       base::Bind(&MediaStreamAudioSource::StopAudioDeliveryTo, |  | 
| 419                  MediaStreamAudioSource::From(blink_source_)->GetWeakPtr(), |  | 
| 420                  track_2.get())); |  | 
| 421   capturer_->AddTrack(track_2.get()); |  | 
| 422 |  | 
| 423   // Stop the capturer will clear up the track lists in the capturer. |  | 
| 424   EXPECT_CALL(*capturer_source_.get(), OnStop()); |  | 
| 425   capturer_->Stop(); |  | 
| 426 |  | 
| 427   // Adding a new track to the capturer. |  | 
| 428   track_2->AddSink(sink.get()); |  | 
| 429   EXPECT_CALL(*sink, FormatIsSet()).Times(0); |  | 
| 430 |  | 
| 431   // Stop the capturer again will not trigger stopping the source of the |  | 
| 432   // capturer again.. |  | 
| 433   event.Reset(); |  | 
| 434   EXPECT_CALL(*capturer_source_.get(), OnStop()).Times(0); |  | 
| 435   capturer_->Stop(); |  | 
| 436 } |  | 
| 437 |  | 
| 438 // Create a new capturer with new source, connect it to a new audio track. |  | 
| 439 #if defined(THREAD_SANITIZER) |  | 
| 440 // Fails under TSan, see https://crbug.com/576634. |  | 
| 441 #define MAYBE_ConnectTracksToDifferentCapturers \ |  | 
| 442     DISABLED_ConnectTracksToDifferentCapturers |  | 
| 443 #else |  | 
| 444 #define MAYBE_ConnectTracksToDifferentCapturers \ |  | 
| 445     ConnectTracksToDifferentCapturers |  | 
| 446 #endif |  | 
| 447 TEST_F(WebRtcLocalAudioTrackTest, MAYBE_ConnectTracksToDifferentCapturers) { |  | 
| 448   // Setup the first audio track and start it. |  | 
| 449   scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter_1( |  | 
| 450       WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL)); |  | 
| 451   std::unique_ptr<WebRtcLocalAudioTrack> track_1( |  | 
| 452       new WebRtcLocalAudioTrack(adapter_1.get())); |  | 
| 453   track_1->Start( |  | 
| 454       base::Bind(&MediaStreamAudioSource::StopAudioDeliveryTo, |  | 
| 455                  MediaStreamAudioSource::From(blink_source_)->GetWeakPtr(), |  | 
| 456                  track_1.get())); |  | 
| 457   capturer_->AddTrack(track_1.get()); |  | 
| 458 |  | 
| 459   // Verify the data flow by connecting the |sink_1| to |track_1|. |  | 
| 460   std::unique_ptr<MockMediaStreamAudioSink> sink_1( |  | 
| 461       new MockMediaStreamAudioSink()); |  | 
| 462   EXPECT_CALL(*sink_1.get(), CaptureData()) |  | 
| 463       .Times(AnyNumber()).WillRepeatedly(Return()); |  | 
| 464   EXPECT_CALL(*sink_1.get(), FormatIsSet()).Times(AnyNumber()); |  | 
| 465   track_1->AddSink(sink_1.get()); |  | 
| 466 |  | 
| 467   // Create a new capturer with new source with different audio format. |  | 
| 468   MockConstraintFactory constraint_factory; |  | 
| 469   StreamDeviceInfo device(MEDIA_DEVICE_AUDIO_CAPTURE, |  | 
| 470                           std::string(), std::string()); |  | 
| 471   std::unique_ptr<WebRtcAudioCapturer> new_capturer( |  | 
| 472       WebRtcAudioCapturer::CreateCapturer( |  | 
| 473           -1, device, constraint_factory.CreateWebMediaConstraints(), NULL, |  | 
| 474           NULL)); |  | 
| 475   scoped_refptr<MockCapturerSource> new_source( |  | 
| 476       new MockCapturerSource(new_capturer.get())); |  | 
| 477   EXPECT_CALL(*new_source.get(), OnInitialize(_, new_capturer.get(), -1)); |  | 
| 478   EXPECT_CALL(*new_source.get(), SetAutomaticGainControl(true)); |  | 
| 479   EXPECT_CALL(*new_source.get(), OnStart()); |  | 
| 480 |  | 
| 481   media::AudioParameters new_param( |  | 
| 482       media::AudioParameters::AUDIO_PCM_LOW_LATENCY, |  | 
| 483       media::CHANNEL_LAYOUT_MONO, 44100, 16, 441); |  | 
| 484   new_capturer->SetCapturerSource(new_source, new_param); |  | 
| 485 |  | 
| 486   // Setup the second audio track, connect it to the new capturer and start it. |  | 
| 487   scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter_2( |  | 
| 488       WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL)); |  | 
| 489   std::unique_ptr<WebRtcLocalAudioTrack> track_2( |  | 
| 490       new WebRtcLocalAudioTrack(adapter_2.get())); |  | 
| 491   track_2->Start( |  | 
| 492       base::Bind(&MediaStreamAudioSource::StopAudioDeliveryTo, |  | 
| 493                  MediaStreamAudioSource::From(blink_source_)->GetWeakPtr(), |  | 
| 494                  track_2.get())); |  | 
| 495   new_capturer->AddTrack(track_2.get()); |  | 
| 496 |  | 
| 497   // Verify the data flow by connecting the |sink_2| to |track_2|. |  | 
| 498   std::unique_ptr<MockMediaStreamAudioSink> sink_2( |  | 
| 499       new MockMediaStreamAudioSink()); |  | 
| 500   base::WaitableEvent event(false, false); |  | 
| 501   EXPECT_CALL(*sink_2, CaptureData()) |  | 
| 502       .Times(AnyNumber()).WillRepeatedly(Return()); |  | 
| 503   EXPECT_CALL(*sink_2, FormatIsSet()).WillOnce(SignalEvent(&event)); |  | 
| 504   track_2->AddSink(sink_2.get()); |  | 
| 505   EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout())); |  | 
| 506 |  | 
| 507   // Stopping the new source will stop the second track. |  | 
| 508   event.Reset(); |  | 
| 509   EXPECT_CALL(*new_source.get(), OnStop()) |  | 
| 510       .Times(1).WillOnce(SignalEvent(&event)); |  | 
| 511   new_capturer->Stop(); |  | 
| 512   EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout())); |  | 
| 513 |  | 
| 514   // Stop the capturer of the first audio track. |  | 
| 515   EXPECT_CALL(*capturer_source_.get(), OnStop()); |  | 
| 516   capturer_->Stop(); |  | 
| 517 } |  | 
| 518 |  | 
| 519 // Make sure a audio track can deliver packets with a buffer size smaller than |  | 
| 520 // 10ms when it is not connected with a peer connection. |  | 
| 521 TEST_F(WebRtcLocalAudioTrackTest, TrackWorkWithSmallBufferSize) { |  | 
| 522   // Setup a capturer which works with a buffer size smaller than 10ms. |  | 
| 523   media::AudioParameters params(media::AudioParameters::AUDIO_PCM_LOW_LATENCY, |  | 
| 524                                 media::CHANNEL_LAYOUT_STEREO, 48000, 16, 128); |  | 
| 525 |  | 
| 526   // Create a capturer with new source which works with the format above. |  | 
| 527   MockConstraintFactory factory; |  | 
| 528   factory.DisableDefaultAudioConstraints(); |  | 
| 529   std::unique_ptr<WebRtcAudioCapturer> capturer( |  | 
| 530       WebRtcAudioCapturer::CreateCapturer( |  | 
| 531           -1, StreamDeviceInfo(MEDIA_DEVICE_AUDIO_CAPTURE, "", "", |  | 
| 532                                params.sample_rate(), params.channel_layout(), |  | 
| 533                                params.frames_per_buffer()), |  | 
| 534           factory.CreateWebMediaConstraints(), NULL, NULL)); |  | 
| 535   scoped_refptr<MockCapturerSource> source( |  | 
| 536       new MockCapturerSource(capturer.get())); |  | 
| 537   EXPECT_CALL(*source.get(), OnInitialize(_, capturer.get(), -1)); |  | 
| 538   EXPECT_CALL(*source.get(), SetAutomaticGainControl(true)); |  | 
| 539   EXPECT_CALL(*source.get(), OnStart()); |  | 
| 540   capturer->SetCapturerSource(source, params); |  | 
| 541 |  | 
| 542   // Setup a audio track, connect it to the capturer and start it. |  | 
| 543   scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter( |  | 
| 544       WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL)); |  | 
| 545   std::unique_ptr<WebRtcLocalAudioTrack> track( |  | 
| 546       new WebRtcLocalAudioTrack(adapter.get())); |  | 
| 547   track->Start( |  | 
| 548       base::Bind(&MediaStreamAudioSource::StopAudioDeliveryTo, |  | 
| 549                  MediaStreamAudioSource::From(blink_source_)->GetWeakPtr(), |  | 
| 550                  track.get())); |  | 
| 551   capturer->AddTrack(track.get()); |  | 
| 552 |  | 
| 553   // Verify the data flow by connecting the |sink| to |track|. |  | 
| 554   std::unique_ptr<MockMediaStreamAudioSink> sink( |  | 
| 555       new MockMediaStreamAudioSink()); |  | 
| 556   base::WaitableEvent event(false, false); |  | 
| 557   EXPECT_CALL(*sink, FormatIsSet()).Times(1); |  | 
| 558   // Verify the sinks are getting the packets with an expecting buffer size. |  | 
| 559 #if defined(OS_ANDROID) |  | 
| 560   const int expected_buffer_size = params.sample_rate() / 100; |  | 
| 561 #else |  | 
| 562   const int expected_buffer_size = params.frames_per_buffer(); |  | 
| 563 #endif |  | 
| 564   EXPECT_CALL(*sink, CaptureData()) |  | 
| 565       .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event)); |  | 
| 566   track->AddSink(sink.get()); |  | 
| 567   EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout())); |  | 
| 568   EXPECT_EQ(expected_buffer_size, sink->audio_params().frames_per_buffer()); |  | 
| 569 |  | 
| 570   // Stopping the new source will stop the second track. |  | 
| 571   EXPECT_CALL(*source.get(), OnStop()).Times(1); |  | 
| 572   capturer->Stop(); |  | 
| 573 |  | 
| 574   // Even though this test don't use |capturer_source_| it will be stopped |  | 
| 575   // during teardown of the test harness. |  | 
| 576   EXPECT_CALL(*capturer_source_.get(), OnStop()); |  | 
| 577 } |  | 
| 578 |  | 
| 579 }  // namespace content |  | 
| OLD | NEW | 
|---|