Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / modules / audio_device / android / opensles_output.h
1 /*
2  *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10
11 #ifndef WEBRTC_MODULES_AUDIO_DEVICE_ANDROID_OPENSLES_OUTPUT_H_
12 #define WEBRTC_MODULES_AUDIO_DEVICE_ANDROID_OPENSLES_OUTPUT_H_
13
14 #include <SLES/OpenSLES.h>
15 #include <SLES/OpenSLES_Android.h>
16 #include <SLES/OpenSLES_AndroidConfiguration.h>
17
18 #include "webrtc/modules/audio_device/android/audio_manager_jni.h"
19 #include "webrtc/modules/audio_device/android/low_latency_event.h"
20 #include "webrtc/modules/audio_device/android/audio_common.h"
21 #include "webrtc/modules/audio_device/include/audio_device_defines.h"
22 #include "webrtc/modules/audio_device/include/audio_device.h"
23 #include "webrtc/system_wrappers/interface/scoped_ptr.h"
24
25 namespace webrtc {
26
27 class AudioDeviceBuffer;
28 class CriticalSectionWrapper;
29 class FineAudioBuffer;
30 class SingleRwFifo;
31 class ThreadWrapper;
32
33 // OpenSL implementation that facilitate playing PCM data to an android device.
34 // This class is Thread-compatible. I.e. Given an instance of this class, calls
35 // to non-const methods require exclusive access to the object.
36 class OpenSlesOutput : public PlayoutDelayProvider {
37  public:
38   explicit OpenSlesOutput(const int32_t id);
39   virtual ~OpenSlesOutput();
40
41   static int32_t SetAndroidAudioDeviceObjects(void* javaVM,
42                                               void* env,
43                                               void* context);
44   static void ClearAndroidAudioDeviceObjects();
45
46   // Main initializaton and termination
47   int32_t Init();
48   int32_t Terminate();
49   bool Initialized() const { return initialized_; }
50
51   // Device enumeration
52   int16_t PlayoutDevices() { return 1; }
53
54   int32_t PlayoutDeviceName(uint16_t index,
55                             char name[kAdmMaxDeviceNameSize],
56                             char guid[kAdmMaxGuidSize]);
57
58   // Device selection
59   int32_t SetPlayoutDevice(uint16_t index);
60   int32_t SetPlayoutDevice(
61       AudioDeviceModule::WindowsDeviceType device) { return 0; }
62
63   // No-op
64   int32_t SetPlayoutSampleRate(uint32_t sample_rate_hz) { return 0; }
65
66   // Audio transport initialization
67   int32_t PlayoutIsAvailable(bool& available);  // NOLINT
68   int32_t InitPlayout();
69   bool PlayoutIsInitialized() const { return play_initialized_; }
70
71   // Audio transport control
72   int32_t StartPlayout();
73   int32_t StopPlayout();
74   bool Playing() const { return playing_; }
75
76   // Audio mixer initialization
77   int32_t InitSpeaker();
78   bool SpeakerIsInitialized() const { return speaker_initialized_; }
79
80   // Speaker volume controls
81   int32_t SpeakerVolumeIsAvailable(bool& available);  // NOLINT
82   int32_t SetSpeakerVolume(uint32_t volume);
83   int32_t SpeakerVolume(uint32_t& volume) const { return 0; }  // NOLINT
84   int32_t MaxSpeakerVolume(uint32_t& maxVolume) const;  // NOLINT
85   int32_t MinSpeakerVolume(uint32_t& minVolume) const;  // NOLINT
86   int32_t SpeakerVolumeStepSize(uint16_t& stepSize) const;  // NOLINT
87
88   // Speaker mute control
89   int32_t SpeakerMuteIsAvailable(bool& available);  // NOLINT
90   int32_t SetSpeakerMute(bool enable) { return -1; }
91   int32_t SpeakerMute(bool& enabled) const { return -1; }  // NOLINT
92
93
94   // Stereo support
95   int32_t StereoPlayoutIsAvailable(bool& available);  // NOLINT
96   int32_t SetStereoPlayout(bool enable);
97   int32_t StereoPlayout(bool& enabled) const;  // NOLINT
98
99   // Delay information and control
100   int32_t SetPlayoutBuffer(const AudioDeviceModule::BufferType type,
101                                    uint16_t sizeMS) { return -1; }
102   int32_t PlayoutBuffer(AudioDeviceModule::BufferType& type,  // NOLINT
103                         uint16_t& sizeMS) const;
104   int32_t PlayoutDelay(uint16_t& delayMS) const;  // NOLINT
105
106
107   // Error and warning information
108   bool PlayoutWarning() const { return false; }
109   bool PlayoutError() const { return false; }
110   void ClearPlayoutWarning() {}
111   void ClearPlayoutError() {}
112
113   // Attach audio buffer
114   void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer);
115
116   // Speaker audio routing
117   int32_t SetLoudspeakerStatus(bool enable);
118   int32_t GetLoudspeakerStatus(bool& enable) const;  // NOLINT
119
120  protected:
121   virtual int PlayoutDelayMs();
122
123  private:
124   enum {
125     kNumInterfaces = 3,
126     // TODO(xians): Reduce the numbers of buffers to improve the latency.
127     //              Currently 30ms worth of buffers are needed due to audio
128     //              pipeline processing jitter. Note: kNumOpenSlBuffers must
129     //              not be changed.
130     // According to the opensles documentation in the ndk:
131     // The lower output latency path is used only if the application requests a
132     // buffer count of 2 or more. Use minimum number of buffers to keep delay
133     // as low as possible.
134     kNumOpenSlBuffers = 2,
135     // NetEq delivers frames on a 10ms basis. This means that every 10ms there
136     // will be a time consuming task. Keeping 10ms worth of buffers will ensure
137     // that there is 10ms to perform the time consuming task without running
138     // into underflow.
139     // In addition to the 10ms that needs to be stored for NetEq processing
140     // there will be jitter in audio pipe line due to the acquisition of locks.
141     // Note: The buffers in the OpenSL queue do not count towards the 10ms of
142     // frames needed since OpenSL needs to have them ready for playout.
143     kNum10MsToBuffer = 6,
144   };
145
146   bool InitSampleRate();
147   bool SetLowLatency();
148   void UpdatePlayoutDelay();
149   // It might be possible to dynamically add or remove buffers based on how
150   // close to depletion the fifo is. Few buffers means low delay. Too few
151   // buffers will cause underrun. Dynamically changing the number of buffer
152   // will greatly increase code complexity.
153   void CalculateNumFifoBuffersNeeded();
154   void AllocateBuffers();
155   int TotalBuffersUsed() const;
156   bool EnqueueAllBuffers();
157   // This function also configures the audio player, e.g. sample rate to use
158   // etc, so it should be called when starting playout.
159   bool CreateAudioPlayer();
160   void DestroyAudioPlayer();
161
162   // When underrun happens there won't be a new frame ready for playout that
163   // can be retrieved yet. Since the OpenSL thread must return ASAP there will
164   // be one less queue available to OpenSL. This function handles this case
165   // gracefully by restarting the audio, pushing silent frames to OpenSL for
166   // playout. This will sound like a click. Underruns are also logged to
167   // make it possible to identify these types of audio artifacts.
168   // This function returns true if there has been underrun. Further processing
169   // of audio data should be avoided until this function returns false again.
170   // The function needs to be protected by |crit_sect_|.
171   bool HandleUnderrun(int event_id, int event_msg);
172
173   static void PlayerSimpleBufferQueueCallback(
174       SLAndroidSimpleBufferQueueItf queueItf,
175       void* pContext);
176   // This function must not take any locks or do any heavy work. It is a
177   // requirement for the OpenSL implementation to work as intended. The reason
178   // for this is that taking locks exposes the OpenSL thread to the risk of
179   // priority inversion.
180   void PlayerSimpleBufferQueueCallbackHandler(
181       SLAndroidSimpleBufferQueueItf queueItf);
182
183   bool StartCbThreads();
184   void StopCbThreads();
185   static bool CbThread(void* context);
186   // This function must be protected against data race with threads calling this
187   // class' public functions. It is a requirement for this class to be
188   // Thread-compatible.
189   bool CbThreadImpl();
190
191   // Java API handle
192   AudioManagerJni audio_manager_;
193
194   int id_;
195   bool initialized_;
196   bool speaker_initialized_;
197   bool play_initialized_;
198
199   // Members that are read/write accessed concurrently by the process thread and
200   // threads calling public functions of this class.
201   scoped_ptr<ThreadWrapper> play_thread_;  // Processing thread
202   scoped_ptr<CriticalSectionWrapper> crit_sect_;
203   // This member controls the starting and stopping of playing audio to the
204   // the device.
205   bool playing_;
206
207   // Only one thread, T1, may push and only one thread, T2, may pull. T1 may or
208   // may not be the same thread as T2. T1 is the process thread and T2 is the
209   // OpenSL thread.
210   scoped_ptr<SingleRwFifo> fifo_;
211   int num_fifo_buffers_needed_;
212   LowLatencyEvent event_;
213   int number_underruns_;
214
215   // OpenSL handles
216   SLObjectItf sles_engine_;
217   SLEngineItf sles_engine_itf_;
218   SLObjectItf sles_player_;
219   SLPlayItf sles_player_itf_;
220   SLAndroidSimpleBufferQueueItf sles_player_sbq_itf_;
221   SLObjectItf sles_output_mixer_;
222
223   // Audio buffers
224   AudioDeviceBuffer* audio_buffer_;
225   scoped_ptr<FineAudioBuffer> fine_buffer_;
226   scoped_ptr<scoped_ptr<int8_t[]>[]> play_buf_;
227   // Index in |rec_buf_| pointing to the audio buffer that will be ready the
228   // next time PlayerSimpleBufferQueueCallbackHandler is invoked.
229   // Ready means buffer is ready to be played out to device.
230   int active_queue_;
231
232   // Audio settings
233   uint32_t speaker_sampling_rate_;
234   int buffer_size_samples_;
235   int buffer_size_bytes_;
236
237   // Audio status
238   uint16_t playout_delay_;
239 };
240
241 }  // namespace webrtc
242
243 #endif  // WEBRTC_MODULES_AUDIO_DEVICE_ANDROID_OPENSLES_OUTPUT_H_