/*
**
** 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);
    ~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);

protected:
    Mutex           mLock;
    Mutex           mRoutingLock;

    // Track frame position for timestamps, etc.
    int64_t         mFramesRendered;

    // 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.
    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;

    // reduce log spew
    bool            mReportedAvailFail;

    status_t        standbyHardware();
    void            releaseAllOutputs();
    void            updateTargetOutputs();
    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);
};

}  // android
#endif  // ANDROID_AUDIO_STREAM_OUT_H
