/*
**
** Copyright 2008, 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.
*/

//#define LOG_NDEBUG 0
#define LOG_TAG "AudioOutput"
#include <utils/Log.h>

#include "android_audio_output.h"

#include <sys/prctl.h>
#include <sys/resource.h>
#include <utils/threads.h>
#include <media/AudioTrack.h>

using namespace android;

// TODO: dynamic buffer count based on sample rate and # channels
static const int kNumOutputBuffers = 4;

// maximum allowed clock drift before correction
static const int32 kMaxClockDriftInMsecs = 25;    // should be tight enough for reasonable sync
static const int32 kMaxClockCorrection = 100;     // maximum clock correction per update

/*
/ Packet Video Audio MIO component
/
/ This implementation routes audio to AudioFlinger. Audio buffers are
/ enqueued in a message queue to a separate audio output thread. Once
/ the buffers have been successfully written, they are returned through
/ another message queue to the MIO and from there back to the engine.
/ This separation is necessary because most of the PV API is not
/ thread-safe.
*/
OSCL_EXPORT_REF AndroidAudioOutput::AndroidAudioOutput() :
    AndroidAudioMIO("AndroidAudioOutput"),
    iExitAudioThread(false),
    iReturnBuffers(false),
    iActiveTiming(NULL)
{
    LOGV("constructor");
    iClockTimeOfWriting_ns = 0;
    iInputFrameSizeInBytes = 0;

    // semaphore used to communicate between this  mio and the audio output thread
    iAudioThreadSem = new OsclSemaphore();
    iAudioThreadSem->Create(0);
    iAudioThreadTermSem = new OsclSemaphore();
    iAudioThreadTermSem->Create(0);
    iAudioThreadReturnSem = new OsclSemaphore();
    iAudioThreadReturnSem->Create(0);
    iAudioThreadCreatedSem = new OsclSemaphore();
    iAudioThreadCreatedSem->Create(0);

    // locks to access the queues by this mio and by the audio output thread
    iOSSRequestQueueLock.Create();
    iOSSRequestQueue.reserve(iWriteResponseQueue.capacity());

    // create active timing object
    OsclMemAllocator alloc;
    OsclAny*ptr=alloc.allocate(sizeof(AndroidAudioMIOActiveTimingSupport));
    if (ptr) {
        iActiveTiming=new(ptr)AndroidAudioMIOActiveTimingSupport(kMaxClockDriftInMsecs, kMaxClockCorrection);
        iActiveTiming->setThreadSemaphore(iAudioThreadSem);
    }
}

OSCL_EXPORT_REF AndroidAudioOutput::~AndroidAudioOutput()
{
    LOGV("destructor");

    // make sure output thread has exited
    RequestAndWaitForThreadExit();

    // cleanup active timing object
    if (iActiveTiming) {
        iActiveTiming->~AndroidAudioMIOActiveTimingSupport();
        OsclMemAllocator alloc;
        alloc.deallocate(iActiveTiming);
    }

    // clean up some thread interface objects
    iAudioThreadSem->Close();
    delete iAudioThreadSem;
    iAudioThreadTermSem->Close();
    delete iAudioThreadTermSem;
    iAudioThreadReturnSem->Close();
    delete iAudioThreadReturnSem;
    iAudioThreadCreatedSem->Close();
    delete iAudioThreadCreatedSem;

    iOSSRequestQueueLock.Close();
}

PVMFCommandId AndroidAudioOutput::QueryInterface(const PVUuid& aUuid, PVInterface*& aInterfacePtr, const OsclAny* aContext)
{
    LOGV("QueryInterface in");
    // check for active timing extension
    if (iActiveTiming && (aUuid == PvmiClockExtensionInterfaceUuid)) {
        PvmiClockExtensionInterface* myInterface = OSCL_STATIC_CAST(PvmiClockExtensionInterface*,iActiveTiming);
        aInterfacePtr = OSCL_STATIC_CAST(PVInterface*, myInterface);
        return QueueCmdResponse(PVMFSuccess, aContext);
    }

    // pass to base class
    else return AndroidAudioMIO::QueryInterface(aUuid, aInterfacePtr, aContext);
}

PVMFCommandId AndroidAudioOutput::QueryUUID(const PvmfMimeString& aMimeType,
                                        Oscl_Vector<PVUuid, OsclMemAllocator>& aUuids,
                                        bool aExactUuidsOnly, const OsclAny* aContext)
{
    LOGV("QueryUUID in");
    int32 err;
    OSCL_TRY(err,
            aUuids.push_back(PVMI_CAPABILITY_AND_CONFIG_PVUUID);
            if (iActiveTiming) {
            PVUuid uuid;
            iActiveTiming->queryUuid(uuid);
            aUuids.push_back(uuid);
            }
            );
    return QueueCmdResponse(err == OsclErrNone ? PVMFSuccess : PVMFFailure, aContext);
}

PVMFCommandId AndroidAudioOutput::Stop(const OsclAny* aContext)
{
    LOGV("AndroidAudioOutput Stop (%p)", aContext);
    // return all buffer by writecomplete
    returnAllBuffers();
    return AndroidAudioMIO::Stop(aContext);
}

PVMFCommandId AndroidAudioOutput::Reset(const OsclAny* aContext)
{
    LOGV("AndroidAudioOutput Reset (%p)", aContext);
    // return all buffer by writecomplete
    returnAllBuffers();
    // request output thread to exit
    RequestAndWaitForThreadExit();
    return AndroidAudioMIO::Reset(aContext);
}

void AndroidAudioOutput::cancelCommand(PVMFCommandId command_id)
{
    LOGV("cancelCommand (%u) RequestQ size %d", command_id,iOSSRequestQueue.size());
    iOSSRequestQueueLock.Lock();
    for (uint32 i = 0; i < iOSSRequestQueue.size(); i++) {
        if (iOSSRequestQueue[i].iCmdId == command_id) {
            iDataQueued -= iOSSRequestQueue[i].iDataLen;
            if (iPeer)
                iPeer->writeComplete(PVMFSuccess, iOSSRequestQueue[i].iCmdId, (OsclAny*)iOSSRequestQueue[i].iContext);
            iOSSRequestQueue.erase(&iOSSRequestQueue[i]);
            break;
        }
    }
    iOSSRequestQueueLock.Unlock();
    LOGV("cancelCommand data queued = %u", iDataQueued);

    ProcessWriteResponseQueue();
}

void AndroidAudioOutput::returnAllBuffers()
{
    LOGV("returnAllBuffers RequestQ size %d",iOSSRequestQueue.size());
    iOSSRequestQueueLock.Lock();
    while (iOSSRequestQueue.size()) {
        iDataQueued -= iOSSRequestQueue[0].iDataLen;
        if (iPeer)
            iPeer->writeComplete(PVMFSuccess, iOSSRequestQueue[0].iCmdId, (OsclAny*)iOSSRequestQueue[0].iContext);
        iOSSRequestQueue.erase(&iOSSRequestQueue[0]);
    }
    iOSSRequestQueueLock.Unlock();
    LOGV("returnAllBuffers data queued = %u", iDataQueued);
    if (iAudioThreadSem && iAudioThreadCreatedAndMIOConfigured) {
        LOGV("signal thread to return buffers");
        iReturnBuffers = true;
        iAudioThreadSem->Signal();
        while (iAudioThreadReturnSem->Wait() != OsclProcStatus::SUCCESS_ERROR)
            ;
        LOGV("return buffers signal completed");
    }
}


PVMFCommandId AndroidAudioOutput::DiscardData(PVMFTimestamp aTimestamp, const OsclAny* aContext)
{
    LOGV("DiscardData timestamp(%u) RequestQ size %d", aTimestamp,iOSSRequestQueue.size());
   
    if(iActiveTiming){
        LOGV("Force clock update");
        iActiveTiming->ForceClockUpdate();
    }

    bool sched = false;
    PVMFCommandId audcmdid;
    const OsclAny* context;
    PVMFTimestamp timestamp;

    // the OSSRequest queue should be drained
    // all the buffers in them should be returned to the engine
    // writeComplete cannot be called from here
    // thus the best way is to queue the buffers onto the write response queue
    // and then call RunIfNotReady
    iOSSRequestQueueLock.Lock();
    for (int32 i = (iOSSRequestQueue.size() - 1); i >= 0; i--) {
        if (iOSSRequestQueue[i].iTimestamp < aTimestamp) {
            audcmdid = iOSSRequestQueue[i].iCmdId;
            context = iOSSRequestQueue[i].iContext;
            timestamp = iOSSRequestQueue[i].iTimestamp;
            iDataQueued -= iOSSRequestQueue[i].iDataLen;
            LOGV("discard buffer (%d) context(%p) timestamp(%u) Datalen(%d)", audcmdid,context, timestamp,iOSSRequestQueue[i].iDataLen);
            iOSSRequestQueue.erase(&iOSSRequestQueue[i]);
            sched = true;

            WriteResponse resp(PVMFSuccess, audcmdid, context, timestamp);
            iWriteResponseQueueLock.Lock();
            iWriteResponseQueue.push_back(resp);
            iWriteResponseQueueLock.Unlock();
        }
    }
    LOGV("DiscardData data queued = %u, setting flush pending", iDataQueued);
    iFlushPending=true;

    iOSSRequestQueueLock.Unlock();

    if (sched)
        RunIfNotReady();

    return AndroidAudioMIO::DiscardData(aTimestamp, aContext);
}

void AndroidAudioOutput::RequestAndWaitForThreadExit()
{
    LOGV("RequestAndWaitForThreadExit In");
    if (iAudioThreadSem && iAudioThreadCreatedAndMIOConfigured) {
        LOGV("signal thread for exit");
        iExitAudioThread = true;
        iAudioThreadSem->Signal();
        while (iAudioThreadTermSem->Wait() != OsclProcStatus::SUCCESS_ERROR)
            ;
        LOGV("thread term signal received");
        iAudioThreadCreatedAndMIOConfigured = false;
    }
}

void AndroidAudioOutput::setParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters,
                                        int num_elements, PvmiKvp * & aRet_kvp)
{
    LOGV("AndroidAudioOutput setParametersSync In");
    AndroidAudioMIO::setParametersSync(aSession, aParameters, num_elements, aRet_kvp);

    // initialize thread when we have enough information
    if (iAudioSamplingRateValid && iAudioNumChannelsValid && iAudioFormat != PVMF_MIME_FORMAT_UNKNOWN) {
        LOGV("start audio thread");
        OsclThread AudioOutput_Thread;
        iExitAudioThread = false;
        iReturnBuffers = false;
        OsclProcStatus::eOsclProcError ret = AudioOutput_Thread.Create((TOsclThreadFuncPtr)start_audout_thread_func,
                                                    0, (TOsclThreadFuncArg)this, Start_on_creation);

        //Don't signal the MIO node that the configuration is complete until the driver latency has been set
        while (iAudioThreadCreatedSem->Wait() != OsclProcStatus::SUCCESS_ERROR) 
           ;

        if(OsclProcStatus::SUCCESS_ERROR == ret){
            iAudioThreadCreatedAndMIOConfigured = true;
            if(iObserver){
                LOGV("event PVMFMIOConfigurationComplete to peer");
                iObserver->ReportInfoEvent(PVMFMIOConfigurationComplete);
            }
        }
        else{
            iAudioThreadCreatedAndMIOConfigured = false;
            if(iObserver){
                LOGE("event PVMFErrResourceConfiguration to peer");
                iObserver->ReportErrorEvent(PVMFErrResourceConfiguration);
            }
        }
    }
    LOGV("AndroidAudioOutput setParametersSync out");
}

void AndroidAudioOutput::Run()
{
    // if running, update clock
    if ((iState == STATE_MIO_STARTED) && iInputFrameSizeInBytes) {
        uint32 msecsQueued = iDataQueued / iInputFrameSizeInBytes * iActiveTiming->msecsPerFrame();
        LOGV("%u msecs of data queued, %u bytes of data queued", msecsQueued,iDataQueued);
        iActiveTiming->UpdateClock();
    }
    AndroidAudioMIO::Run();
}

void AndroidAudioOutput::writeAudioBuffer(uint8* aData, uint32 aDataLen, PVMFCommandId cmdId, OsclAny* aContext, PVMFTimestamp aTimestamp)
{
    // queue up buffer and signal audio thread to process it
    LOGV("writeAudioBuffer :: DataLen(%d), cmdId(%d), Context(%p), Timestamp (%d)",aDataLen, cmdId, aContext, aTimestamp);
    OSSRequest req(aData, aDataLen, cmdId, aContext, aTimestamp);
    iOSSRequestQueueLock.Lock();
    iOSSRequestQueue.push_back(req);
    iDataQueued += aDataLen;

    // wake up the audio output thread to process this buffer only if clock has started running
    if (iActiveTiming->clockState() == PVMFMediaClock::RUNNING) {
        LOGV("clock is ticking signal thread for data");
        iAudioThreadSem->Signal();
    }
    iOSSRequestQueueLock.Unlock();
}

//------------------------------------------------------------------------
// audio thread
//

#undef LOG_TAG
#define LOG_TAG "audiothread"

// this is the audio output thread
// used to send data to the linux audio output device
// communicates with the audio MIO via a semaphore, a request queue and a response queue
/*static*/ int AndroidAudioOutput::start_audout_thread_func(TOsclThreadFuncArg arg)
{
    LOGV("start_audout_thread_func in");
    AndroidAudioOutput *obj = (AndroidAudioOutput *)arg;
    prctl(PR_SET_NAME, (unsigned long) "audio out", 0, 0, 0);
    int err = obj->audout_thread_func();
    LOGV("start_audout_thread_func out return code %d",err);
    return err;
}

int AndroidAudioOutput::audout_thread_func()
{
    enum { IDLE, STOPPED, STARTED, PAUSED } state = IDLE;
    int64_t lastClock = 0;

    // LOGD("audout_thread_func");

#if defined(HAVE_SCHED_SETSCHEDULER) && defined(HAVE_GETTID)
    setpriority(PRIO_PROCESS, gettid(), ANDROID_PRIORITY_AUDIO);
#endif

    if (iAudioNumChannelsValid == false || iAudioSamplingRateValid == false || iAudioFormat == PVMF_MIME_FORMAT_UNKNOWN) {
        LOGE("channel count or sample rate is invalid");
        return -1;
    }

    LOGV("Creating AudioTrack object: rate=%d, channels=%d, buffers=%d", iAudioSamplingRate, iAudioNumChannels, kNumOutputBuffers);
    status_t ret = mAudioSink->open(iAudioSamplingRate, iAudioNumChannels, ((iAudioFormat==PVMF_MIME_PCM8)?AudioSystem::PCM_8_BIT:AudioSystem::PCM_16_BIT), kNumOutputBuffers);
    iAudioSamplingRateValid = false; // purpose of these flags is over here, reset these for next validation recording.
    iAudioNumChannelsValid  = false;
    iAudioFormat = PVMF_MIME_FORMAT_UNKNOWN;
    if (ret != 0) {
        iAudioThreadCreatedAndMIOConfigured = false;
        LOGE("Error creating AudioTrack");
        return -1;
    }

    // calculate timing data
    int outputFrameSizeInBytes = mAudioSink->frameSize();
    float msecsPerFrame = mAudioSink->msecsPerFrame();
    uint32 latency = mAudioSink->latency();
    LOGV("driver latency(%u),outputFrameSizeInBytes(%d),msecsPerFrame(%f),frame count(%d)", latency,outputFrameSizeInBytes,msecsPerFrame,mAudioSink->frameCount());

    // initialize active timing
    iActiveTiming->setFrameRate(msecsPerFrame);
    iActiveTiming->setDriverLatency(latency);

    iAudioThreadCreatedSem->Signal();
    // this must be set after iActiveTiming->setFrameRate to prevent race
    // condition in Run()
    iInputFrameSizeInBytes = outputFrameSizeInBytes;

    // buffer management
    uint32 bytesAvailInBuffer = 0;
    uint32 bytesToWrite;
    uint32 bytesWritten;
    uint8* data = 0;
    uint32 len = 0;
    PVMFCommandId cmdid = 0;
    const OsclAny* context = 0;
    PVMFTimestamp timestamp = 0;

    // wait for signal from MIO thread
    LOGV("wait for signal");
    iAudioThreadSem->Wait();
    LOGV("ready to work");

    while (1)
    {
        // if paused, stop the output track
        switch (iActiveTiming->clockState()) {
        case PVMFMediaClock::RUNNING:
            // start output
            if (state != STARTED) {
                if (iFlushPending) {
                    LOGV("flush");
                    mAudioSink->flush();
                    iFlushPending = false;
                    bytesAvailInBuffer = 0;
                    iClockTimeOfWriting_ns = 0;
                    // discard partial buffer and send response to MIO
                    if (data && len) {
                        LOGV("discard partial buffer and send response to MIO");
                        sendResponse(cmdid, context, timestamp);
                        data = 0;
                        len = 0;
                    }
                }
                if (iDataQueued || len) {
                    LOGV("start");
                    mAudioSink->start();
                    state = STARTED;
                } else {
                    LOGV("clock running and no data queued - don't start track");
                }
            }
            else{
                LOGV("audio sink already in started state");
            }
            break;
        case PVMFMediaClock::STOPPED:
             LOGV("clock has been stopped...");
        case PVMFMediaClock::PAUSED:
            if (state == STARTED) {
                LOGV("pause");
                mAudioSink->pause();
            }
            state = PAUSED;
            if(!iExitAudioThread && !iReturnBuffers) {
                LOGV("wait");
                iAudioThreadSem->Wait();
                LOGV("awake");
            }
            break;
        default:
            break;
        }
        // if out of data, check the request queue
        if (len == 0) {
            //LOGV("no playable data, Request Q size %d",iOSSRequestQueue.size());
            iOSSRequestQueueLock.Lock();
            bool empty = iOSSRequestQueue.empty();
            if (!empty) {
                data = iOSSRequestQueue[0].iData;
                len = iOSSRequestQueue[0].iDataLen;
                cmdid = iOSSRequestQueue[0].iCmdId;
                context = iOSSRequestQueue[0].iContext;
                timestamp = iOSSRequestQueue[0].iTimestamp;
                iDataQueued -= len;
                iOSSRequestQueue.erase(&iOSSRequestQueue[0]);
                LOGV("receive buffer (%d), timestamp = %u data queued = %u", cmdid, timestamp,iDataQueued);
            }
            iOSSRequestQueueLock.Unlock();

            // if queue is empty, wait for more work
            // FIXME: Why do end up here so many times when stopping?
            if (empty && !iExitAudioThread && !iReturnBuffers) {
                LOGV("queue is empty, wait for more work");
                iAudioThreadSem->Wait();
            }

            // empty buffer means "End-Of-Stream" - send response to MIO
            else if (len == 0) {
                LOGV("EOS");
                state = STOPPED;
                mAudioSink->stop();
                if(!iExitAudioThread){
                    nsecs_t interval_nanosec = 0; // Interval between last writetime and EOS processing time in nanosec
                    nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
                    LOGV("now = %lld ,iClockTimeOfWriting_ns = %lld",now, iClockTimeOfWriting_ns);
                    if(now >= iClockTimeOfWriting_ns){
                        interval_nanosec = now - iClockTimeOfWriting_ns;
                    }
                    else{ //when timevalue wraps
                         interval_nanosec = 0;
                    }
                    LOGV(" I am early,going for sleep for latency = %u millsec, interval_nanosec = %lld",latency, interval_nanosec);
                    struct timespec requested_time_delay, remaining;
                    requested_time_delay.tv_sec = latency/1000; 
                    nsecs_t latency_nanosec = (latency%1000)*1000*1000;
                    if(interval_nanosec < latency_nanosec){
                        requested_time_delay.tv_nsec = latency_nanosec - interval_nanosec;
                        nanosleep (&requested_time_delay, &remaining);
                        LOGV(" Wow, what a great siesta....send response to engine");
                    }
                    else{// interval is greater than latency so no need of sleep
                        LOGV(" No time to sleep :( send response to engine anyways");
                    }
                    iClockTimeOfWriting_ns = 0;
                    sendResponse(cmdid, context, timestamp);
                }
            }
        }

        if (iReturnBuffers) {
            LOGV("Return buffers from the audio thread");
            if (len) sendResponse(cmdid, context, timestamp);
            iReturnBuffers=false;
            data = 0;
            len = 0;
            iAudioThreadReturnSem->Signal();
        }

        // check for exit signal
        if (iExitAudioThread) {
            LOGV("exit received");
            if (len) sendResponse(cmdid, context, timestamp);
            break;
        }

        // data to output?
        if (len && (state == STARTED) && !iExitAudioThread) {

            // always align to AudioFlinger buffer boundary
            if (bytesAvailInBuffer == 0)
                bytesAvailInBuffer = mAudioSink->bufferSize();

                bytesToWrite = bytesAvailInBuffer > len ? len : bytesAvailInBuffer;
                //LOGV("16 bit :: cmdid = %d, len = %u, bytesAvailInBuffer = %u, bytesToWrite = %u", cmdid, len, bytesAvailInBuffer, bytesToWrite);
                bytesWritten = mAudioSink->write(data, bytesToWrite);
                if (bytesWritten != bytesToWrite) {
                    LOGE("Error writing audio data");
                    iAudioThreadSem->Wait();
                }
                data += bytesWritten;
                len -= bytesWritten;
                iClockTimeOfWriting_ns = systemTime(SYSTEM_TIME_MONOTONIC);


            // count bytes sent
            bytesAvailInBuffer -= bytesWritten;

            // update frame count for latency calculation
            iActiveTiming->incFrameCount(bytesWritten / outputFrameSizeInBytes);
            //LOGV("outputFrameSizeInBytes = %u,bytesWritten = %u,bytesAvailInBuffer = %u", outputFrameSizeInBytes,bytesWritten,bytesAvailInBuffer);
            // if done with buffer - send response to MIO
            if (data && !len) {
                LOGV("done with the data cmdid %d, context %p, timestamp %d ",cmdid, context, timestamp);
                sendResponse(cmdid, context, timestamp);
                data = 0;
            }
        }
    } // while loop

    LOGV("stop and delete track");
    mAudioSink->stop();
    iClockTimeOfWriting_ns = 0;

    // LOGD("audout_thread_func exit");
    iAudioThreadTermSem->Signal();

    return 0;
}

