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