1// Copyright (c) 2012 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#ifndef PPAPI_PROXY_AUDIO_INPUT_RESOURCE_H_
6#define PPAPI_PROXY_AUDIO_INPUT_RESOURCE_H_
7
8#include "base/basictypes.h"
9#include "base/compiler_specific.h"
10#include "base/memory/ref_counted.h"
11#include "base/memory/scoped_ptr.h"
12#include "base/memory/shared_memory.h"
13#include "base/sync_socket.h"
14#include "base/threading/simple_thread.h"
15#include "ppapi/proxy/device_enumeration_resource_helper.h"
16#include "ppapi/proxy/plugin_resource.h"
17#include "ppapi/shared_impl/scoped_pp_resource.h"
18#include "ppapi/thunk/ppb_audio_input_api.h"
19
20namespace media {
21class AudioBus;
22}
23
24namespace ppapi {
25namespace proxy {
26
27class ResourceMessageReplyParams;
28
29class AudioInputResource : public PluginResource,
30                           public thunk::PPB_AudioInput_API,
31                           public base::DelegateSimpleThread::Delegate {
32 public:
33  AudioInputResource(Connection connection, PP_Instance instance);
34  virtual ~AudioInputResource();
35
36  // Resource overrides.
37  virtual thunk::PPB_AudioInput_API* AsPPB_AudioInput_API() OVERRIDE;
38  virtual void OnReplyReceived(const ResourceMessageReplyParams& params,
39                               const IPC::Message& msg) OVERRIDE;
40
41  // PPB_AudioInput_API implementation.
42  virtual int32_t EnumerateDevices(
43      const PP_ArrayOutput& output,
44      scoped_refptr<TrackedCallback> callback) OVERRIDE;
45  virtual int32_t MonitorDeviceChange(
46      PP_MonitorDeviceChangeCallback callback,
47      void* user_data) OVERRIDE;
48  virtual int32_t Open0_3(PP_Resource device_ref,
49                          PP_Resource config,
50                          PPB_AudioInput_Callback_0_3 audio_input_callback_0_3,
51                          void* user_data,
52                          scoped_refptr<TrackedCallback> callback) OVERRIDE;
53  virtual int32_t Open(PP_Resource device_ref,
54                       PP_Resource config,
55                       PPB_AudioInput_Callback audio_input_callback,
56                       void* user_data,
57                       scoped_refptr<TrackedCallback> callback) OVERRIDE;
58  virtual PP_Resource GetCurrentConfig() OVERRIDE;
59  virtual PP_Bool StartCapture() OVERRIDE;
60  virtual PP_Bool StopCapture() OVERRIDE;
61  virtual void Close() OVERRIDE;
62
63 protected:
64  // Resource override.
65  virtual void LastPluginRefWasDeleted() OVERRIDE;
66
67 private:
68  enum OpenState {
69    BEFORE_OPEN,
70    OPENED,
71    CLOSED
72  };
73
74  void OnPluginMsgOpenReply(const ResourceMessageReplyParams& params);
75
76  // Sets the shared memory and socket handles. This will automatically start
77  // capture if we're currently set to capture.
78  void SetStreamInfo(base::SharedMemoryHandle shared_memory_handle,
79                     size_t shared_memory_size,
80                     base::SyncSocket::Handle socket_handle);
81
82  // Starts execution of the audio input thread.
83  void StartThread();
84
85  // Stops execution of the audio input thread.
86  void StopThread();
87
88  // DelegateSimpleThread::Delegate implementation.
89  // Run on the audio input thread.
90  virtual void Run() OVERRIDE;
91
92  int32_t CommonOpen(PP_Resource device_ref,
93                     PP_Resource config,
94                     PPB_AudioInput_Callback_0_3 audio_input_callback_0_3,
95                     PPB_AudioInput_Callback audio_input_callback,
96                     void* user_data,
97                     scoped_refptr<TrackedCallback> callback);
98
99  OpenState open_state_;
100
101  // True if capturing the stream.
102  bool capturing_;
103
104  // Socket used to notify us when new samples are available. This pointer is
105  // created in SetStreamInfo().
106  scoped_ptr<base::CancelableSyncSocket> socket_;
107
108  // Sample buffer in shared memory. This pointer is created in
109  // SetStreamInfo(). The memory is only mapped when the audio thread is
110  // created.
111  scoped_ptr<base::SharedMemory> shared_memory_;
112
113  // The size of the sample buffer in bytes.
114  size_t shared_memory_size_;
115
116  // When the callback is set, this thread is spawned for calling it.
117  scoped_ptr<base::DelegateSimpleThread> audio_input_thread_;
118
119  // Callback to call when new samples are available.
120  PPB_AudioInput_Callback_0_3 audio_input_callback_0_3_;
121  PPB_AudioInput_Callback audio_input_callback_;
122
123  // User data pointer passed verbatim to the callback function.
124  void* user_data_;
125
126  // The callback is not directly passed to OnPluginMsgOpenReply() because we
127  // would like to be able to cancel it early in Close().
128  scoped_refptr<TrackedCallback> open_callback_;
129
130  // Owning reference to the current config object. This isn't actually used,
131  // we just dish it out as requested by the plugin.
132  ScopedPPResource config_;
133
134  DeviceEnumerationResourceHelper enumeration_helper_;
135
136  // The data size (in bytes) of one second of audio input. Used to calculate
137  // latency.
138  size_t bytes_per_second_;
139
140  // AudioBus for shuttling data across the shared memory.
141  scoped_ptr<media::AudioBus> audio_bus_;
142  int sample_frame_count_;
143
144  // Internal buffer for client's integer audio data.
145  int client_buffer_size_bytes_;
146  scoped_ptr<uint8_t[]> client_buffer_;
147
148  DISALLOW_COPY_AND_ASSIGN(AudioInputResource);
149};
150
151}  // namespace proxy
152}  // namespace ppapi
153
154#endif  // PPAPI_PROXY_AUDIO_INPUT_RESOURCE_H_
155