[email protected] | 028b90f6 | 2012-04-05 01:44:13 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
[email protected] | 5d84d01 | 2010-12-02 17:17:21 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
[email protected] | 9a57839 | 2011-12-07 18:59:27 | [diff] [blame] | 5 | #ifndef PPAPI_SHARED_IMPL_PPB_AUDIO_SHARED_H_ |
| 6 | #define PPAPI_SHARED_IMPL_PPB_AUDIO_SHARED_H_ |
[email protected] | 5d84d01 | 2010-12-02 17:17:21 | [diff] [blame] | 7 | |
avi | e029c413 | 2015-12-23 06:45:22 | [diff] [blame] | 8 | #include <stddef.h> |
| 9 | #include <stdint.h> |
| 10 | |
dcheng | ced9224 | 2016-04-07 00:00:12 | [diff] [blame] | 11 | #include <memory> |
| 12 | |
avi | e029c413 | 2015-12-23 06:45:22 | [diff] [blame] | 13 | #include "base/macros.h" |
[email protected] | 8299b71 | 2013-07-17 19:55:23 | [diff] [blame] | 14 | #include "base/memory/shared_memory.h" |
[email protected] | 5d84d01 | 2010-12-02 17:17:21 | [diff] [blame] | 15 | #include "base/sync_socket.h" |
[email protected] | ac9ba8fe | 2010-12-30 18:08:36 | [diff] [blame] | 16 | #include "base/threading/simple_thread.h" |
[email protected] | dfc48e4c | 2012-09-05 13:39:21 | [diff] [blame] | 17 | #include "media/base/audio_bus.h" |
[email protected] | b9a5984 | 2011-01-15 01:04:00 | [diff] [blame] | 18 | #include "ppapi/c/ppb_audio.h" |
[email protected] | 6b151126 | 2013-09-06 21:46:34 | [diff] [blame] | 19 | #include "ppapi/c/ppb_audio_config.h" |
[email protected] | 7f8b26b | 2011-08-18 15:41:01 | [diff] [blame] | 20 | #include "ppapi/shared_impl/resource.h" |
[email protected] | 55cdf605 | 2011-05-13 19:22:53 | [diff] [blame] | 21 | #include "ppapi/thunk/ppb_audio_api.h" |
[email protected] | 5d84d01 | 2010-12-02 17:17:21 | [diff] [blame] | 22 | |
[email protected] | d40ece1 | 2014-04-23 16:11:39 | [diff] [blame] | 23 | struct PP_ThreadFunctions; |
[email protected] | 420ade4 | 2012-07-25 21:47:31 | [diff] [blame] | 24 | |
[email protected] | 55cdf605 | 2011-05-13 19:22:53 | [diff] [blame] | 25 | namespace ppapi { |
[email protected] | 5d84d01 | 2010-12-02 17:17:21 | [diff] [blame] | 26 | |
[email protected] | 6b151126 | 2013-09-06 21:46:34 | [diff] [blame] | 27 | class PPAPI_SHARED_EXPORT AudioCallbackCombined { |
| 28 | public: |
| 29 | AudioCallbackCombined(); |
| 30 | explicit AudioCallbackCombined(PPB_Audio_Callback_1_0 callback_1_0); |
| 31 | explicit AudioCallbackCombined(PPB_Audio_Callback callback); |
| 32 | |
| 33 | ~AudioCallbackCombined(); |
| 34 | |
| 35 | bool IsValid() const; |
| 36 | |
| 37 | void Run(void* sample_buffer, |
| 38 | uint32_t buffer_size_in_bytes, |
| 39 | PP_TimeDelta latency, |
| 40 | void* user_data) const; |
| 41 | |
| 42 | private: |
| 43 | PPB_Audio_Callback_1_0 callback_1_0_; |
| 44 | PPB_Audio_Callback callback_; |
| 45 | }; |
| 46 | |
[email protected] | 5d84d01 | 2010-12-02 17:17:21 | [diff] [blame] | 47 | // Implements the logic to map shared memory and run the audio thread signaled |
| 48 | // from the sync socket. Both the proxy and the renderer implementation use |
| 49 | // this code. |
[email protected] | 9a57839 | 2011-12-07 18:59:27 | [diff] [blame] | 50 | class PPAPI_SHARED_EXPORT PPB_Audio_Shared |
[email protected] | f0a04c4 | 2011-08-26 22:43:20 | [diff] [blame] | 51 | : public thunk::PPB_Audio_API, |
| 52 | public base::DelegateSimpleThread::Delegate { |
[email protected] | 5d84d01 | 2010-12-02 17:17:21 | [diff] [blame] | 53 | public: |
[email protected] | 9a57839 | 2011-12-07 18:59:27 | [diff] [blame] | 54 | PPB_Audio_Shared(); |
| 55 | virtual ~PPB_Audio_Shared(); |
[email protected] | 5d84d01 | 2010-12-02 17:17:21 | [diff] [blame] | 56 | |
| 57 | bool playing() const { return playing_; } |
| 58 | |
| 59 | // Sets the callback information that the background thread will use. This |
| 60 | // is optional. Without a callback, the thread will not be run. This |
| 61 | // non-callback mode is used in the renderer with the proxy, since the proxy |
| 62 | // handles the callback entirely within the plugin process. |
[email protected] | 6b151126 | 2013-09-06 21:46:34 | [diff] [blame] | 63 | void SetCallback(const AudioCallbackCombined& callback, void* user_data); |
[email protected] | 5d84d01 | 2010-12-02 17:17:21 | [diff] [blame] | 64 | |
| 65 | // Configures the current state to be playing or not. The caller is |
| 66 | // responsible for ensuring the new state is the opposite of the current one. |
| 67 | // |
| 68 | // This is the implementation for PPB_Audio.Start/StopPlayback, except that |
| 69 | // it does not actually notify the audio system to stop playback, it just |
| 70 | // configures our object to stop generating callbacks. The actual stop |
| 71 | // playback request will be done in the derived classes and will be different |
| 72 | // from the proxy and the renderer. |
| 73 | void SetStartPlaybackState(); |
| 74 | void SetStopPlaybackState(); |
| 75 | |
| 76 | // Sets the shared memory and socket handles. This will automatically start |
| 77 | // playback if we're currently set to play. |
[email protected] | 9672468 | 2012-04-26 20:53:37 | [diff] [blame] | 78 | void SetStreamInfo(PP_Instance instance, |
| 79 | base::SharedMemoryHandle shared_memory_handle, |
[email protected] | 5d84d01 | 2010-12-02 17:17:21 | [diff] [blame] | 80 | size_t shared_memory_size, |
[email protected] | dfc48e4c | 2012-09-05 13:39:21 | [diff] [blame] | 81 | base::SyncSocket::Handle socket_handle, |
[email protected] | 6b151126 | 2013-09-06 21:46:34 | [diff] [blame] | 82 | PP_AudioSampleRate sample_rate, |
[email protected] | dfc48e4c | 2012-09-05 13:39:21 | [diff] [blame] | 83 | int sample_frame_count); |
[email protected] | 5d84d01 | 2010-12-02 17:17:21 | [diff] [blame] | 84 | |
[email protected] | a4a01e4 | 2014-04-21 10:36:21 | [diff] [blame] | 85 | // Returns whether a thread can be created on the client context. |
| 86 | // In trusted plugin, this should always return true, as it uses Chrome's |
| 87 | // thread library. In NaCl plugin, this returns whether SetThreadFunctions |
| 88 | // was invoked properly. |
| 89 | static bool IsThreadFunctionReady(); |
| 90 | |
[email protected] | d40ece1 | 2014-04-23 16:11:39 | [diff] [blame] | 91 | // Configures this class to run in a NaCl plugin. |
| 92 | // If called, SetThreadFunctions() must be called before calling |
| 93 | // SetStartPlaybackState() on any instance of this class. |
| 94 | static void SetNaClMode(); |
| 95 | |
[email protected] | 420ade4 | 2012-07-25 21:47:31 | [diff] [blame] | 96 | // NaCl has a special API for IRT code to create threads that can call back |
| 97 | // into user code. |
| 98 | static void SetThreadFunctions(const struct PP_ThreadFunctions* functions); |
[email protected] | 246fc49 | 2012-08-27 20:28:18 | [diff] [blame] | 99 | |
[email protected] | 5d84d01 | 2010-12-02 17:17:21 | [diff] [blame] | 100 | private: |
| 101 | // Starts execution of the audio thread. |
| 102 | void StartThread(); |
| 103 | |
[email protected] | 0e8d17b1 | 2012-05-15 21:32:25 | [diff] [blame] | 104 | // Stop execution of the audio thread. |
| 105 | void StopThread(); |
| 106 | |
[email protected] | 5d84d01 | 2010-12-02 17:17:21 | [diff] [blame] | 107 | // DelegateSimpleThread::Delegate implementation. Run on the audio thread. |
[email protected] | 78994ab0 | 2010-12-08 18:06:44 | [diff] [blame] | 108 | virtual void Run(); |
[email protected] | 5d84d01 | 2010-12-02 17:17:21 | [diff] [blame] | 109 | |
| 110 | // True if playing the stream. |
| 111 | bool playing_; |
| 112 | |
| 113 | // Socket used to notify us when audio is ready to accept new samples. This |
| 114 | // pointer is created in StreamCreated(). |
dcheng | ced9224 | 2016-04-07 00:00:12 | [diff] [blame] | 115 | std::unique_ptr<base::CancelableSyncSocket> socket_; |
[email protected] | 5d84d01 | 2010-12-02 17:17:21 | [diff] [blame] | 116 | |
| 117 | // Sample buffer in shared memory. This pointer is created in |
| 118 | // StreamCreated(). The memory is only mapped when the audio thread is |
| 119 | // created. |
dcheng | ced9224 | 2016-04-07 00:00:12 | [diff] [blame] | 120 | std::unique_ptr<base::SharedMemory> shared_memory_; |
[email protected] | 5d84d01 | 2010-12-02 17:17:21 | [diff] [blame] | 121 | |
| 122 | // The size of the sample buffer in bytes. |
| 123 | size_t shared_memory_size_; |
| 124 | |
| 125 | // When the callback is set, this thread is spawned for calling it. |
dcheng | ced9224 | 2016-04-07 00:00:12 | [diff] [blame] | 126 | std::unique_ptr<base::DelegateSimpleThread> audio_thread_; |
[email protected] | d40ece1 | 2014-04-23 16:11:39 | [diff] [blame] | 127 | uintptr_t nacl_thread_id_; |
| 128 | bool nacl_thread_active_; |
[email protected] | 420ade4 | 2012-07-25 21:47:31 | [diff] [blame] | 129 | |
| 130 | static void CallRun(void* self); |
[email protected] | 5d84d01 | 2010-12-02 17:17:21 | [diff] [blame] | 131 | |
| 132 | // Callback to call when audio is ready to accept new samples. |
[email protected] | 6b151126 | 2013-09-06 21:46:34 | [diff] [blame] | 133 | AudioCallbackCombined callback_; |
[email protected] | 5d84d01 | 2010-12-02 17:17:21 | [diff] [blame] | 134 | |
| 135 | // User data pointer passed verbatim to the callback function. |
| 136 | void* user_data_; |
[email protected] | 9a57839 | 2011-12-07 18:59:27 | [diff] [blame] | 137 | |
[email protected] | dfc48e4c | 2012-09-05 13:39:21 | [diff] [blame] | 138 | // AudioBus for shuttling data across the shared memory. |
dcheng | ced9224 | 2016-04-07 00:00:12 | [diff] [blame] | 139 | std::unique_ptr<media::AudioBus> audio_bus_; |
[email protected] | dfc48e4c | 2012-09-05 13:39:21 | [diff] [blame] | 140 | |
| 141 | // Internal buffer for client's integer audio data. |
| 142 | int client_buffer_size_bytes_; |
dcheng | ced9224 | 2016-04-07 00:00:12 | [diff] [blame] | 143 | std::unique_ptr<uint8_t[]> client_buffer_; |
[email protected] | dfc48e4c | 2012-09-05 13:39:21 | [diff] [blame] | 144 | |
[email protected] | 6b151126 | 2013-09-06 21:46:34 | [diff] [blame] | 145 | // The size (in bytes) of one second of audio data. Used to calculate latency. |
| 146 | size_t bytes_per_second_; |
| 147 | |
[email protected] | 1caf0aa | 2013-10-31 07:58:02 | [diff] [blame] | 148 | // Buffer index used to coordinate with the browser side audio receiver. |
| 149 | uint32_t buffer_index_; |
| 150 | |
[email protected] | 9a57839 | 2011-12-07 18:59:27 | [diff] [blame] | 151 | DISALLOW_COPY_AND_ASSIGN(PPB_Audio_Shared); |
[email protected] | 5d84d01 | 2010-12-02 17:17:21 | [diff] [blame] | 152 | }; |
| 153 | |
[email protected] | 55cdf605 | 2011-05-13 19:22:53 | [diff] [blame] | 154 | } // namespace ppapi |
[email protected] | 5d84d01 | 2010-12-02 17:17:21 | [diff] [blame] | 155 | |
[email protected] | 9a57839 | 2011-12-07 18:59:27 | [diff] [blame] | 156 | #endif // PPAPI_SHARED_IMPL_PPB_AUDIO_SHARED_H_ |