webrtc_audio_renderer_unittest.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
1// Copyright 2014 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 <vector> 6 7#include "content/renderer/media/audio_device_factory.h" 8#include "content/renderer/media/audio_message_filter.h" 9#include "content/renderer/media/media_stream_audio_renderer.h" 10#include "content/renderer/media/mock_media_stream_dependency_factory.h" 11#include "content/renderer/media/webrtc_audio_device_impl.h" 12#include "content/renderer/media/webrtc_audio_renderer.h" 13#include "media/audio/audio_output_device.h" 14#include "media/audio/audio_output_ipc.h" 15#include "media/base/audio_bus.h" 16#include "media/base/mock_audio_renderer_sink.h" 17#include "testing/gmock/include/gmock/gmock.h" 18#include "testing/gtest/include/gtest/gtest.h" 19#include "third_party/libjingle/source/talk/app/webrtc/mediastreaminterface.h" 20 21using testing::Return; 22 23namespace content { 24 25namespace { 26 27class MockAudioOutputIPC : public media::AudioOutputIPC { 28 public: 29 MockAudioOutputIPC() {} 30 virtual ~MockAudioOutputIPC() {} 31 32 MOCK_METHOD3(CreateStream, void(media::AudioOutputIPCDelegate* delegate, 33 const media::AudioParameters& params, 34 int session_id)); 35 MOCK_METHOD0(PlayStream, void()); 36 MOCK_METHOD0(PauseStream, void()); 37 MOCK_METHOD0(CloseStream, void()); 38 MOCK_METHOD1(SetVolume, void(double volume)); 39}; 40 41class FakeAudioOutputDevice 42 : NON_EXPORTED_BASE(public media::AudioOutputDevice) { 43 public: 44 FakeAudioOutputDevice( 45 scoped_ptr<media::AudioOutputIPC> ipc, 46 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner) 47 : AudioOutputDevice(ipc.Pass(), 48 io_task_runner) {} 49 MOCK_METHOD0(Start, void()); 50 MOCK_METHOD0(Stop, void()); 51 MOCK_METHOD0(Pause, void()); 52 MOCK_METHOD0(Play, void()); 53 MOCK_METHOD1(SetVolume, bool(double volume)); 54 55 protected: 56 virtual ~FakeAudioOutputDevice() {} 57}; 58 59class MockAudioDeviceFactory : public AudioDeviceFactory { 60 public: 61 MockAudioDeviceFactory() {} 62 virtual ~MockAudioDeviceFactory() {} 63 MOCK_METHOD1(CreateOutputDevice, media::AudioOutputDevice*(int)); 64 MOCK_METHOD1(CreateInputDevice, media::AudioInputDevice*(int)); 65}; 66 67class MockAudioRendererSource : public WebRtcAudioRendererSource { 68 public: 69 MockAudioRendererSource() {} 70 virtual ~MockAudioRendererSource() {} 71 MOCK_METHOD3(RenderData, void(media::AudioBus* audio_bus, 72 int sample_rate, 73 int audio_delay_milliseconds)); 74 MOCK_METHOD1(RemoveAudioRenderer, void(WebRtcAudioRenderer* renderer)); 75}; 76 77} // namespace 78 79class WebRtcAudioRendererTest : public testing::Test { 80 protected: 81 WebRtcAudioRendererTest() 82 : message_loop_(new base::MessageLoopForIO), 83 mock_ipc_(new MockAudioOutputIPC()), 84 mock_output_device_(new FakeAudioOutputDevice( 85 scoped_ptr<media::AudioOutputIPC>(mock_ipc_), 86 message_loop_->message_loop_proxy())), 87 factory_(new MockAudioDeviceFactory()), 88 source_(new MockAudioRendererSource()), 89 stream_(new talk_base::RefCountedObject<MockMediaStream>("label")), 90 renderer_(new WebRtcAudioRenderer(stream_, 1, 1, 1, 44100, 441)) { 91 EXPECT_CALL(*factory_.get(), CreateOutputDevice(1)) 92 .WillOnce(Return(mock_output_device_)); 93 EXPECT_CALL(*mock_output_device_, Start()); 94 EXPECT_TRUE(renderer_->Initialize(source_.get())); 95 renderer_proxy_ = renderer_->CreateSharedAudioRendererProxy(stream_); 96 } 97 98 // Used to construct |mock_output_device_|. 99 scoped_ptr<base::MessageLoopForIO> message_loop_; 100 MockAudioOutputIPC* mock_ipc_; // Owned by AudioOuputDevice. 101 102 scoped_refptr<FakeAudioOutputDevice> mock_output_device_; 103 scoped_ptr<MockAudioDeviceFactory> factory_; 104 scoped_ptr<MockAudioRendererSource> source_; 105 scoped_refptr<webrtc::MediaStreamInterface> stream_; 106 scoped_refptr<WebRtcAudioRenderer> renderer_; 107 scoped_refptr<MediaStreamAudioRenderer> renderer_proxy_; 108}; 109 110// Verify that the renderer will be stopped if the only proxy is stopped. 111TEST_F(WebRtcAudioRendererTest, StopRenderer) { 112 renderer_proxy_->Start(); 113 114 // |renderer_| has only one proxy, stopping the proxy should stop the sink of 115 // |renderer_|. 116 EXPECT_CALL(*mock_output_device_, Stop()); 117 EXPECT_CALL(*source_.get(), RemoveAudioRenderer(renderer_.get())); 118 renderer_proxy_->Stop(); 119} 120 121// Verify that the renderer will not be stopped unless the last proxy is 122// stopped. 123TEST_F(WebRtcAudioRendererTest, MultipleRenderers) { 124 renderer_proxy_->Start(); 125 126 // Create a vector of renderer proxies from the |renderer_|. 127 std::vector<scoped_refptr<MediaStreamAudioRenderer> > renderer_proxies_; 128 static const int kNumberOfRendererProxy = 5; 129 for (int i = 0; i < kNumberOfRendererProxy; ++i) { 130 scoped_refptr<MediaStreamAudioRenderer> renderer_proxy( 131 renderer_->CreateSharedAudioRendererProxy(stream_)); 132 renderer_proxy->Start(); 133 renderer_proxies_.push_back(renderer_proxy); 134 } 135 136 // Stop the |renderer_proxy_| should not stop the sink since it is used by 137 // other proxies. 138 EXPECT_CALL(*mock_output_device_, Stop()).Times(0); 139 renderer_proxy_->Stop(); 140 141 for (int i = 0; i < kNumberOfRendererProxy; ++i) { 142 if (i != kNumberOfRendererProxy -1) { 143 EXPECT_CALL(*mock_output_device_, Stop()).Times(0); 144 } else { 145 // When the last proxy is stopped, the sink will stop. 146 EXPECT_CALL(*source_.get(), RemoveAudioRenderer(renderer_.get())); 147 EXPECT_CALL(*mock_output_device_, Stop()); 148 } 149 renderer_proxies_[i]->Stop(); 150 } 151} 152 153} // namespace content 154