/*
**
** 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 INCLUDING_FROM_AUDIOFLINGER_H
    #error This header file should only be included from AudioFlinger.h
#endif

// playback track
class Track : public TrackBase, public VolumeProvider {
public:
                        Track(  PlaybackThread *thread,
                                const sp<Client>& client,
                                audio_stream_type_t streamType,
                                uint32_t sampleRate,
                                audio_format_t format,
                                audio_channel_mask_t channelMask,
                                size_t frameCount,
                                const sp<IMemory>& sharedBuffer,
                                int sessionId,
                                IAudioFlinger::track_flags_t flags);
    virtual             ~Track();

    static  void        appendDumpHeader(String8& result);
            void        dump(char* buffer, size_t size);
    virtual status_t    start(AudioSystem::sync_event_t event =
                                    AudioSystem::SYNC_EVENT_NONE,
                             int triggerSession = 0);
    virtual void        stop();
            void        pause();

            void        flush();
            void        destroy();
            int         name() const { return mName; }

            audio_stream_type_t streamType() const {
                return mStreamType;
            }
            status_t    attachAuxEffect(int EffectId);
            void        setAuxBuffer(int EffectId, int32_t *buffer);
            int32_t     *auxBuffer() const { return mAuxBuffer; }
            void        setMainBuffer(int16_t *buffer) { mMainBuffer = buffer; }
            int16_t     *mainBuffer() const { return mMainBuffer; }
            int         auxEffectId() const { return mAuxEffectId; }

// implement FastMixerState::VolumeProvider interface
    virtual uint32_t    getVolumeLR();

    virtual status_t    setSyncEvent(const sp<SyncEvent>& event);

protected:
    // for numerous
    friend class PlaybackThread;
    friend class MixerThread;
    friend class DirectOutputThread;

                        Track(const Track&);
                        Track& operator = (const Track&);

    // AudioBufferProvider interface
    virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer,
                                   int64_t pts = kInvalidPTS);
    // releaseBuffer() not overridden

    virtual size_t framesReady() const;

    bool isPausing() const {
        return mState == PAUSING;
    }
    bool isPaused() const {
        return mState == PAUSED;
    }
    bool isResuming() const {
        return mState == RESUMING;
    }
    bool isReady() const;
    void setPaused() { mState = PAUSED; }
    void reset();

    bool isOutputTrack() const {
        return (mStreamType == AUDIO_STREAM_CNT);
    }

    sp<IMemory> sharedBuffer() const { return mSharedBuffer; }

    // framesWritten is cumulative, never reset, and is shared all tracks
    // audioHalFrames is derived from output latency
    // FIXME parameters not needed, could get them from the thread
    bool presentationComplete(size_t framesWritten, size_t audioHalFrames);

public:
    void triggerEvents(AudioSystem::sync_event_t type);
    void invalidate();
    bool isInvalid() const { return mIsInvalid; }
    virtual bool isTimedTrack() const { return false; }
    bool isFastTrack() const { return (mFlags & IAudioFlinger::TRACK_FAST) != 0; }
    virtual bool isOut() const;

protected:

    // FILLED state is used for suppressing volume ramp at begin of playing
    enum {FS_INVALID, FS_FILLING, FS_FILLED, FS_ACTIVE};
    mutable uint8_t     mFillingUpStatus;
    int8_t              mRetryCount;
    const sp<IMemory>   mSharedBuffer;
    bool                mResetDone;
    const audio_stream_type_t mStreamType;
    int                 mName;      // track name on the normal mixer,
                                    // allocated statically at track creation time,
                                    // and is even allocated (though unused) for fast tracks
                                    // FIXME don't allocate track name for fast tracks
    int16_t             *mMainBuffer;
    int32_t             *mAuxBuffer;
    int                 mAuxEffectId;
    bool                mHasVolumeController;
    size_t              mPresentationCompleteFrames; // number of frames written to the
                                    // audio HAL when this track will be fully rendered
                                    // zero means not monitoring
private:
    IAudioFlinger::track_flags_t mFlags;

    // The following fields are only for fast tracks, and should be in a subclass
    int                 mFastIndex; // index within FastMixerState::mFastTracks[];
                                    // either mFastIndex == -1 if not isFastTrack()
                                    // or 0 < mFastIndex < FastMixerState::kMaxFast because
                                    // index 0 is reserved for normal mixer's submix;
                                    // index is allocated statically at track creation time
                                    // but the slot is only used if track is active
    FastTrackUnderruns  mObservedUnderruns; // Most recently observed value of
                                    // mFastMixerDumpState.mTracks[mFastIndex].mUnderruns
    uint32_t            mUnderrunCount; // Counter of total number of underruns, never reset
    volatile float      mCachedVolume;  // combined master volume and stream type volume;
                                        // 'volatile' means accessed without lock or
                                        // barrier, but is read/written atomically
    bool                mIsInvalid; // non-resettable latch, set by invalidate()
};  // end of Track

class TimedTrack : public Track {
  public:
    static sp<TimedTrack> create(PlaybackThread *thread,
                                 const sp<Client>& client,
                                 audio_stream_type_t streamType,
                                 uint32_t sampleRate,
                                 audio_format_t format,
                                 audio_channel_mask_t channelMask,
                                 size_t frameCount,
                                 const sp<IMemory>& sharedBuffer,
                                 int sessionId);
    virtual ~TimedTrack();

    class TimedBuffer {
      public:
        TimedBuffer();
        TimedBuffer(const sp<IMemory>& buffer, int64_t pts);
        const sp<IMemory>& buffer() const { return mBuffer; }
        int64_t pts() const { return mPTS; }
        uint32_t position() const { return mPosition; }
        void setPosition(uint32_t pos) { mPosition = pos; }
      private:
        sp<IMemory> mBuffer;
        int64_t     mPTS;
        uint32_t    mPosition;
    };

    // Mixer facing methods.
    virtual bool isTimedTrack() const { return true; }
    virtual size_t framesReady() const;

    // AudioBufferProvider interface
    virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer,
                                   int64_t pts);
    virtual void releaseBuffer(AudioBufferProvider::Buffer* buffer);

    // Client/App facing methods.
    status_t    allocateTimedBuffer(size_t size,
                                    sp<IMemory>* buffer);
    status_t    queueTimedBuffer(const sp<IMemory>& buffer,
                                 int64_t pts);
    status_t    setMediaTimeTransform(const LinearTransform& xform,
                                      TimedAudioTrack::TargetTimeline target);

  private:
    TimedTrack(PlaybackThread *thread,
               const sp<Client>& client,
               audio_stream_type_t streamType,
               uint32_t sampleRate,
               audio_format_t format,
               audio_channel_mask_t channelMask,
               size_t frameCount,
               const sp<IMemory>& sharedBuffer,
               int sessionId);

    void timedYieldSamples_l(AudioBufferProvider::Buffer* buffer);
    void timedYieldSilence_l(uint32_t numFrames,
                             AudioBufferProvider::Buffer* buffer);
    void trimTimedBufferQueue_l();
    void trimTimedBufferQueueHead_l(const char* logTag);
    void updateFramesPendingAfterTrim_l(const TimedBuffer& buf,
                                        const char* logTag);

    uint64_t            mLocalTimeFreq;
    LinearTransform     mLocalTimeToSampleTransform;
    LinearTransform     mMediaTimeToSampleTransform;
    sp<MemoryDealer>    mTimedMemoryDealer;

    Vector<TimedBuffer> mTimedBufferQueue;
    bool                mQueueHeadInFlight;
    bool                mTrimQueueHeadOnRelease;
    uint32_t            mFramesPendingInQueue;

    uint8_t*            mTimedSilenceBuffer;
    uint32_t            mTimedSilenceBufferSize;
    mutable Mutex       mTimedBufferQueueLock;
    bool                mTimedAudioOutputOnTime;
    CCHelper            mCCHelper;

    Mutex               mMediaTimeTransformLock;
    LinearTransform     mMediaTimeTransform;
    bool                mMediaTimeTransformValid;
    TimedAudioTrack::TargetTimeline mMediaTimeTransformTarget;
};


// playback track, used by DuplicatingThread
class OutputTrack : public Track {
public:

    class Buffer : public AudioBufferProvider::Buffer {
    public:
        int16_t *mBuffer;
    };

                        OutputTrack(PlaybackThread *thread,
                                DuplicatingThread *sourceThread,
                                uint32_t sampleRate,
                                audio_format_t format,
                                audio_channel_mask_t channelMask,
                                size_t frameCount);
    virtual             ~OutputTrack();

    virtual status_t    start(AudioSystem::sync_event_t event =
                                    AudioSystem::SYNC_EVENT_NONE,
                             int triggerSession = 0);
    virtual void        stop();
            bool        write(int16_t* data, uint32_t frames);
            bool        bufferQueueEmpty() const { return mBufferQueue.size() == 0; }
            bool        isActive() const { return mActive; }
    const wp<ThreadBase>& thread() const { return mThread; }

private:

    enum {
        NO_MORE_BUFFERS = 0x80000001,   // same in AudioTrack.h, ok to be different value
    };

    status_t            obtainBuffer(AudioBufferProvider::Buffer* buffer,
                                     uint32_t waitTimeMs);
    void                clearBufferQueue();

    // Maximum number of pending buffers allocated by OutputTrack::write()
    static const uint8_t kMaxOverFlowBuffers = 10;

    Vector < Buffer* >          mBufferQueue;
    AudioBufferProvider::Buffer mOutBuffer;
    bool                        mActive;
    DuplicatingThread* const mSourceThread; // for waitTimeMs() in write()
    void*                       mBuffers;   // starting address of buffers in plain memory
};  // end of OutputTrack
