Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(836)

Unified Diff: chrome/browser/renderer_host/audio_renderer_host.cc

Issue 6532073: Move core pieces of browser\renderer_host to src\content. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/renderer_host/audio_renderer_host.cc
===================================================================
--- chrome/browser/renderer_host/audio_renderer_host.cc (revision 75488)
+++ chrome/browser/renderer_host/audio_renderer_host.cc (working copy)
@@ -1,480 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/renderer_host/audio_renderer_host.h"
-
-#include "base/metrics/histogram.h"
-#include "base/process.h"
-#include "base/shared_memory.h"
-#include "chrome/browser/renderer_host/audio_sync_reader.h"
-#include "chrome/common/render_messages.h"
-#include "chrome/common/render_messages_params.h"
-#include "ipc/ipc_logging.h"
-
-// The minimum number of samples in a hardware packet.
-// This value is selected so that we can handle down to 5khz sample rate.
-static const int kMinSamplesPerHardwarePacket = 1024;
-
-// The maximum number of samples in a hardware packet.
-// This value is selected so that we can handle up to 192khz sample rate.
-static const int kMaxSamplesPerHardwarePacket = 64 * 1024;
-
-// This constant governs the hardware audio buffer size, this value should be
-// chosen carefully.
-// This value is selected so that we have 8192 samples for 48khz streams.
-static const int kMillisecondsPerHardwarePacket = 170;
-
-static uint32 SelectSamplesPerPacket(AudioParameters params) {
- // Select the number of samples that can provide at least
- // |kMillisecondsPerHardwarePacket| worth of audio data.
- int samples = kMinSamplesPerHardwarePacket;
- while (samples <= kMaxSamplesPerHardwarePacket &&
- samples * base::Time::kMillisecondsPerSecond <
- params.sample_rate * kMillisecondsPerHardwarePacket) {
- samples *= 2;
- }
- return samples;
-}
-
-AudioRendererHost::AudioEntry::AudioEntry()
- : render_view_id(0),
- stream_id(0),
- pending_buffer_request(false),
- pending_close(false) {
-}
-
-AudioRendererHost::AudioEntry::~AudioEntry() {}
-
-///////////////////////////////////////////////////////////////////////////////
-// AudioRendererHost implementations.
-AudioRendererHost::AudioRendererHost() {
-}
-
-AudioRendererHost::~AudioRendererHost() {
- DCHECK(audio_entries_.empty());
-}
-
-void AudioRendererHost::OnChannelClosing() {
- BrowserMessageFilter::OnChannelClosing();
-
- // Since the IPC channel is gone, close all requested audio streams.
- DeleteEntries();
-}
-
-void AudioRendererHost::OnDestruct() const {
- BrowserThread::DeleteOnIOThread::Destruct(this);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// media::AudioOutputController::EventHandler implementations.
-void AudioRendererHost::OnCreated(media::AudioOutputController* controller) {
- BrowserThread::PostTask(
- BrowserThread::IO,
- FROM_HERE,
- NewRunnableMethod(
- this,
- &AudioRendererHost::DoCompleteCreation,
- make_scoped_refptr(controller)));
-}
-
-void AudioRendererHost::OnPlaying(media::AudioOutputController* controller) {
- BrowserThread::PostTask(
- BrowserThread::IO,
- FROM_HERE,
- NewRunnableMethod(
- this,
- &AudioRendererHost::DoSendPlayingMessage,
- make_scoped_refptr(controller)));
-}
-
-void AudioRendererHost::OnPaused(media::AudioOutputController* controller) {
- BrowserThread::PostTask(
- BrowserThread::IO,
- FROM_HERE,
- NewRunnableMethod(
- this,
- &AudioRendererHost::DoSendPausedMessage,
- make_scoped_refptr(controller)));
-}
-
-void AudioRendererHost::OnError(media::AudioOutputController* controller,
- int error_code) {
- BrowserThread::PostTask(
- BrowserThread::IO,
- FROM_HERE,
- NewRunnableMethod(this,
- &AudioRendererHost::DoHandleError,
- make_scoped_refptr(controller),
- error_code));
-}
-
-void AudioRendererHost::OnMoreData(media::AudioOutputController* controller,
- AudioBuffersState buffers_state) {
- BrowserThread::PostTask(
- BrowserThread::IO,
- FROM_HERE,
- NewRunnableMethod(this,
- &AudioRendererHost::DoRequestMoreData,
- make_scoped_refptr(controller),
- buffers_state));
-}
-
-void AudioRendererHost::DoCompleteCreation(
- media::AudioOutputController* controller) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- AudioEntry* entry = LookupByController(controller);
- if (!entry)
- return;
-
- if (!peer_handle()) {
- NOTREACHED() << "Renderer process handle is invalid.";
- DeleteEntryOnError(entry);
- return;
- }
-
- // Once the audio stream is created then complete the creation process by
- // mapping shared memory and sharing with the renderer process.
- base::SharedMemoryHandle foreign_memory_handle;
- if (!entry->shared_memory.ShareToProcess(peer_handle(),
- &foreign_memory_handle)) {
- // If we failed to map and share the shared memory then close the audio
- // stream and send an error message.
- DeleteEntryOnError(entry);
- return;
- }
-
- if (entry->controller->LowLatencyMode()) {
- AudioSyncReader* reader =
- static_cast<AudioSyncReader*>(entry->reader.get());
-
-#if defined(OS_WIN)
- base::SyncSocket::Handle foreign_socket_handle;
-#else
- base::FileDescriptor foreign_socket_handle;
-#endif
-
- // If we failed to prepare the sync socket for the renderer then we fail
- // the construction of audio stream.
- if (!reader->PrepareForeignSocketHandle(peer_handle(),
- &foreign_socket_handle)) {
- DeleteEntryOnError(entry);
- return;
- }
-
- Send(new ViewMsg_NotifyLowLatencyAudioStreamCreated(
- entry->render_view_id, entry->stream_id, foreign_memory_handle,
- foreign_socket_handle, entry->shared_memory.created_size()));
- return;
- }
-
- // The normal audio stream has created, send a message to the renderer
- // process.
- Send(new ViewMsg_NotifyAudioStreamCreated(
- entry->render_view_id, entry->stream_id, foreign_memory_handle,
- entry->shared_memory.created_size()));
-}
-
-void AudioRendererHost::DoSendPlayingMessage(
- media::AudioOutputController* controller) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- AudioEntry* entry = LookupByController(controller);
- if (!entry)
- return;
-
- ViewMsg_AudioStreamState_Params params;
- params.state = ViewMsg_AudioStreamState_Params::kPlaying;
- Send(new ViewMsg_NotifyAudioStreamStateChanged(
- entry->render_view_id, entry->stream_id, params));
-}
-
-void AudioRendererHost::DoSendPausedMessage(
- media::AudioOutputController* controller) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- AudioEntry* entry = LookupByController(controller);
- if (!entry)
- return;
-
- ViewMsg_AudioStreamState_Params params;
- params.state = ViewMsg_AudioStreamState_Params::kPaused;
- Send(new ViewMsg_NotifyAudioStreamStateChanged(
- entry->render_view_id, entry->stream_id, params));
-}
-
-void AudioRendererHost::DoRequestMoreData(
- media::AudioOutputController* controller,
- AudioBuffersState buffers_state) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- // If we already have a pending request then return.
- AudioEntry* entry = LookupByController(controller);
- if (!entry || entry->pending_buffer_request)
- return;
-
- DCHECK(!entry->controller->LowLatencyMode());
- entry->pending_buffer_request = true;
- Send(new ViewMsg_RequestAudioPacket(
- entry->render_view_id, entry->stream_id, buffers_state));
-}
-
-void AudioRendererHost::DoHandleError(media::AudioOutputController* controller,
- int error_code) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- AudioEntry* entry = LookupByController(controller);
- if (!entry)
- return;
-
- DeleteEntryOnError(entry);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// IPC Messages handler
-bool AudioRendererHost::OnMessageReceived(const IPC::Message& message,
- bool* message_was_ok) {
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP_EX(AudioRendererHost, message, *message_was_ok)
- IPC_MESSAGE_HANDLER(ViewHostMsg_CreateAudioStream, OnCreateStream)
- IPC_MESSAGE_HANDLER(ViewHostMsg_PlayAudioStream, OnPlayStream)
- IPC_MESSAGE_HANDLER(ViewHostMsg_PauseAudioStream, OnPauseStream)
- IPC_MESSAGE_HANDLER(ViewHostMsg_FlushAudioStream, OnFlushStream)
- IPC_MESSAGE_HANDLER(ViewHostMsg_CloseAudioStream, OnCloseStream)
- IPC_MESSAGE_HANDLER(ViewHostMsg_NotifyAudioPacketReady, OnNotifyPacketReady)
- IPC_MESSAGE_HANDLER(ViewHostMsg_GetAudioVolume, OnGetVolume)
- IPC_MESSAGE_HANDLER(ViewHostMsg_SetAudioVolume, OnSetVolume)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP_EX()
-
- return handled;
-}
-
-void AudioRendererHost::OnCreateStream(
- const IPC::Message& msg, int stream_id,
- const ViewHostMsg_Audio_CreateStream_Params& params, bool low_latency) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- DCHECK(LookupById(msg.routing_id(), stream_id) == NULL);
-
- AudioParameters audio_params(params.params);
-
- // Select the hardware packet size if not specified.
- if (!audio_params.samples_per_packet) {
- audio_params.samples_per_packet = SelectSamplesPerPacket(audio_params);
- }
- uint32 packet_size = audio_params.GetPacketSize();
-
- scoped_ptr<AudioEntry> entry(new AudioEntry());
- // Create the shared memory and share with the renderer process.
- if (!entry->shared_memory.CreateAndMapAnonymous(packet_size)) {
- // If creation of shared memory failed then send an error message.
- SendErrorMessage(msg.routing_id(), stream_id);
- return;
- }
-
- if (low_latency) {
- // If this is the low latency mode, we need to construct a SyncReader first.
- scoped_ptr<AudioSyncReader> reader(
- new AudioSyncReader(&entry->shared_memory));
-
- // Then try to initialize the sync reader.
- if (!reader->Init()) {
- SendErrorMessage(msg.routing_id(), stream_id);
- return;
- }
-
- // If we have successfully created the SyncReader then assign it to the
- // entry and construct an AudioOutputController.
- entry->reader.reset(reader.release());
- entry->controller =
- media::AudioOutputController::CreateLowLatency(this, audio_params,
- entry->reader.get());
- } else {
- // The choice of buffer capacity is based on experiment.
- entry->controller =
- media::AudioOutputController::Create(this, audio_params,
- 3 * packet_size);
- }
-
- if (!entry->controller) {
- SendErrorMessage(msg.routing_id(), stream_id);
- return;
- }
-
- // If we have created the controller successfully create a entry and add it
- // to the map.
- entry->render_view_id = msg.routing_id();
- entry->stream_id = stream_id;
-
- audio_entries_.insert(std::make_pair(
- AudioEntryId(msg.routing_id(), stream_id),
- entry.release()));
-}
-
-void AudioRendererHost::OnPlayStream(const IPC::Message& msg, int stream_id) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- AudioEntry* entry = LookupById(msg.routing_id(), stream_id);
- if (!entry) {
- SendErrorMessage(msg.routing_id(), stream_id);
- return;
- }
-
- entry->controller->Play();
-}
-
-void AudioRendererHost::OnPauseStream(const IPC::Message& msg, int stream_id) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- AudioEntry* entry = LookupById(msg.routing_id(), stream_id);
- if (!entry) {
- SendErrorMessage(msg.routing_id(), stream_id);
- return;
- }
-
- entry->controller->Pause();
-}
-
-void AudioRendererHost::OnFlushStream(const IPC::Message& msg, int stream_id) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- AudioEntry* entry = LookupById(msg.routing_id(), stream_id);
- if (!entry) {
- SendErrorMessage(msg.routing_id(), stream_id);
- return;
- }
-
- entry->controller->Flush();
-}
-
-void AudioRendererHost::OnCloseStream(const IPC::Message& msg, int stream_id) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- AudioEntry* entry = LookupById(msg.routing_id(), stream_id);
-
- if (entry)
- CloseAndDeleteStream(entry);
-}
-
-void AudioRendererHost::OnSetVolume(const IPC::Message& msg, int stream_id,
- double volume) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- AudioEntry* entry = LookupById(msg.routing_id(), stream_id);
- if (!entry) {
- SendErrorMessage(msg.routing_id(), stream_id);
- return;
- }
-
- // Make sure the volume is valid.
- if (volume < 0 || volume > 1.0)
- return;
- entry->controller->SetVolume(volume);
-}
-
-void AudioRendererHost::OnGetVolume(const IPC::Message& msg, int stream_id) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- NOTREACHED() << "This message shouldn't be received";
-}
-
-void AudioRendererHost::OnNotifyPacketReady(
- const IPC::Message& msg, int stream_id, uint32 packet_size) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- AudioEntry* entry = LookupById(msg.routing_id(), stream_id);
- if (!entry) {
- SendErrorMessage(msg.routing_id(), stream_id);
- return;
- }
-
- DCHECK(!entry->controller->LowLatencyMode());
- CHECK(packet_size <= entry->shared_memory.created_size());
-
- if (!entry->pending_buffer_request) {
- NOTREACHED() << "Buffer received but no such pending request";
- }
- entry->pending_buffer_request = false;
-
- // Enqueue the data to media::AudioOutputController.
- entry->controller->EnqueueData(
- reinterpret_cast<uint8*>(entry->shared_memory.memory()),
- packet_size);
-}
-
-void AudioRendererHost::SendErrorMessage(int32 render_view_id,
- int32 stream_id) {
- ViewMsg_AudioStreamState_Params state;
- state.state = ViewMsg_AudioStreamState_Params::kError;
- Send(new ViewMsg_NotifyAudioStreamStateChanged(
- render_view_id, stream_id, state));
-}
-
-void AudioRendererHost::DeleteEntries() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- for (AudioEntryMap::iterator i = audio_entries_.begin();
- i != audio_entries_.end(); ++i) {
- CloseAndDeleteStream(i->second);
- }
-}
-
-void AudioRendererHost::CloseAndDeleteStream(AudioEntry* entry) {
- if (!entry->pending_close) {
- entry->controller->Close(
- NewRunnableMethod(this, &AudioRendererHost::OnStreamClosed, entry));
- entry->pending_close = true;
- }
-}
-
-void AudioRendererHost::OnStreamClosed(AudioEntry* entry) {
- // Delete the entry after we've closed the stream.
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- NewRunnableMethod(this, &AudioRendererHost::DeleteEntry, entry));
-}
-
-void AudioRendererHost::DeleteEntry(AudioEntry* entry) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- // Delete the entry when this method goes out of scope.
- scoped_ptr<AudioEntry> entry_deleter(entry);
-
- // Erase the entry from the map.
- audio_entries_.erase(
- AudioEntryId(entry->render_view_id, entry->stream_id));
-}
-
-void AudioRendererHost::DeleteEntryOnError(AudioEntry* entry) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- // Sends the error message first before we close the stream because
- // |entry| is destroyed in DeleteEntry().
- SendErrorMessage(entry->render_view_id, entry->stream_id);
- CloseAndDeleteStream(entry);
-}
-
-AudioRendererHost::AudioEntry* AudioRendererHost::LookupById(
- int route_id, int stream_id) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- AudioEntryMap::iterator i = audio_entries_.find(
- AudioEntryId(route_id, stream_id));
- if (i != audio_entries_.end() && !i->second->pending_close)
- return i->second;
- return NULL;
-}
-
-AudioRendererHost::AudioEntry* AudioRendererHost::LookupByController(
- media::AudioOutputController* controller) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- // Iterate the map of entries.
- // TODO(hclam): Implement a faster look up method.
- for (AudioEntryMap::iterator i = audio_entries_.begin();
- i != audio_entries_.end(); ++i) {
- if (!i->second->pending_close && controller == i->second->controller.get())
- return i->second;
- }
- return NULL;
-}

Powered by Google App Engine
This is Rietveld 408576698