/*
**
** 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 "AudioMIO"
#include <utils/Log.h>

#include "android_audio_mio.h"
#include "pvlogger.h"
#include "pv_mime_string_utils.h"
#include "oscl_snprintf.h"
#include "oscl_mem.h"
#include "oscl_dll.h"
#include "oscl_mem.h"

#include <sys/prctl.h>

#include <utils/Timers.h>
#include <sys/resource.h>
#include <limits.h>

#include <utils/threads.h>

#include <media/AudioTrack.h>

using namespace android;

// depth of buffer/command queues in MIO
static const int kCommandQueueDepth = 10;

// Define entry point for this DLL
OSCL_DLL_ENTRY_POINT_DEFAULT()

// Audio Media IO component base class implementation
OSCL_EXPORT_REF AndroidAudioMIO::AndroidAudioMIO(const char* name)
    : OsclTimerObject(OsclActiveObject::EPriorityNominal, name),
    iWriteCompleteAO(NULL)
{
    initData();
}

OSCL_EXPORT_REF AndroidAudioMIO::~AndroidAudioMIO()
{
    LOGV("destructor");
    Cleanup();
}

void AndroidAudioMIO::initData()
{
    LOGV("initData in");
    ResetData();

    iCommandCounter = 0;
    iLogger = NULL;
    iCommandResponseQueue.reserve(kCommandQueueDepth);
    iWriteResponseQueueLock.Create();
    iWriteResponseQueue.reserve(kCommandQueueDepth);
    iObserver = NULL;
    iLogger = NULL;
    iPeer = NULL;
    iState = STATE_MIO_IDLE;
    iWriteBusy = false;
    iFlushPending = false;
    iDataQueued = 0;
    LOGV("initData out");
}

void AndroidAudioMIO::ResetData()
//reset all data from this session.
{
    LOGV("ResetData in");
    // reset all the received media parameters.
    iAudioFormat = PVMF_MIME_FORMAT_UNKNOWN;
    iAudioNumChannelsValid = false;
    iAudioSamplingRateValid = false;
    iAudioThreadCreatedAndMIOConfigured = false;
    LOGV("ResetData out");
}

//cleanup all allocated memory and release resources.
void AndroidAudioMIO::Cleanup()
{
    LOGV("Cleanup in");
    while (!iCommandResponseQueue.empty()) {
        if (iObserver) {
            iObserver->RequestCompleted(PVMFCmdResp(iCommandResponseQueue[0].iCmdId,
                        iCommandResponseQueue[0].iContext, iCommandResponseQueue[0].iStatus));
        }
        iCommandResponseQueue.erase(&iCommandResponseQueue[0]);
    }

    // return empty buffers
    returnAllBuffers();

    // delete the request active object
    if (iWriteCompleteAO) {
        OSCL_DELETE(iWriteCompleteAO);
        iWriteCompleteAO = NULL;
    }
    iWriteResponseQueueLock.Close();
    LOGV("Cleanup out");
}

PVMFStatus AndroidAudioMIO::connect(PvmiMIOSession& aSession, PvmiMIOObserver* aObserver)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidAudioMIO::connect() called"));

    // currently supports only one session
    if (iObserver) return PVMFFailure;
    iObserver = aObserver;
    return PVMFSuccess;
}

PVMFStatus AndroidAudioMIO::disconnect(PvmiMIOSession aSession)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidAudioMIO::disconnect() called"));
    iObserver = NULL;
    return PVMFSuccess;
}


PvmiMediaTransfer* AndroidAudioMIO::createMediaTransfer(PvmiMIOSession& aSession,
                            PvmiKvp* read_formats, int32 read_flags,
                            PvmiKvp* write_formats, int32 write_flags)
{
    // create the request active object
    // such when audio output thread is done with a buffer
    // it can put the buffer on the write response queue
    // and schedule this MIO to run, to return the buffer
    // to the engine
    iWriteCompleteAO = OSCL_NEW(AndroidAudioOutputThreadSafeCallbackAO,(this, 5));

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidAudioMIO::createMediaTransfer() called"));
    return (PvmiMediaTransfer*)this;
}

PVMFCommandId AndroidAudioMIO::QueueCmdResponse(PVMFStatus status, const OsclAny* aContext)
{
    PVMFCommandId cmdId = iCommandCounter++;
    CommandResponse resp(status, cmdId, aContext);
    iCommandResponseQueue.push_back(resp);

    // cancel any timer delay so the command response will happen ASAP.
    if (IsBusy()) Cancel();
    RunIfNotReady();
    return cmdId;
}

// return any held buffers to the engine
void AndroidAudioMIO::ProcessWriteResponseQueue()
{
    //LOGV("ProcessWriteResponseQueue in [Response Q size %d]",iWriteResponseQueue.size());
    PVMFStatus status = 0;
    PVMFCommandId cmdId = 0;
    const OsclAny* context = 0;

    iWriteResponseQueueLock.Lock();
    while (!iWriteResponseQueue.empty()) {
        status = iWriteResponseQueue[0].iStatus;
        cmdId = iWriteResponseQueue[0].iCmdId;
        context = (OsclAny*)iWriteResponseQueue[0].iContext;
        iWriteResponseQueue.erase(&iWriteResponseQueue[0]);
        iWriteResponseQueueLock.Unlock();
        if (iPeer) {
            LOGV("Return buffer(%d) status(%d) context(%p)", cmdId,status,context);
            iPeer->writeComplete(status, cmdId, (OsclAny*)context);
        }
        iWriteResponseQueueLock.Lock();
    }
    iWriteResponseQueueLock.Unlock();
    //LOGV("ProcessWriteResponseQueue out");
}

PVMFCommandId AndroidAudioMIO::QueryUUID(const PvmfMimeString& aMimeType,
                                        Oscl_Vector<PVUuid, OsclMemAllocator>& aUuids,
                                        bool aExactUuidsOnly, const OsclAny* aContext)
{
    LOGV("QueryUUID");
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidAudioMIO::QueryUUID() called"));
    return QueueCmdResponse(PVMFFailure, aContext);
}

PVMFCommandId AndroidAudioMIO::QueryInterface(const PVUuid& aUuid, PVInterface*& aInterfacePtr, const OsclAny* aContext)
{
    LOGV("QueryInterface");
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidAudioMIO::QueryInterface() called"));
    PVMFStatus status=PVMFFailure;
    if (aUuid == PVMI_CAPABILITY_AND_CONFIG_PVUUID) {
        PvmiCapabilityAndConfig* myInterface = OSCL_STATIC_CAST(PvmiCapabilityAndConfig*, this);
        aInterfacePtr = OSCL_STATIC_CAST(PVInterface*, myInterface);
        status = PVMFSuccess;
    }
    return QueueCmdResponse(status, aContext);
}

PVMFCommandId AndroidAudioMIO::Init(const OsclAny* aContext)
{
    LOGV("Init (%p)", aContext);
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidAudioMIO::Init() called"));
    iState=STATE_MIO_INITIALIZED;
    return QueueCmdResponse(PVMFSuccess, aContext);
}

PVMFCommandId AndroidAudioMIO::Reset(const OsclAny* aContext)
{
    LOGV("Reset (%p)", aContext);
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidAudioMIO::Reset() called"));
    return QueueCmdResponse(PVMFSuccess, aContext);
}

PVMFCommandId AndroidAudioMIO::Start(const OsclAny* aContext)
{
    // Start is NO-OP 
    LOGV("Start (%p)", aContext);
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidAudioMIO::Start() called"));
    iState = STATE_MIO_STARTED;
    return QueueCmdResponse(PVMFSuccess, aContext);
}

PVMFCommandId AndroidAudioMIO::Pause(const OsclAny* aContext)
{
    LOGV("Pause (%p)", aContext);
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidAudioMIO::Pause() called"));
    iState = STATE_MIO_PAUSED;
    return QueueCmdResponse(PVMFSuccess, aContext);
}


PVMFCommandId AndroidAudioMIO::Flush(const OsclAny* aContext)
{
    LOGV("Flush (%p)", aContext);
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidAudioMIO::Flush() called"));
    iState = STATE_MIO_INITIALIZED;
    return QueueCmdResponse(PVMFSuccess, aContext);
}

PVMFCommandId AndroidAudioMIO::DiscardData(const OsclAny* aContext)
{
    LOGV("DiscardData (%p)", aContext);
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidAudioMIO::DiscardData() called"));
    return DiscardData(UINT_MAX, aContext);
}

PVMFCommandId AndroidAudioMIO::DiscardData(PVMFTimestamp aTimestamp, const OsclAny* aContext)
{
    LOGV("DiscardData (%u, %p)", aTimestamp, aContext);
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidAudioMIO::DiscardData() called"));
    return QueueCmdResponse(PVMFSuccess, aContext);
}

PVMFCommandId AndroidAudioMIO::Stop(const OsclAny* aContext)
{
    LOGV("Stop (%p)", aContext);
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidAudioMIO::Stop() called"));
    iState = STATE_MIO_INITIALIZED;
    return QueueCmdResponse(PVMFSuccess, aContext);
}

PVMFCommandId AndroidAudioMIO::CancelAllCommands(const OsclAny* aContext)
{
    LOGV("CancelAllCommands (%p)", aContext);
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidAudioMIO::CancelAllCommands() called"));

    //commands are executed immediately upon being received, so
    //it isn't really possible to cancel them.
    return QueueCmdResponse(PVMFSuccess, aContext);
}

PVMFCommandId AndroidAudioMIO::CancelCommand(PVMFCommandId aCmdId, const OsclAny* aContext)
{
    LOGV("CancelCommand (%u, %p)", aCmdId, aContext);
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidAudioMIO::CancelCommand() called"));

    //see if the response is still queued.
    PVMFStatus status = PVMFFailure;
    for (uint32 i = 0; i < iCommandResponseQueue.size(); i++) {
        if (iCommandResponseQueue[i].iCmdId == aCmdId) {
            status = PVMFSuccess;
            break;
        }
    }
    return QueueCmdResponse(PVMFSuccess, aContext);
}

void AndroidAudioMIO::ThreadLogon()
{
    LOGV("ThreadLogon() called ");
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidAudioMIO::ThreadLogon() called"));
    if (iState == STATE_MIO_IDLE) {
        iLogger = PVLogger::GetLoggerObject("AndroidAudioMIO\n");
        AddToScheduler();
        iState=STATE_MIO_LOGGED_ON;
    }
}

void AndroidAudioMIO::ThreadLogoff()
{
    LOGV("ThreadLogoff() called");
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidAudioMIO::ThreadLogoff() called"));
    if (iState!=STATE_MIO_IDLE) {
        RemoveFromScheduler();
        iLogger = NULL;
        iState = STATE_MIO_IDLE;
        ResetData();
    }
}

void AndroidAudioMIO::setPeer(PvmiMediaTransfer* aPeer)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidAudioMIO::setPeer() called"));
    // Set the observer
    iPeer = aPeer;
}

//This routine will determine whether data can be accepted in a writeAsync
//call and if not, will return true;
bool AndroidAudioMIO::CheckWriteBusy(uint32 aSeqNum)
{
    // FIXME: this line screws up video output - why?
    // return (iOSSRequestQueue.size() >= 5);
    return false;
}

PVMFCommandId AndroidAudioMIO::writeAsync(uint8 aFormatType, int32 aFormatIndex, uint8* aData, uint32 aDataLen,
                                        const PvmiMediaXferHeader& data_header_info, OsclAny* aContext)
{
    // Do a leave if MIO is not configured except when it is an EOS
    if (!iAudioThreadCreatedAndMIOConfigured
            &&
            !((PVMI_MEDIAXFER_FMT_TYPE_NOTIFICATION == aFormatType)
              && (PVMI_MEDIAXFER_FMT_INDEX_END_OF_STREAM == aFormatIndex)))
    {
        LOGE("ERROR :: data is pumped in before mio configured");
        OSCL_LEAVE(OsclErrInvalidState);
        return -1;
    }

    uint32 aSeqNum = data_header_info.seq_num;
    PVMFTimestamp aTimestamp = data_header_info.timestamp;
    uint32 flags = data_header_info.flags;

    bool bWriteComplete = true;

    //LOGV("writeAsync() called seqnum %d ts %d flags %d context %d formattype %d formatindex %d",aSeqNum, aTimestamp, flags,aContext,aFormatType,aFormatIndex);
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
        (0,"AndroidAudioMIO::writeAsync() seqnum %d ts %d flags %d context %d",
         aSeqNum, aTimestamp, flags,aContext));

    PVMFStatus status=PVMFFailure;

    switch(aFormatType) {
    case PVMI_MEDIAXFER_FMT_TYPE_COMMAND :
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
            (0,"AndroidAudioMIO::writeAsync() called with Command info."));
        //ignore
        LOGV("PVMI_MEDIAXFER_FMT_TYPE_COMMAND");
        status = PVMFSuccess;
        break;

    case PVMI_MEDIAXFER_FMT_TYPE_NOTIFICATION :
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
            (0,"AndroidAudioMIO::writeAsync() called with Notification info."));
        switch(aFormatIndex) {
        case PVMI_MEDIAXFER_FMT_INDEX_END_OF_STREAM:
            LOGV("PVMI_MEDIAXFER_FMT_INDEX_END_OF_STREAM");
            bWriteComplete = false; //force an empty buffer through the audio thread
            break;
        default:
            break;
        }
        //ignore
        status = PVMFSuccess;
        break;

    case PVMI_MEDIAXFER_FMT_TYPE_DATA :
        switch(aFormatIndex) {
        case PVMI_MEDIAXFER_FMT_INDEX_FMT_SPECIFIC_INFO:
            status = PVMFSuccess;
            LOGV("PVMI_MEDIAXFER_FMT_INDEX_FMT_SPECIFIC_INFO");
            break;

        case PVMI_MEDIAXFER_FMT_INDEX_DATA:
            LOGV("PVMI_MEDIAXFER_FMT_INDEX_DATA");
            //data contains the media bitstream.

            //Check whether we can accept data now and leave if we can't.
            if (CheckWriteBusy(aSeqNum)) {
                PVLOGGER_LOGMSG(PVLOGMSG_INST_REL, iLogger, PVLOGMSG_ERR,
                    (0,"AndroidAudioMIO::writeAsync: Entering busy state"));

                //schedule an event to re-start the data flow.
                iWriteBusy = true;
                bWriteComplete = false;

                // Rich:: commenting in this line.
                //        Need some timeout here just in case.
                //        I have no evidence of any problems.
                RunIfNotReady(10 * 1000);
                OSCL_LEAVE(OsclErrBusy);
            } else {
                if (aDataLen > 0) {
                    // this buffer will be queued by the audio output thread to process
                    // this buffer cannot be write completed until
                    // it has been processed by the audio output thread
                    bWriteComplete = false;
                } else { 
                       LOGE("writeAsync() called with aDataLen==0");
                       PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO,
                            (0,"AndroidAudioMIO::writeAsync() called aDataLen==0."));
                }
                status = PVMFSuccess;
            }
            break;

        default:
            LOGE("Error unrecognized format index =%u", aFormatIndex);
            PVLOGGER_LOGMSG(PVLOGMSG_INST_REL, iLogger, PVLOGMSG_ERR,
                (0,"AndroidAudioMIO::writeAsync: Error - unrecognized format index"));
            status = PVMFFailure;
            break;
        }
        break;

    default:
        LOGE("Error unrecognized format type =%u", aFormatType);
        PVLOGGER_LOGMSG(PVLOGMSG_INST_REL, iLogger, PVLOGMSG_ERR,
            (0,"AndroidAudioMIO::writeAsync: Error - unrecognized format type"));
        status = PVMFFailure;
        break;
    }

    //Schedule asynchronous response
    PVMFCommandId cmdid=iCommandCounter++;
    if (bWriteComplete) {
        LOGV("write complete (%d)", cmdid);
        WriteResponse resp(status, cmdid, aContext, aTimestamp);
        iWriteResponseQueueLock.Lock();
        iWriteResponseQueue.push_back(resp);
        iWriteResponseQueueLock.Unlock();
        RunIfNotReady();
    } else if (!iWriteBusy) {
        writeAudioBuffer(aData, aDataLen, cmdid, aContext, aTimestamp);
    }
    LOGV("data queued = %u", iDataQueued);

    return cmdid;
}

PVMFStatus AndroidAudioMIO::getParametersSync(PvmiMIOSession aSession, PvmiKeyType aIdentifier,
                                              PvmiKvp*& aParameters, int& num_parameter_elements,
                                              PvmiCapabilityContext aContext)
{
    LOGV("getParametersSync in %s",aIdentifier);
    OSCL_UNUSED_ARG(aSession);
    OSCL_UNUSED_ARG(aContext);
    aParameters=NULL;
    num_parameter_elements=0;
    PVMFStatus status = PVMFFailure;

    if(pv_mime_strcmp(aIdentifier, INPUT_FORMATS_CAP_QUERY) == 0) {
        //This is a query for the list of supported formats.
        aParameters=(PvmiKvp*)oscl_malloc(2 * sizeof(PvmiKvp));
        if (aParameters) {
            aParameters[num_parameter_elements++].value.pChar_value = (char*)PVMF_MIME_PCM16;
            aParameters[num_parameter_elements++].value.pChar_value = (char*)PVMF_MIME_PCM8;
            status = PVMFSuccess;
        }
        else{
            status = PVMFErrNoMemory;
        }
    }
    //other queries are not currently supported.

    //unrecognized key.
    LOGV("getParametersSync out status %d",status);
    return status;
}

PVMFStatus AndroidAudioMIO::releaseParameters(PvmiMIOSession aSession, PvmiKvp* aParameters, int num_elements)
{
    LOGV("releaseParameters in");
    OSCL_UNUSED_ARG(aSession);
    OSCL_UNUSED_ARG(num_elements);
    PVMFStatus status = PVMFFailure;
    //release parameters that were allocated by this component.
    if (aParameters) {
        oscl_free(aParameters);
        status = PVMFSuccess;
    }
    LOGV("releaseParameters out status %d",status);
    return status;
}

PVMFStatus AndroidAudioMIO::verifyParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters, int num_elements)
{
    OSCL_UNUSED_ARG(aSession);
    //LOGV("verifyParametersSync in");

    // Go through each parameter
    for (int32 i=0; i<num_elements; i++) {
        char* compstr = NULL;
        pv_mime_string_extract_type(0, aParameters[i].key, compstr);
        if (pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/media/format-type")) == 0) {
            if ((pv_mime_strcmp(aParameters[i].value.pChar_value, PVMF_MIME_PCM8) == 0) ||
                (pv_mime_strcmp(aParameters[i].value.pChar_value, PVMF_MIME_PCM16) == 0)
               ) {
                return PVMFSuccess;
            }
            else {
                return PVMFErrNotSupported;
            }
        }
    }
    return PVMFSuccess;
    //LOGV("verifyParametersSync out");

}
void AndroidAudioMIO::setParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters,
                                        int num_elements, PvmiKvp * & aRet_kvp)
{
    OSCL_UNUSED_ARG(aSession);
    //LOGV("setParametersSync in");
    aRet_kvp = NULL;

    for (int32 i=0;i<num_elements;i++) {
        //Check against known audio parameter keys...
        if (pv_mime_strcmp(aParameters[i].key, MOUT_AUDIO_FORMAT_KEY) == 0) {
            LOGV("Audio format: %s", aParameters[i].value.pChar_value);
            iAudioFormat=aParameters[i].value.pChar_value;
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                (0,"AndroidAudioOutput::setParametersSync() Audio Format Key, Value %s",aParameters[i].value.pChar_value));
        } else if (pv_mime_strcmp(aParameters[i].key, MOUT_AUDIO_SAMPLING_RATE_KEY) == 0) {
            iAudioSamplingRate=(int32)aParameters[i].value.uint32_value;
            iAudioSamplingRateValid=true;
            // LOGD("iAudioSamplingRate=%d", iAudioSamplingRate);
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                (0,"AndroidAudioMIO::setParametersSync() Audio Sampling Rate Key, Value %d",iAudioSamplingRate));
        } else if (pv_mime_strcmp(aParameters[i].key, MOUT_AUDIO_NUM_CHANNELS_KEY) == 0) {
            iAudioNumChannels=(int32)aParameters[i].value.uint32_value;
            iAudioNumChannelsValid=true;
            // LOGD("iAudioNumChannels=%d", iAudioNumChannels);
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                (0,"AndroidAudioMIO::setParametersSync() Audio Num Channels Key, Value %d",iAudioNumChannels));
        } else {
            //if we get here the key is unrecognized.
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                (0,"AndroidAudioMIO::setParametersSync() Error, unrecognized key %s",aParameters[i].key));

            //set the return value to indicate the unrecognized key
            //and return.
            aRet_kvp = &aParameters[i];
            return;
        }
    }

    //LOGV("setParametersSync out");
}

//
// Private section
//

void AndroidAudioMIO::Run()
{
    while (!iCommandResponseQueue.empty()) {
        if (iObserver) {
            iObserver->RequestCompleted(PVMFCmdResp(iCommandResponseQueue[0].iCmdId,
                        iCommandResponseQueue[0].iContext,
                        iCommandResponseQueue[0].iStatus));
        }
        iCommandResponseQueue.erase(&iCommandResponseQueue[0]);
    }

    //send async write completion
    ProcessWriteResponseQueue();

    //Re-start the data transfer if needed.
    if (iWriteBusy) {
        iWriteBusy = false;
        iPeer->statusUpdate(PVMI_MEDIAXFER_STATUS_WRITE);
    }
}

// send response to MIO
void AndroidAudioMIO::sendResponse(PVMFCommandId cmdid, const OsclAny* context, PVMFTimestamp timestamp)
{
    LOGV("sendResponse :: return buffer (%d) timestamp(%d) context(%p)", cmdid, timestamp, context);
    WriteResponse resp(PVMFSuccess, cmdid, context, timestamp);
    iWriteResponseQueueLock.Lock();
    if (iWriteResponseQueue.size() < iWriteResponseQueue.capacity()) {
        iWriteResponseQueue.push_back(resp);
    } else {
        LOGE("Exceeded response queue capacity");
    }
    iWriteResponseQueueLock.Unlock();

    // Create an event for the threadsafe callback AO
    OsclAny* P = NULL;
    iWriteCompleteAO->ReceiveEvent(P);
}

void AndroidAudioMIO::setAudioSink(const sp<MediaPlayerInterface::AudioSink>& audioSink)
{
    LOGV("setAudioSink in");
    mAudioSink = audioSink;
}

//------------------------------------------------------------------------
// Active timing support
//
OSCL_EXPORT_REF PVMFStatus AndroidAudioMIOActiveTimingSupport::SetClock(PVMFMediaClock *clockVal)
{
    LOGV("ATS :: SetClock in");
    iClock=clockVal;
    
    return PVMFSuccess;
}

void AndroidAudioMIOActiveTimingSupport::NotificationsInterfaceDestroyed()
{
    LOGV("ATS :: NotificationsInterfaceDestroyed in");
    iClockNotificationsInf=NULL;
}


OSCL_EXPORT_REF bool AndroidAudioMIOActiveTimingSupport::queryInterface(const PVUuid& aUuid, PVInterface*& aInterface)
{
    aInterface = NULL;
    PVUuid uuid;
    queryUuid(uuid);
    bool status = false;
    if (uuid == aUuid) {
        PvmiClockExtensionInterface* myInterface = OSCL_STATIC_CAST(PvmiClockExtensionInterface*, this);
        aInterface = OSCL_STATIC_CAST(PVInterface*, myInterface);
        status = true;
    }
    LOGV("ATS :: queryInterface out status %d",status);
    return status;
}

void AndroidAudioMIOActiveTimingSupport::queryUuid(PVUuid& uuid)
{
    LOGV("ATS :: queryUuid in");
    uuid = PvmiClockExtensionInterfaceUuid;
}

void AndroidAudioMIOActiveTimingSupport::ClockStateUpdated()
{
    LOGV("ATS :: ClockStateUpdated in");
    if (iClock) {
       
        PVMFMediaClock::PVMFMediaClockState newClockState = iClock->GetState();
        if (newClockState != iClockState) {
            iClockState = newClockState;
            switch (iClockState) {
            case PVMFMediaClock::STOPPED:
                LOGV("A/V clock stopped");
                break;
            case PVMFMediaClock::RUNNING:
                LOGV("A/V clock running");
                // must be seeking, get new clock offset for A/V sync
                if (iUpdateClock) {
                    bool overflowFlag = false;
                    uint32 currentTimeBase32 = 0;
                    iClock->GetCurrentTime32(iStartTime, overflowFlag, PVMF_MEDIA_CLOCK_MSEC, currentTimeBase32);
                    iFrameCount = 0;
                    iUpdateClock = false;
                    LOGV("update iStartTime: %d", iStartTime);
                }
                LOGV("signal thread to start");
                if (iAudioThreadSem) iAudioThreadSem->Signal();
                break;
            case PVMFMediaClock::PAUSED:
                LOGV("A/V clock paused");
                break;
            default:
                LOGE("Wrong clock state!");
                break;
            }
        }
    }
    LOGV("ATS :: ClockStateUpdated out");
}

void AndroidAudioMIOActiveTimingSupport::UpdateClock()
{
    LOGV("ATS :: UpdateClock in");
    if (iClock && (iClockState == PVMFMediaClock::RUNNING)) {
        uint32 clockTime32, timeBaseTime32, updateClock32;
        int32 correction = 0;
        bool overflowFlag = false;
        // get current time
        iClock->GetCurrentTime32(clockTime32, overflowFlag, PVMF_MEDIA_CLOCK_MSEC, timeBaseTime32);
        LOGV("PV clock current = %u", clockTime32);

        // calculate sample clock
        updateClock32 = iFrameCount * iMsecsPerFrame;
        LOGV("sample clock = %u frameCount(%u) msecsPerFrame(%f)", updateClock32,iFrameCount,iMsecsPerFrame);

        correction = updateClock32 - (clockTime32 - iStartTime);
        LOGV("ADJ_CLK iDriverLatency %d old clock %d delta %d", iDriverLatency, clockTime32, correction);

        // do clock correction if drift exceeds threshold
        if (OSCL_ABS(correction) > iMinCorrection) {
            if (correction > iMaxCorrection) {
                correction = iMaxCorrection;
            } else if (correction < -iMaxCorrection) {
                correction = -iMaxCorrection;
            }
            updateClock32 = clockTime32 + correction;
            LOGV("ADJ_CLK old clock %d correction %d new clock %d", clockTime32, correction, updateClock32);

            PVMFMediaClockAdjustTimeStatus adjustmentstatus = 
            iClock->AdjustClockTime32(clockTime32, timeBaseTime32, updateClock32,PVMF_MEDIA_CLOCK_MSEC,overflowFlag);

            if ((PVMF_MEDIA_CLOCK_ADJUST_SUCCESS != adjustmentstatus))
            {
                LOGE("Error adjusting clock status = %d",adjustmentstatus);
            }
            if(overflowFlag) {
            LOGE("Adjusting clock caused overflow");
            }
        }
        else{
            LOGV("ATS :: sample clock and pv clock are close enough no need to update");
        }
    }
    LOGV("ATS :: UpdateClock out");
}
void AndroidAudioMIOActiveTimingSupport::setDriverLatency(uint32 latency)
{
    LOGV("ATS :: setDriverLatency in");
    iDriverLatency = latency;
    if (iClock){
        LOGV("register latency to media clock and set clockobserver");
        PVMFStatus ret = iClock->ConstructMediaClockNotificationsInterface(iClockNotificationsInf,*this,latency);
        if(iClockNotificationsInf && (PVMFSuccess == ret))
        {
            iClockNotificationsInf->SetClockStateObserver(*this);
        }
        else
        {
            LOGE("latency could NOT be set !! set it later ");
        }
    }
    LOGV("ATS :: setDriverLatency out");
}

