/*
**
** 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