15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/renderer_host/media/audio_renderer_host.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/bind_helpers.h" 97dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/memory/shared_memory.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h" 11a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "base/process/process.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/browser_main_loop.h" 131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/browser/media/audio_stream_monitor.h" 14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/browser/media/capture/audio_mirroring_manager.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/media/media_internals.h" 16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/browser/renderer_host/media/audio_input_device_manager.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/renderer_host/media/audio_sync_reader.h" 18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/browser/renderer_host/media/media_stream_manager.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/media/audio_messages.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/content_browser_client.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/media_observer.h" 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/common/content_switches.h" 23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "media/audio/audio_manager_base.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/audio_bus.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/limits.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using media::AudioBus; 281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)using media::AudioManager; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class AudioRendererHost::AudioEntry 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : public media::AudioOutputController::EventHandler { 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AudioEntry(AudioRendererHost* host, 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int stream_id, 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int render_view_id, 38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int render_frame_id, 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const media::AudioParameters& params, 4058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const std::string& output_device_id, 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<base::SharedMemory> shared_memory, 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<media::AudioOutputController::SyncReader> reader); 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual ~AudioEntry(); 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int stream_id() const { 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return stream_id_; 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int render_view_id() const { 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return render_view_id_; 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int render_frame_id() const { return render_frame_id_; } 54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) media::AudioOutputController* controller() const { return controller_.get(); } 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::SharedMemory* shared_memory() { 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return shared_memory_.get(); 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) media::AudioOutputController::SyncReader* reader() const { 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return reader_.get(); 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) bool playing() const { return playing_; } 6646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) void set_playing(bool playing) { playing_ = playing; } 6746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private: 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // media::AudioOutputController::EventHandler implementation. 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void OnCreated() OVERRIDE; 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void OnPlaying() OVERRIDE; 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void OnPaused() OVERRIDE; 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void OnError() OVERRIDE; 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void OnDeviceChange(int new_buffer_size, int new_sample_rate) 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) OVERRIDE; 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AudioRendererHost* const host_; 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const int stream_id_; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // The routing ID of the source render view/frame. 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const int render_view_id_; 82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const int render_frame_id_; 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Shared memory for transmission of the audio data. Used by |reader_|. 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const scoped_ptr<base::SharedMemory> shared_memory_; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // The synchronous reader to be used by |controller_|. 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const scoped_ptr<media::AudioOutputController::SyncReader> reader_; 89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // The AudioOutputController that manages the audio stream. 91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const scoped_refptr<media::AudioOutputController> controller_; 9246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 9346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) bool playing_; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)AudioRendererHost::AudioEntry::AudioEntry( 97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) AudioRendererHost* host, 98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int stream_id, 99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int render_view_id, 100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int render_frame_id, 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const media::AudioParameters& params, 10258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const std::string& output_device_id, 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<base::SharedMemory> shared_memory, 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<media::AudioOutputController::SyncReader> reader) 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : host_(host), 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) stream_id_(stream_id), 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) render_view_id_(render_view_id), 108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) render_frame_id_(render_frame_id), 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) shared_memory_(shared_memory.Pass()), 110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) reader_(reader.Pass()), 111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) controller_(media::AudioOutputController::Create(host->audio_manager_, 112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) this, 113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) params, 114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) output_device_id, 11546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) reader_.get())), 11646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) playing_(false) { 117868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(controller_.get()); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AudioRendererHost::AudioEntry::~AudioEntry() {} 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/////////////////////////////////////////////////////////////////////////////// 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// AudioRendererHost implementations. 1241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AudioRendererHost::AudioRendererHost( 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int render_process_id, 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) media::AudioManager* audio_manager, 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AudioMirroringManager* mirroring_manager, 129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) MediaInternals* media_internals, 130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) MediaStreamManager* media_stream_manager) 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : BrowserMessageFilter(AudioMsgStart), 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) render_process_id_(render_process_id), 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) audio_manager_(audio_manager), 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mirroring_manager_(mirroring_manager), 135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) audio_log_(media_internals->CreateAudioLog( 136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) media::AudioLogFactory::AUDIO_OUTPUT_CONTROLLER)), 13746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) media_stream_manager_(media_stream_manager), 13846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) num_playing_streams_(0) { 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(audio_manager_); 140868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(media_stream_manager_); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AudioRendererHost::~AudioRendererHost() { 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(audio_entries_.empty()); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void AudioRendererHost::GetOutputControllers( 1481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) int render_view_id, 1491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const RenderViewHost::GetAudioOutputControllersCallback& callback) const { 1501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) BrowserThread::PostTaskAndReplyWithResult( 1511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) BrowserThread::IO, 1521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) FROM_HERE, 1531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) base::Bind(&AudioRendererHost::DoGetOutputControllers, this, 1541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) render_view_id), 1551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) callback); 1561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 1571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioRendererHost::OnChannelClosing() { 159f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Since the IPC sender is gone, close all requested audio streams. 160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) while (!audio_entries_.empty()) { 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Note: OnCloseStream() removes the entries from audio_entries_. 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) OnCloseStream(audio_entries_.begin()->first); 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioRendererHost::OnDestruct() const { 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::DeleteOnIOThread::Destruct(this); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void AudioRendererHost::AudioEntry::OnCreated() { 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::IO, 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 174ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Bind(&AudioRendererHost::DoCompleteCreation, host_, stream_id_)); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void AudioRendererHost::AudioEntry::OnPlaying() { 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::IO, 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 181a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&AudioRendererHost::DoNotifyStreamStateChanged, 182a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) host_, 183a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) stream_id_, 184a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) true)); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void AudioRendererHost::AudioEntry::OnPaused() { 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::IO, 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 191a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&AudioRendererHost::DoNotifyStreamStateChanged, 192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) host_, 193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) stream_id_, 194a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) false)); 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void AudioRendererHost::AudioEntry::OnError() { 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::PostTask( 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::IO, 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&AudioRendererHost::ReportErrorAndClose, host_, stream_id_)); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void AudioRendererHost::AudioEntry::OnDeviceChange(int new_buffer_size, 205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int new_sample_rate) { 206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) BrowserThread::PostTask( 207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) BrowserThread::IO, 208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(base::IgnoreResult(&AudioRendererHost::Send), host_, 210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new AudioMsg_NotifyDeviceChanged( 211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) stream_id_, new_buffer_size, new_sample_rate))); 212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 214ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid AudioRendererHost::DoCompleteCreation(int stream_id) { 215effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!PeerHandle()) { 2184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DLOG(WARNING) << "Renderer process handle is invalid."; 219ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ReportErrorAndClose(stream_id); 220ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return; 221ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 222ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 223ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch AudioEntry* const entry = LookupById(stream_id); 224ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (!entry) { 225ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ReportErrorAndClose(stream_id); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Once the audio stream is created then complete the creation process by 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // mapping shared memory and sharing with the renderer process. 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::SharedMemoryHandle foreign_memory_handle; 2327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!entry->shared_memory()->ShareToProcess(PeerHandle(), 233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &foreign_memory_handle)) { 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we failed to map and share the shared memory then close the audio 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // stream and send an error message. 236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ReportErrorAndClose(entry->stream_id()); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AudioSyncReader* reader = static_cast<AudioSyncReader*>(entry->reader()); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::SyncSocket::TransitDescriptor socket_descriptor; 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we failed to prepare the sync socket for the renderer then we fail 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the construction of audio stream. 2461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!reader->PrepareForeignSocket(PeerHandle(), &socket_descriptor)) { 247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ReportErrorAndClose(entry->stream_id()); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(new AudioMsg_NotifyStreamCreated( 2521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci entry->stream_id(), foreign_memory_handle, socket_descriptor, 2531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) entry->shared_memory()->requested_size())); 2541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 2551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 256a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void AudioRendererHost::DoNotifyStreamStateChanged(int stream_id, 257a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool is_playing) { 258effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 259a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 260a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) AudioEntry* const entry = LookupById(stream_id); 261a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!entry) 262a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 263a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 264a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Send(new AudioMsg_NotifyStreamStateChanged( 265a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) stream_id, 266a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) is_playing ? media::AudioOutputIPCDelegate::kPlaying 267a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : media::AudioOutputIPCDelegate::kPaused)); 268a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 2691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (is_playing) { 2701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci AudioStreamMonitor::StartMonitoringStream( 2711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci render_process_id_, 2721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci entry->render_frame_id(), 2731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci entry->stream_id(), 2741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&media::AudioOutputController::ReadCurrentPowerAndClip, 2751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci entry->controller())); 2761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // TODO(dalecurtis): See about using AudioStreamMonitor instead. 2771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!entry->playing()) { 2781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci entry->set_playing(true); 2791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::AtomicRefCountInc(&num_playing_streams_); 2801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else { 2821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci AudioStreamMonitor::StopMonitoringStream( 2831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci render_process_id_, entry->render_frame_id(), entry->stream_id()); 2841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // TODO(dalecurtis): See about using AudioStreamMonitor instead. 2851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (entry->playing()) { 2861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci entry->set_playing(false); 2871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::AtomicRefCountDec(&num_playing_streams_); 288a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 289a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 290a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 291a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 2921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)RenderViewHost::AudioOutputControllerList 2931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)AudioRendererHost::DoGetOutputControllers(int render_view_id) const { 294effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 2951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) RenderViewHost::AudioOutputControllerList controllers; 2971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) AudioEntryMap::const_iterator it = audio_entries_.begin(); 2981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) for (; it != audio_entries_.end(); ++it) { 2991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) AudioEntry* entry = it->second; 3001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (entry->render_view_id() == render_view_id) 3011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) controllers.push_back(entry->controller()); 3021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 3031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return controllers; 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/////////////////////////////////////////////////////////////////////////////// 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// IPC Messages handler 309cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool AudioRendererHost::OnMessageReceived(const IPC::Message& message) { 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool handled = true; 311cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) IPC_BEGIN_MESSAGE_MAP(AudioRendererHost, message) 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(AudioHostMsg_CreateStream, OnCreateStream) 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(AudioHostMsg_PlayStream, OnPlayStream) 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(AudioHostMsg_PauseStream, OnPauseStream) 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(AudioHostMsg_CloseStream, OnCloseStream) 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(AudioHostMsg_SetVolume, OnSetVolume) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_UNHANDLED(handled = false) 318cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) IPC_END_MESSAGE_MAP() 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return handled; 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioRendererHost::OnCreateStream( 3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int stream_id, int render_view_id, int render_frame_id, int session_id, 325868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const media::AudioParameters& params) { 326effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DVLOG(1) << "AudioRendererHost@" << this 329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << "::OnCreateStream(stream_id=" << stream_id 330868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) << ", render_view_id=" << render_view_id 331868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) << ", session_id=" << session_id << ")"; 332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK_GT(render_view_id, 0); 333a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK_GT(render_frame_id, 0); 334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // media::AudioParameters is validated in the deserializer. 3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (LookupById(stream_id) != NULL) { 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SendErrorMessage(stream_id); 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Initialize the |output_device_id| to an empty string which indicates that 34258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // the default device should be used. If a StreamDeviceInfo instance was found 34358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // though, then we use the matched output device. 3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string output_device_id; 34558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const StreamDeviceInfo* info = media_stream_manager_-> 34658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) audio_input_device_manager()->GetOpenedDeviceInfoById(session_id); 34758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (info) 34858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) output_device_id = info->device.matched_output_device_id; 34958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create the shared memory and share with the renderer process. 351a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) uint32 shared_memory_size = AudioBus::CalculateMemorySize(params); 352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory()); 353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!shared_memory->CreateAndMapAnonymous(shared_memory_size)) { 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendErrorMessage(stream_id); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<AudioSyncReader> reader( 3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new AudioSyncReader(shared_memory.get(), params)); 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!reader->Init()) { 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendErrorMessage(stream_id); 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MediaObserver* const media_observer = 366ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch GetContentClient()->browser()->GetMediaObserver(); 367ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (media_observer) 3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) media_observer->OnCreatingAudioStream(render_process_id_, render_frame_id); 369ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<AudioEntry> entry(new AudioEntry( 371a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) this, 372a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) stream_id, 373a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) render_view_id, 374a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) render_frame_id, 375a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) params, 376a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) output_device_id, 3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) shared_memory.Pass(), 378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) reader.PassAs<media::AudioOutputController::SyncReader>())); 379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (mirroring_manager_) { 380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) mirroring_manager_->AddDiverter( 3811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci render_process_id_, entry->render_frame_id(), entry->controller()); 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) audio_entries_.insert(std::make_pair(stream_id, entry.release())); 3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) audio_log_->OnCreated(stream_id, params, output_device_id); 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioRendererHost::OnPlayStream(int stream_id) { 388effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AudioEntry* entry = LookupById(stream_id); 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!entry) { 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendErrorMessage(stream_id); 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entry->controller()->Play(); 397f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) audio_log_->OnStarted(stream_id); 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioRendererHost::OnPauseStream(int stream_id) { 401effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AudioEntry* entry = LookupById(stream_id); 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!entry) { 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendErrorMessage(stream_id); 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entry->controller()->Pause(); 410f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) audio_log_->OnStopped(stream_id); 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioRendererHost::OnSetVolume(int stream_id, double volume) { 414effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AudioEntry* entry = LookupById(stream_id); 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!entry) { 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendErrorMessage(stream_id); 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make sure the volume is valid. 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (volume < 0 || volume > 1.0) 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entry->controller()->SetVolume(volume); 426f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) audio_log_->OnSetVolume(stream_id, volume); 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void AudioRendererHost::SendErrorMessage(int stream_id) { 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(new AudioMsg_NotifyStreamStateChanged( 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stream_id, media::AudioOutputIPCDelegate::kError)); 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 434c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void AudioRendererHost::OnCloseStream(int stream_id) { 435effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Prevent oustanding callbacks from attempting to close/delete the same 438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // AudioEntry twice. 439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AudioEntryMap::iterator i = audio_entries_.find(stream_id); 440c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (i == audio_entries_.end()) 441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<AudioEntry> entry(i->second); 443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) audio_entries_.erase(i); 444c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) media::AudioOutputController* const controller = entry->controller(); 4461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (mirroring_manager_) 4471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci mirroring_manager_->RemoveDiverter(controller); 448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) controller->Close( 449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&AudioRendererHost::DeleteEntry, this, base::Passed(&entry))); 450f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) audio_log_->OnClosed(stream_id); 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void AudioRendererHost::DeleteEntry(scoped_ptr<AudioEntry> entry) { 454effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 4551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci AudioStreamMonitor::StopMonitoringStream( 4561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci render_process_id_, entry->render_frame_id(), entry->stream_id()); 4571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (entry->playing()) 4581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::AtomicRefCountDec(&num_playing_streams_); 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void AudioRendererHost::ReportErrorAndClose(int stream_id) { 462effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 464c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Make sure this isn't a stray callback executing after the stream has been 465c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // closed, so error notifications aren't sent after clients believe the stream 466c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // is closed. 467c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!LookupById(stream_id)) 468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 470c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SendErrorMessage(stream_id); 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 472f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) audio_log_->OnError(stream_id); 473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) OnCloseStream(stream_id); 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 476c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)AudioRendererHost::AudioEntry* AudioRendererHost::LookupById(int stream_id) { 477effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AudioEntryMap::const_iterator i = audio_entries_.find(stream_id); 480c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return i != audio_entries_.end() ? i->second : NULL; 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 48346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)bool AudioRendererHost::HasActiveAudio() { 48446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return !base::AtomicRefCountIsZero(&num_playing_streams_); 48546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 48646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace content 488