/* ** ** Copyright 2014, The Android Open Source Project ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. ** You may obtain a copy of the License at ** ** http://www.apache.org/licenses/LICENSE-2.0 ** ** Unless required by applicable law or agreed to in writing, software ** distributed under the License is distributed on an "AS IS" BASIS, ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the License for the specific language governing permissions and ** limitations under the License. */ #ifndef ANDROID_AUDIO_HARDWARE_OUTPUT_H #define ANDROID_AUDIO_HARDWARE_OUTPUT_H #include <stdint.h> #include <sys/types.h> #include <hardware/audio.h> #include <utils/String8.h> #include <utils/threads.h> #include "alsa_utils.h" #include "AudioOutput.h" namespace android { class AudioStreamOut; class AudioOutput; class AudioHardwareOutput { public: AudioHardwareOutput(); virtual ~AudioHardwareOutput(); status_t initCheck(); status_t setMasterVolume(float volume); status_t getMasterVolume(float* volume); status_t setMasterMute(bool mute); status_t getMasterMute(bool* mute); status_t setParameters(const char* kvpairs); char* getParameters(const char* keys); status_t dump(int fd); void updateRouting(uint32_t devMask); uint32_t getMaxDelayCompUsec() const { return mMaxDelayCompUsec; } uint32_t getVideoDelayCompUsec() const { return mSettings.videoDelayCompUsec; } HDMIAudioCaps& getHDMIAudioCaps() { return mHDMIAudioCaps; } // Interface to allow streams to obtain and release various physical // outputs. status_t obtainOutput(const AudioStreamOut& tgtStream, uint32_t devMask, sp<AudioOutput>* newOutput); void releaseOutput(const AudioStreamOut& tgtStream, const sp<AudioOutput>& releaseMe); // create I/O streams AudioStreamOut* openOutputStream(uint32_t devices, audio_format_t *format, uint32_t *channels, uint32_t *sampleRate, audio_output_flags_t flags, status_t *status); void closeOutputStream(AudioStreamOut* out); void standbyStatusUpdate(bool isInStandby, bool isMCStream); private: struct OutputSettings { bool allowed; uint32_t delayCompUsec; bool isFixed; float fixedLvl; void setDefaults(); }; struct Settings { OutputSettings hdmi; uint32_t videoDelayCompUsec; float masterVolume; bool masterMute; void setDefaults(); }; void updateTgtDevices_l(); bool applyOutputSettings_l(const OutputSettings& initial, const OutputSettings& current, OutputSettings& updateMe, uint32_t outDevMask); // Notes on locking: // There are 3 locks in the AudioHardware class; mStreamLock, mOutputLock // and mSettingsLock. // // mStreamLock is held when interacting with AudioStreamOuts, in particular // during creation and destruction of streams, and during routing changes // (HDMI connecting and disconnecting) which (potentially) end up effecting // the target device masks of the output streams. // // mOutputLock is held while interacting with AudioOutputs (which represent // the physical outputs of the system). AudioStreamOuts grab this lock // during calls to (obtain|release)Output which can trigger instantiation // and destruction of AudioOutputs. During this operation, the // AudioStreamOut instance will be holding its own "routing" lock. Care // should be taken to never hold the output lock or setting lock while making // a call into an AudioStreamOut which may obtain the routing lock. // Currently, the set of publicly accessible calls in AudioStreamOut which // may obtain the routing lock are... // 1) ~AudioStreamOut (calls releaseAllOutputs) // 2) standby (calls releaseAllOutputs) // 3) pause (calls releaseAllOutputs) // 4) setTgtDevices // 5) getPresentationPosition // 6) write // // mSettingsLock is held while reading settings and while writing/applying // settings to existing outputs. Lock ordering is important when applying // settings to outputs as the both the output and settings lock need to be // held at the same time. Whenever settings need to be applied to outputs, // the output lock should always obtained first, followed by the settings // lock. Mutex mStreamLock; AudioStreamOut *mMainOutput; AudioStreamOut *mMCOutput; bool mHDMIConnected; Mutex mOutputLock; AudioOutputList mPhysOutputs; Mutex mSettingsLock; Settings mSettings; uint32_t mMaxDelayCompUsec; HDMIAudioCaps mHDMIAudioCaps; int mHDMICardID; static const String8 kHDMIAllowedParamKey; static const String8 kHDMIDelayCompParamKey; static const String8 kFixedHDMIOutputParamKey; static const String8 kFixedHDMIOutputLevelParamKey; static const String8 kVideoDelayCompParamKey; static const float kDefaultMasterVol; }; // ---------------------------------------------------------------------------- }; // namespace android #endif // ANDROID_AUDIO_HARDWARE_OUTPUT_H