1 /* 2 ** 3 ** Copyright 2014, The Android Open Source Project 4 ** 5 ** Licensed under the Apache License, Version 2.0 (the "License"); 6 ** you may not use this file except in compliance with the License. 7 ** You may obtain a copy of the License at 8 ** 9 ** http://www.apache.org/licenses/LICENSE-2.0 10 ** 11 ** Unless required by applicable law or agreed to in writing, software 12 ** distributed under the License is distributed on an "AS IS" BASIS, 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 ** See the License for the specific language governing permissions and 15 ** limitations under the License. 16 */ 17 18 #ifndef ANDROID_AUDIO_HARDWARE_OUTPUT_H 19 #define ANDROID_AUDIO_HARDWARE_OUTPUT_H 20 21 #include <stdint.h> 22 #include <sys/types.h> 23 24 #include <hardware/audio.h> 25 #include <utils/String8.h> 26 #include <utils/threads.h> 27 28 #include "alsa_utils.h" 29 #include "AudioOutput.h" 30 31 namespace android { 32 33 class AudioStreamOut; 34 class AudioOutput; 35 36 class AudioHardwareOutput { 37 public: 38 AudioHardwareOutput(); 39 virtual ~AudioHardwareOutput(); 40 status_t initCheck(); 41 status_t setMasterVolume(float volume); 42 status_t getMasterVolume(float* volume); 43 status_t setMasterMute(bool mute); 44 status_t getMasterMute(bool* mute); 45 status_t setParameters(const char* kvpairs); 46 char* getParameters(const char* keys); 47 status_t dump(int fd); 48 void updateRouting(uint32_t devMask); 49 uint32_t getMaxDelayCompUsec() const { return mMaxDelayCompUsec; } 50 uint32_t getVideoDelayCompUsec() const { 51 return mSettings.videoDelayCompUsec; 52 } 53 HDMIAudioCaps& getHDMIAudioCaps() { return mHDMIAudioCaps; } 54 55 // Interface to allow streams to obtain and release various physical 56 // outputs. 57 status_t obtainOutput(const AudioStreamOut& tgtStream, 58 uint32_t devMask, 59 sp<AudioOutput>* newOutput); 60 void releaseOutput(const AudioStreamOut& tgtStream, 61 const sp<AudioOutput>& releaseMe); 62 63 64 // create I/O streams 65 AudioStreamOut* openOutputStream(uint32_t devices, 66 audio_format_t *format, 67 uint32_t *channels, 68 uint32_t *sampleRate, 69 audio_output_flags_t flags, 70 status_t *status); 71 void closeOutputStream(AudioStreamOut* out); 72 73 void standbyStatusUpdate(bool isInStandby, bool isMCStream); 74 75 private: 76 struct OutputSettings { 77 bool allowed; 78 uint32_t delayCompUsec; 79 bool isFixed; 80 float fixedLvl; 81 void setDefaults(); 82 }; 83 84 struct Settings { 85 OutputSettings hdmi; 86 uint32_t videoDelayCompUsec; 87 float masterVolume; 88 bool masterMute; 89 void setDefaults(); 90 }; 91 92 void updateTgtDevices_l(); 93 bool applyOutputSettings_l(const OutputSettings& initial, 94 const OutputSettings& current, 95 OutputSettings& updateMe, 96 uint32_t outDevMask); 97 98 // Notes on locking: 99 // There are 3 locks in the AudioHardware class; mStreamLock, mOutputLock 100 // and mSettingsLock. 101 // 102 // mStreamLock is held when interacting with AudioStreamOuts, in particular 103 // during creation and destruction of streams, and during routing changes 104 // (HDMI connecting and disconnecting) which (potentially) end up effecting 105 // the target device masks of the output streams. 106 // 107 // mOutputLock is held while interacting with AudioOutputs (which represent 108 // the physical outputs of the system). AudioStreamOuts grab this lock 109 // during calls to (obtain|release)Output which can trigger instantiation 110 // and destruction of AudioOutputs. During this operation, the 111 // AudioStreamOut instance will be holding its own "routing" lock. Care 112 // should be taken to never hold the output lock or setting lock while making 113 // a call into an AudioStreamOut which may obtain the routing lock. 114 // Currently, the set of publicly accessible calls in AudioStreamOut which 115 // may obtain the routing lock are... 116 // 1) ~AudioStreamOut (calls releaseAllOutputs) 117 // 2) standby (calls releaseAllOutputs) 118 // 3) pause (calls releaseAllOutputs) 119 // 4) setTgtDevices 120 // 5) getPresentationPosition 121 // 6) write 122 // 123 // mSettingsLock is held while reading settings and while writing/applying 124 // settings to existing outputs. Lock ordering is important when applying 125 // settings to outputs as the both the output and settings lock need to be 126 // held at the same time. Whenever settings need to be applied to outputs, 127 // the output lock should always obtained first, followed by the settings 128 // lock. 129 130 Mutex mStreamLock; 131 AudioStreamOut *mMainOutput; 132 AudioStreamOut *mMCOutput; 133 bool mHDMIConnected; 134 135 Mutex mOutputLock; 136 AudioOutputList mPhysOutputs; 137 138 Mutex mSettingsLock; 139 Settings mSettings; 140 uint32_t mMaxDelayCompUsec; 141 142 HDMIAudioCaps mHDMIAudioCaps; 143 int mHDMICardID; 144 145 static const String8 kHDMIAllowedParamKey; 146 static const String8 kHDMIDelayCompParamKey; 147 static const String8 kFixedHDMIOutputParamKey; 148 static const String8 kFixedHDMIOutputLevelParamKey; 149 static const String8 kVideoDelayCompParamKey; 150 static const float kDefaultMasterVol; 151 152 }; 153 154 // ---------------------------------------------------------------------------- 155 156 }; // namespace android 157 158 #endif // ANDROID_AUDIO_HARDWARE_OUTPUT_H 159