C++程序  |  149行  |  5.69 KB

/*
**
** Copyright 2012, 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_STREAM_OUT_H
#define ANDROID_AUDIO_STREAM_OUT_H

#include <stdint.h>
#include <sys/types.h>

#include <common_time/local_clock.h>
#include <hardware/audio.h>
#include <media/AudioParameter.h>

#include "AudioOutput.h"

namespace android {

class AudioHardwareOutput;

class AudioStreamOut {
  public:
    AudioStreamOut(AudioHardwareOutput& owner, bool mcOut, bool isIec958NonAudio);
    ~AudioStreamOut();

    uint32_t            latency() const;
    status_t            getRenderPosition(uint32_t *dspFrames);
    status_t            getPresentationPosition(uint64_t *frames, struct timespec *timestamp);
    status_t            getNextWriteTimestamp(int64_t *timestamp);
    status_t            standby();
    status_t            pause();
    status_t            resume();
    status_t            flush();
    status_t            dump(int fd);

    uint32_t            sampleRate()        const { return mInputSampleRate; }
    uint32_t            outputSampleRate()  const;

    size_t              bufferSize()        const { return mInputBufSize; }
    uint32_t            chanMask()          const { return mInputChanMask; }
    audio_format_t      format()            const { return mInputFormat; }
    uint32_t            framesPerChunk()    const { return mInputChunkFrames; }
    uint32_t            nomChunksInFlight() const { return mInputNominalChunksInFlight; }

    status_t            set(audio_format_t *pFormat,
                            uint32_t       *pChannels,
                            uint32_t       *pRate);
    void                setTgtDevices(uint32_t tgtDevices);

    status_t            setParameters(struct audio_stream *stream,
                                      const char *kvpairs);
    char*               getParameters(const char* keys);
    const char*         getName() const { return mIsMCOutput ? "Multi-channel"
                                                             : "Main"; }

    ssize_t             write(const void* buffer, size_t bytes);

    bool                isIec958NonAudio() const { return mIsIec958NonAudio; }

protected:
    // Lock in this order to avoid deadlock.
    //    mRoutingLock
    //    mPresentationLock

    // Track frame position for timestamps, etc.
    uint64_t        mRenderPosition;  // in frames, increased by write
    uint64_t        mFramesPresented; // increased by write

    // Cache of the last PresentationPosition.
    // This cache is used in case of retrograde timestamps or if the mRoutingLock is held.
    Mutex           mPresentationLock; // protects these mLastPresentation* variables
    uint64_t        mLastPresentationPosition; // frames
    struct timespec mLastPresentationTime;
    bool            mLastPresentationValid;

    // Our HAL, used as the middle-man to collect and trade AudioOutputs.
    AudioHardwareOutput&  mOwnerHAL;

    // Details about the format of the audio we have been configured to receive
    // from audio flinger.
    uint32_t        mInputSampleRate;
    uint32_t        mInputChanMask;
    audio_format_t  mInputFormat;
    uint32_t        mInputNominalChunksInFlight;

    // Handy values pre-computed from the audio configuration.
    uint32_t        mInputBufSize;
    uint32_t        mInputChanCount;
    uint32_t        mInputFrameSize;
    uint32_t        mInputChunkFrames;
    uint32_t        mInputNominalLatencyUSec;
    LinearTransform mLocalTimeToFrames;

    // Bookkeeping used to throttle audio flinger when this audio stream has no
    // actual physical outputs.
    LocalClock      mLocalClock;
    bool            mThrottleValid;
    int64_t         mWriteStartLT;
    int64_t         mFramesWritten; // application rate frames, not device rate frames
    LinearTransform mUSecToLocalTime;

    // State to track which actual outputs are assigned to this output stream.
    Mutex           mRoutingLock; // This protects mPhysOutputs and mTgtDevices
    AudioOutputList mPhysOutputs;
    uint32_t        mTgtDevices;
    bool            mTgtDevicesDirty;
    uint32_t        mAudioFlingerTgtDevices;

    // Flag to track if this StreamOut was created to sink a direct output
    // multichannel stream.
    bool            mIsMCOutput;
    // Is the stream on standby?
    bool            mInStandby;
    // Is the stream compressed audio in SPDIF data bursts?
    const bool      mIsIec958NonAudio;

    // reduce log spew
    bool            mReportedAvailFail;

    status_t        standbyHardware();
    void            releaseAllOutputs(); // locks mRoutingLock
    void            updateTargetOutputs();  // locks mRoutingLock
    void            updateInputNums();
    void            finishedWriteOp(size_t framesWritten, bool needThrottle);
    void            resetThrottle() { mThrottleValid = false; }
    status_t        getNextWriteTimestamp_internal(int64_t *timestamp);
    void            adjustOutputs(int64_t maxTime);
    ssize_t         writeInternal(const void* buffer, size_t bytes);

    // mRoutingLock should be held before calling this.
    status_t        getPresentationPosition_l(uint64_t *frames, struct timespec *timestamp);
};

}  // android
#endif  // ANDROID_AUDIO_STREAM_OUT_H