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