C++程序  |  159行  |  5.71 KB

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