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