1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
|
// Copyright (c) 2012 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.
//
// AudioInputRendererHost serves audio related requests from audio capturer
// which lives inside the render process and provide access to audio hardware.
//
// Create stream sequence (AudioInputController = AIC):
//
// AudioInputHostMsg_CreateStream -> OnCreateStream -> AIC::CreateLowLatency ->
// <- AudioInputMsg_NotifyStreamCreated <- DoCompleteCreation <- OnCreated <-
//
// Close stream sequence:
//
// AudioInputHostMsg_CloseStream -> OnCloseStream -> AIC::Close ->
//
// For the OnStartDevice() request, AudioInputRendererHost starts the device
// referenced by the session id, and an OnDeviceStarted() callback with the
// id of the opened device will be received later. Then it will send a
// IPC message to notify the renderer that the device is ready, so that
// renderer can continue with the OnCreateStream() request.
//
// OnDeviceStopped() is called when the user closes the device through
// AudioInputDeviceManager without calling Stop() before. What
// AudioInputRenderHost::OnDeviceStopped() does is to send a IPC mesaage to
// notify the renderer in order to stop the stream.
//
// Start device sequence:
//
// OnStartDevice -> AudioInputDeviceManager::Start ->
// AudioInputDeviceManagerEventHandler::OnDeviceStarted ->
// AudioInputMsg_NotifyDeviceStarted
//
// Shutdown device sequence:
//
// OnDeviceStopped -> CloseAndDeleteStream
// AudioInputMsg_NotifyStreamStateChanged
//
// This class is owned by BrowserRenderProcessHost and instantiated on UI
// thread. All other operations and method calls happen on IO thread, so we
// need to be extra careful about the lifetime of this object.
//
// To ensure low latency audio, a SyncSocket pair is used to signal buffer
// readiness without having to route messages using the IO thread.
#ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_AUDIO_INPUT_RENDERER_HOST_H_
#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_AUDIO_INPUT_RENDERER_HOST_H_
#pragma once
#include <map>
#include <string>
#include "base/compiler_specific.h"
#include "base/gtest_prod_util.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/process.h"
#include "base/sequenced_task_runner_helpers.h"
#include "base/shared_memory.h"
#include "content/browser/renderer_host/media/audio_input_device_manager_event_handler.h"
#include "content/public/browser/browser_message_filter.h"
#include "content/public/browser/browser_thread.h"
#include "media/audio/audio_input_controller.h"
#include "media/audio/audio_io.h"
#include "media/audio/simple_sources.h"
namespace content {
class ResourceContext;
}
namespace media {
class AudioManager;
class AudioParameters;
}
class CONTENT_EXPORT AudioInputRendererHost
: public content::BrowserMessageFilter,
public media::AudioInputController::EventHandler,
public media_stream::AudioInputDeviceManagerEventHandler {
public:
struct AudioEntry {
AudioEntry();
~AudioEntry();
// The AudioInputController that manages the audio input stream.
scoped_refptr<media::AudioInputController> controller;
// The audio input stream ID in the render view.
int stream_id;
// Shared memory for transmission of the audio data.
base::SharedMemory shared_memory;
// The synchronous writer to be used by the controller. We have the
// ownership of the writer.
scoped_ptr<media::AudioInputController::SyncWriter> writer;
// Set to true after we called Close() for the controller.
bool pending_close;
};
// Called from UI thread from the owner of this object.
AudioInputRendererHost(content::ResourceContext* resource_context,
media::AudioManager* audio_manager);
// content::BrowserMessageFilter implementation.
virtual void OnChannelClosing() OVERRIDE;
virtual void OnDestruct() const OVERRIDE;
virtual bool OnMessageReceived(const IPC::Message& message,
bool* message_was_ok) OVERRIDE;
// AudioInputController::EventHandler implementation.
virtual void OnCreated(media::AudioInputController* controller) OVERRIDE;
virtual void OnRecording(media::AudioInputController* controller) OVERRIDE;
virtual void OnError(media::AudioInputController* controller,
int error_code) OVERRIDE;
virtual void OnData(media::AudioInputController* controller,
const uint8* data,
uint32 size) OVERRIDE;
// media_stream::AudioInputDeviceManagerEventHandler implementation.
virtual void OnDeviceStarted(int session_id,
const std::string& device_id) OVERRIDE;
virtual void OnDeviceStopped(int session_id) OVERRIDE;
private:
// TODO(henrika): extend test suite (compare AudioRenderHost)
friend class content::BrowserThread;
friend class base::DeleteHelper<AudioInputRendererHost>;
virtual ~AudioInputRendererHost();
// Methods called on IO thread ----------------------------------------------
// Start the audio input device with the session id. If the device
// starts successfully, it will trigger OnDeviceStarted() callback.
void OnStartDevice(int stream_id, int session_id);
// Audio related IPC message handlers.
// Creates an audio input stream with the specified format. If this call is
// successful this object would keep an internal entry of the stream for the
// required properties.
void OnCreateStream(int stream_id,
const media::AudioParameters& params,
const std::string& device_id,
bool automatic_gain_control);
// Record the audio input stream referenced by |stream_id|.
void OnRecordStream(int stream_id);
// Close the audio stream referenced by |stream_id|.
void OnCloseStream(int stream_id);
// Set the volume of the audio stream referenced by |stream_id|.
void OnSetVolume(int stream_id, double volume);
// Complete the process of creating an audio input stream. This will set up
// the shared memory or shared socket in low latency mode.
void DoCompleteCreation(media::AudioInputController* controller);
// Send a state change message to the renderer.
void DoSendRecordingMessage(media::AudioInputController* controller);
void DoSendPausedMessage(media::AudioInputController* controller);
// Handle error coming from audio stream.
void DoHandleError(media::AudioInputController* controller, int error_code);
// Send an error message to the renderer.
void SendErrorMessage(int stream_id);
// Delete all audio entry and all audio streams
void DeleteEntries();
// Closes the stream. The stream is then deleted in DeleteEntry() after it
// is closed.
void CloseAndDeleteStream(AudioEntry* entry);
// Delete an audio entry and close the related audio stream.
void DeleteEntry(AudioEntry* entry);
// Delete audio entry and close the related audio input stream.
void DeleteEntryOnError(AudioEntry* entry);
// Stop the device and delete its audio session entry.
void StopAndDeleteDevice(int stream_id);
// A helper method to look up a AudioEntry identified by |stream_id|.
// Returns NULL if not found.
AudioEntry* LookupById(int stream_id);
// Search for a AudioEntry having the reference to |controller|.
// This method is used to look up an AudioEntry after a controller
// event is received.
AudioEntry* LookupByController(media::AudioInputController* controller);
// A helper method to look up a session identified by |stream_id|.
// Returns 0 if not found.
int LookupSessionById(int stream_id);
// Used to get an instance of AudioInputDeviceManager.
content::ResourceContext* resource_context_;
media::AudioManager* audio_manager_;
// A map of stream IDs to audio sources.
typedef std::map<int, AudioEntry*> AudioEntryMap;
AudioEntryMap audio_entries_;
// A map of session IDs to audio session sources.
typedef std::map<int, int> SessionEntryMap;
SessionEntryMap session_entries_;
DISALLOW_COPY_AND_ASSIGN(AudioInputRendererHost);
};
#endif // CONTENT_BROWSER_RENDERER_HOST_MEDIA_AUDIO_INPUT_RENDERER_HOST_H_
|