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 MEDIA_AUDIO_ANDROID_OPENSLES_OUTPUT_H_
6 #define MEDIA_AUDIO_ANDROID_OPENSLES_OUTPUT_H_
7 
8 #include <SLES/OpenSLES.h>
9 #include <SLES/OpenSLES_Android.h>
10 #include <stddef.h>
11 #include <stdint.h>
12 
13 #include <memory>
14 
15 #include "base/compiler_specific.h"
16 #include "base/macros.h"
17 #include "base/synchronization/lock.h"
18 #include "base/threading/thread_checker.h"
19 #include "media/audio/android/muteable_audio_output_stream.h"
20 #include "media/audio/android/opensles_util.h"
21 #include "media/base/audio_parameters.h"
22 #include "media/base/audio_timestamp_helper.h"
23 
24 namespace media {
25 
26 class AudioManagerAndroid;
27 
28 // Implements PCM audio output support for Android using the OpenSLES API.
29 // This class is created and lives on the Audio Manager thread but recorded
30 // audio buffers are given to us from an internal OpenSLES audio thread.
31 // All public methods should be called on the Audio Manager thread.
32 class OpenSLESOutputStream : public MuteableAudioOutputStream {
33  public:
34   static const int kMaxNumOfBuffersInQueue = 2;
35 
36   OpenSLESOutputStream(AudioManagerAndroid* manager,
37                        const AudioParameters& params,
38                        SLint32 stream_type);
39 
40   ~OpenSLESOutputStream() override;
41 
42   // Implementation of MuteableAudioOutputStream.
43   bool Open() override;
44   void Close() override;
45   void Flush() override;
46   void Start(AudioSourceCallback* callback) override;
47   void Stop() override;
48   void SetVolume(double volume) override;
49   void GetVolume(double* volume) override;
50 
51   // Set the value of |muted_|. It does not affect |volume_| which can be
52   // got by calling GetVolume(). See comments for |muted_| below.
53   void SetMute(bool muted) override;
54 
55  private:
56   bool CreatePlayer();
57 
58   // Called from OpenSLES specific audio worker thread.
59   static void SimpleBufferQueueCallback(
60       SLAndroidSimpleBufferQueueItf buffer_queue,
61       void* instance);
62 
63   // Fills up one buffer by asking the registered source for data.
64   // Called from OpenSLES specific audio worker thread.
65   void FillBufferQueue();
66 
67   // Called from the audio manager thread.
68   void FillBufferQueueNoLock();
69 
70   // Called in Open();
71   void SetupAudioBuffer();
72 
73   // Called in Close();
74   void ReleaseAudioBuffer();
75 
76   // If OpenSLES reports an error this function handles it and passes it to
77   // the attached AudioOutputCallback::OnError().
78   void HandleError(SLresult error);
79 
80   // Cache |hardware_latency_in_ms_| by asking |audio_manager_| for it, if the
81   // kUseAudioLatencyFromHAL is enabled.
82   void CacheHardwareLatencyIfNeeded();
83 
84   // Adjust |position_in_ms| for hardware latency, and return the result.
85   base::TimeDelta AdjustPositionForHardwareLatency(uint32_t position_in_ms);
86 
87   base::ThreadChecker thread_checker_;
88 
89   // Protects |callback_|, |active_buffer_index_|, |audio_data_|,
90   // |buffer_size_bytes_| and |simple_buffer_queue_|.
91   base::Lock lock_;
92 
93   AudioManagerAndroid* audio_manager_;
94 
95   // Audio playback stream type.
96   // See SLES/OpenSLES_Android.h for details.
97   SLint32 stream_type_;
98 
99   AudioSourceCallback* callback_;
100 
101   // Shared engine interfaces for the app.
102   media::ScopedSLObjectItf engine_object_;
103   media::ScopedSLObjectItf player_object_;
104   media::ScopedSLObjectItf output_mixer_;
105 
106   SLPlayItf player_;
107 
108   // Buffer queue recorder interface.
109   SLAndroidSimpleBufferQueueItf simple_buffer_queue_;
110 
111   SLDataFormat_PCM format_;
112   SLAndroidDataFormat_PCM_EX float_format_;
113 
114   // Audio buffers that are allocated during Open() based on parameters given
115   // during construction.
116   uint8_t* audio_data_[kMaxNumOfBuffersInQueue];
117 
118   int active_buffer_index_;
119 
120   bool started_;
121 
122   // Volume control coming from hardware. It overrides |volume_| when it's
123   // true. Otherwise, use |volume_| for scaling.
124   // This is needed because platform voice volume never goes to zero in
125   // COMMUNICATION mode on Android.
126   bool muted_;
127 
128   // Volume level from 0 to 1.
129   float volume_;
130 
131   int samples_per_second_;
132 
133   // On Android 5.0+ we can output directly to float instead of in integer, so
134   // there we'll use kSampleFormatF32. If not, this will be kSampleFormatS16.
135   SampleFormat sample_format_;
136 
137   int bytes_per_frame_;
138   size_t buffer_size_bytes_;
139 
140   // On API level 25+ we can provide hints to OpenSLES about what type of
141   // content the stream is being used for.
142   SLuint32 performance_mode_;
143 
144   // Used to calculate the delay value for each OnMoreData() call.
145   AudioTimestampHelper delay_calculator_;
146 
147   // Container for retrieving data from AudioSourceCallback::OnMoreData().
148   std::unique_ptr<AudioBus> audio_bus_;
149 
150   // Adjustment for hardware latency.  Needed for some cast targets, since
151   // OpenSLES's GetPosition doesn't properly account for HAL latency.
152   base::TimeDelta hardware_latency_;
153 
154   DISALLOW_COPY_AND_ASSIGN(OpenSLESOutputStream);
155 };
156 
157 }  // namespace media
158 
159 #endif  // MEDIA_AUDIO_ANDROID_OPENSLES_OUTPUT_H_
160