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