/* ------------------------------------------------------------------
 * Copyright (C) 2008 PacketVideo
 *
 * 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 "VideoMIO"
#include <utils/Log.h>
#include <ui/ISurface.h>

#include "android_surface_output.h"
#include <media/PVPlayer.h>

#include "pvlogger.h"
#include "pv_mime_string_utils.h"
#include "oscl_snprintf.h"

#include "oscl_dll.h"

// Define entry point for this DLL
OSCL_DLL_ENTRY_POINT_DEFAULT()

//The factory functions.
#include "oscl_mem.h"

using namespace android;

OSCL_EXPORT_REF AndroidSurfaceOutput::AndroidSurfaceOutput() :
    OsclTimerObject(OsclActiveObject::EPriorityNominal, "androidsurfaceoutput")
{
    initData();

    iColorConverter = NULL;
    mInitialized = false;
    mPvPlayer = NULL;
    mEmulation = false;
    iEosReceived = false;
}

status_t AndroidSurfaceOutput::set(PVPlayer* pvPlayer, const sp<ISurface>& surface, bool emulation)
{
    mPvPlayer = pvPlayer;
    mEmulation = emulation;
    setVideoSurface(surface);
    return NO_ERROR;
}

status_t AndroidSurfaceOutput::setVideoSurface(const sp<ISurface>& surface)
{
    LOGV("setVideoSurface(%p)", surface.get());
    // unregister buffers for the old surface
    if (mSurface != NULL) {
        LOGV("unregisterBuffers from old surface");
        mSurface->unregisterBuffers();
    }
    mSurface = surface;
    // register buffers for the new surface
    if ((mSurface != NULL) && (mBufferHeap.heap != NULL)) {
        LOGV("registerBuffers from old surface");
        mSurface->registerBuffers(mBufferHeap);
    }
    return NO_ERROR;
}

void AndroidSurfaceOutput::initData()
{
    iVideoHeight = iVideoWidth = iVideoDisplayHeight = iVideoDisplayWidth = 0;
    iVideoFormat=PVMF_MIME_FORMAT_UNKNOWN;
    resetVideoParameterFlags();

    iCommandCounter=0;
    iLogger=NULL;
    iCommandResponseQueue.reserve(5);
    iWriteResponseQueue.reserve(5);
    iObserver=NULL;
    iLogger=NULL;
    iPeer=NULL;
    iState=STATE_IDLE;
    iIsMIOConfigured = false;
}

void AndroidSurfaceOutput::ResetData()
    //reset all data from this session.
{
    Cleanup();

    //reset all the received media parameters.
    iVideoFormatString="";
    iVideoFormat=PVMF_MIME_FORMAT_UNKNOWN;
    resetVideoParameterFlags();
    iIsMIOConfigured = false;
}

void AndroidSurfaceOutput::resetVideoParameterFlags()
{
    iVideoParameterFlags = VIDEO_PARAMETERS_INVALID;
}

bool AndroidSurfaceOutput::checkVideoParameterFlags()
{
    return (iVideoParameterFlags & VIDEO_PARAMETERS_MASK) == VIDEO_PARAMETERS_VALID;
}

/*
 * process the write response queue by sending writeComplete to the peer
 * (nominally the decoder node).
 *
 * numFramesToHold is the number of frames to be held in the MIO. During
 * playback, we hold the last frame which is used by SurfaceFlinger
 * to composite the final output.
 */
void AndroidSurfaceOutput::processWriteResponseQueue(int numFramesToHold)
{
    LOGV("processWriteResponseQueue: queued = %d, numFramesToHold = %d",
            iWriteResponseQueue.size(), numFramesToHold);
    while (iWriteResponseQueue.size() > numFramesToHold) {
        if (iPeer) {
            iPeer->writeComplete(iWriteResponseQueue[0].iStatus,
                    iWriteResponseQueue[0].iCmdId,
                    (OsclAny*)iWriteResponseQueue[0].iContext);
        }
        iWriteResponseQueue.erase(&iWriteResponseQueue[0]);
    }
}

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

    processWriteResponseQueue(0);

    // We'll close frame buf and delete here for now.
    closeFrameBuf();

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::Cleanup() Out"));
 }

OSCL_EXPORT_REF AndroidSurfaceOutput::~AndroidSurfaceOutput()
{
    Cleanup();
}


PVMFStatus AndroidSurfaceOutput::connect(PvmiMIOSession& aSession, PvmiMIOObserver* aObserver)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::connect() called"));
    // Each Session could have its own set of Configuration parameters
    //in an array of structures and the session ID could be an index to that array.

    //currently supports only one session
    if (iObserver)
        return PVMFFailure;

    iObserver=aObserver;
    return PVMFSuccess;
}


PVMFStatus AndroidSurfaceOutput::disconnect(PvmiMIOSession aSession)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::disconnect() called"));
    //currently supports only one session
    iObserver=NULL;
    return PVMFSuccess;
}


PvmiMediaTransfer* AndroidSurfaceOutput::createMediaTransfer(PvmiMIOSession& aSession, 
                                                        PvmiKvp* read_formats, int32 read_flags,
                                                        PvmiKvp* write_formats, int32 write_flags)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::createMediaTransfer() called"));
    return (PvmiMediaTransfer*)this;
}

void AndroidSurfaceOutput::QueueCommandResponse(CommandResponse& aResp)
{
    //queue a command response and schedule processing.

    iCommandResponseQueue.push_back(aResp);

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

    RunIfNotReady();
}

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

    OSCL_UNUSED_ARG(aMimeType);
    OSCL_UNUSED_ARG(aExactUuidsOnly);

    PVMFCommandId cmdid=iCommandCounter++;

    PVMFStatus status=PVMFFailure;
    int32 err ;
    OSCL_TRY(err, aUuids.push_back(PVMI_CAPABILITY_AND_CONFIG_PVUUID););
    if (err==OsclErrNone)
        status= PVMFSuccess;

    CommandResponse resp(status,cmdid,aContext);
    QueueCommandResponse(resp);
    return cmdid;
}


PVMFCommandId AndroidSurfaceOutput::QueryInterface(const PVUuid& aUuid, PVInterface*& aInterfacePtr, const OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::QueryInterface() called"));

    PVMFCommandId cmdid=iCommandCounter++;

    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;
    }
    else
    {
        status=PVMFFailure;
    }

    CommandResponse resp(status,cmdid,aContext);
    QueueCommandResponse(resp);
    return cmdid;
}


void AndroidSurfaceOutput::deleteMediaTransfer(PvmiMIOSession& aSession, PvmiMediaTransfer* media_transfer)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::deleteMediaTransfer() called"));
    // This class is implementing the media transfer, so no cleanup is needed
}


PVMFCommandId AndroidSurfaceOutput:: Init(const OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::Init() called"));

    PVMFCommandId cmdid=iCommandCounter++;

    PVMFStatus status=PVMFFailure;

    switch(iState)
    {
    case STATE_LOGGED_ON:
        status=PVMFSuccess;
        iState=STATE_INITIALIZED;
        break;

    default:
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::Invalid State"));
        status=PVMFErrInvalidState;
        break;
    }

    CommandResponse resp(status,cmdid,aContext);
    QueueCommandResponse(resp);
    return cmdid;
}

PVMFCommandId AndroidSurfaceOutput::Reset(const OsclAny* aContext)
{
    ResetData();
    PVMFCommandId cmdid=iCommandCounter++;
    CommandResponse resp(PVMFSuccess,cmdid,aContext);
    QueueCommandResponse(resp);
    return cmdid;
}


PVMFCommandId AndroidSurfaceOutput::Start(const OsclAny* aContext)
{
    iEosReceived = false;
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::Start() called"));

    PVMFCommandId cmdid=iCommandCounter++;

    PVMFStatus status=PVMFFailure;

    switch(iState)
    {
    case STATE_INITIALIZED:
    case STATE_PAUSED:

        iState=STATE_STARTED;
        processWriteResponseQueue(0);
        status=PVMFSuccess;
        break;

    default:
        status=PVMFErrInvalidState;
        break;
    }

    CommandResponse resp(status,cmdid,aContext);
    QueueCommandResponse(resp);
    return cmdid;
}

// post the last video frame to refresh screen after pause
void AndroidSurfaceOutput::postLastFrame()
{
    // ignore if no surface or heap
    if ((mSurface == NULL) || (mBufferHeap.heap == NULL)) return;
    mSurface->postBuffer(mFrameBuffers[mFrameBufferIndex]);
}

PVMFCommandId AndroidSurfaceOutput::Pause(const OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::Pause() called"));

    PVMFCommandId cmdid=iCommandCounter++;

    PVMFStatus status=PVMFFailure;

    switch(iState)
    {
    case STATE_STARTED:

        iState=STATE_PAUSED;
        status=PVMFSuccess;

        // post last buffer to prevent stale data
        // if not configured, PVMFMIOConfigurationComplete is not sent
        // there should not be any media data.
    if(iIsMIOConfigured) { 
        postLastFrame();
        }
        break;

    default:
        status=PVMFErrInvalidState;
        break;
    }

    CommandResponse resp(status,cmdid,aContext);
    QueueCommandResponse(resp);
    return cmdid;
}


PVMFCommandId AndroidSurfaceOutput::Flush(const OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::Flush() called"));

    PVMFCommandId cmdid=iCommandCounter++;

    PVMFStatus status=PVMFFailure;

    switch(iState)
    {
    case STATE_STARTED:

        iState=STATE_INITIALIZED;
        status=PVMFSuccess;
        break;

    default:
        status=PVMFErrInvalidState;
        break;
    }

    CommandResponse resp(status,cmdid,aContext);
    QueueCommandResponse(resp);
    return cmdid;
}

PVMFCommandId AndroidSurfaceOutput::DiscardData(const OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::DiscardData() called"));

    PVMFCommandId cmdid=iCommandCounter++;

    //this component doesn't buffer data, so there's nothing
    //needed here.

    PVMFStatus status=PVMFSuccess;
    processWriteResponseQueue(0);

    CommandResponse resp(status,cmdid,aContext);
    QueueCommandResponse(resp);
    return cmdid;
}

PVMFCommandId AndroidSurfaceOutput::DiscardData(PVMFTimestamp aTimestamp, const OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::DiscardData() called"));

    PVMFCommandId cmdid=iCommandCounter++;

    aTimestamp = 0;

    //this component doesn't buffer data, so there's nothing
    //needed here.

    PVMFStatus status=PVMFSuccess;
    processWriteResponseQueue(0);

    CommandResponse resp(status,cmdid,aContext);
    QueueCommandResponse(resp);
    return cmdid;
}

PVMFCommandId AndroidSurfaceOutput::Stop(const OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::Stop() called"));

    PVMFCommandId cmdid=iCommandCounter++;

    PVMFStatus status=PVMFFailure;

    switch(iState)
    {
    case STATE_STARTED:
    case STATE_PAUSED:

#ifdef PERFORMANCE_MEASUREMENTS_ENABLED
        // FIXME: This should be moved to OMAP library
    PVOmapVideoProfile.MarkEndTime();
    PVOmapVideoProfile.PrintStats();
    PVOmapVideoProfile.Reset();
#endif

        iState=STATE_INITIALIZED;
        status=PVMFSuccess;
        break;

    default:
        status=PVMFErrInvalidState;
        break;
    }

    CommandResponse resp(status,cmdid,aContext);
    QueueCommandResponse(resp);
    return cmdid;
}

PVMFCommandId AndroidSurfaceOutput::CancelAllCommands(const OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::CancelAllCommands() called"));

    PVMFCommandId cmdid=iCommandCounter++;

    //commands are executed immediately upon being received, so
    //it isn't really possible to cancel them.

    PVMFStatus status=PVMFSuccess;

    CommandResponse resp(status,cmdid,aContext);
    QueueCommandResponse(resp);
    return cmdid;
}

PVMFCommandId AndroidSurfaceOutput::CancelCommand(PVMFCommandId aCmdId, const OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::CancelCommand() called"));

    PVMFCommandId cmdid=iCommandCounter++;

    //commands are executed immediately upon being received, so
    //it isn't really possible to cancel them.

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

    CommandResponse resp(status,cmdid,aContext);
    QueueCommandResponse(resp);
    return cmdid;
}

void AndroidSurfaceOutput::ThreadLogon()
{
    if(iState==STATE_IDLE)
    {
        iLogger = PVLogger::GetLoggerObject("PVOmapVideo");
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::ThreadLogon() called"));
        AddToScheduler();
        iState=STATE_LOGGED_ON;
    }
}


void AndroidSurfaceOutput::ThreadLogoff()
{   
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::ThreadLogoff() called"));
    
    if(iState!=STATE_IDLE)
    {
        RemoveFromScheduler();
        iLogger=NULL;
        iState=STATE_IDLE;
    }
}


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


void AndroidSurfaceOutput::useMemoryAllocators(OsclMemAllocator* write_alloc)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::useMemoryAllocators() called"));
    //not supported.
}

// This routine will determine whether data can be accepted in a writeAsync
// call and if not, will return true;
bool AndroidSurfaceOutput::CheckWriteBusy(uint32 aSeqNum)
{
    // for all other cases, accept data now.
    return false;
}

PVMFCommandId AndroidSurfaceOutput::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 (!iIsMIOConfigured
            &&
            !((PVMI_MEDIAXFER_FMT_TYPE_NOTIFICATION == aFormatType)
              && (PVMI_MEDIAXFER_FMT_INDEX_END_OF_STREAM == aFormatIndex)))
    {
        LOGE("data is pumped in before MIO is 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;

    if (aSeqNum < 6)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
            (0,"AndroidSurfaceOutput::writeAsync() seqnum %d ts %d context %d",aSeqNum,aTimestamp,aContext));

        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
            (0,"AndroidSurfaceOutput::writeAsync() Format Type %d Format Index %d length %d",aFormatType,aFormatIndex,aDataLen));
    }

    PVMFStatus status=PVMFFailure;

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

    case PVMI_MEDIAXFER_FMT_TYPE_NOTIFICATION :
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
            (0,"AndroidSurfaceOutput::writeAsync() called with Notification info."));
        switch(aFormatIndex)
        {
        case PVMI_MEDIAXFER_FMT_INDEX_END_OF_STREAM:
            iEosReceived = true;
            break;
        default:
            break;
        }
        //ignore
        status= PVMFSuccess;
        break;

    case PVMI_MEDIAXFER_FMT_TYPE_DATA :
        switch(aFormatIndex)
        {
        case PVMI_MEDIAXFER_FMT_INDEX_FMT_SPECIFIC_INFO:
            //format-specific info contains codec headers.
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                (0,"AndroidSurfaceOutput::writeAsync() called with format-specific info."));

            if (iState<STATE_INITIALIZED)
            {
                PVLOGGER_LOGMSG(PVLOGMSG_INST_REL, iLogger, PVLOGMSG_ERR,
                    (0,"AndroidSurfaceOutput::writeAsync: Error - Invalid state"));
                status=PVMFErrInvalidState;
            }
            else
            {
                status= PVMFSuccess;
            }

            break;

        case PVMI_MEDIAXFER_FMT_INDEX_DATA:
            //data contains the media bitstream.

            //Verify the state
            if (iState!=STATE_STARTED)
            {
                PVLOGGER_LOGMSG(PVLOGMSG_INST_REL, iLogger, PVLOGMSG_ERR,
                    (0,"AndroidSurfaceOutput::writeAsync: Error - Invalid state"));
                status=PVMFErrInvalidState;
            }
            else
            {

                //printf("V WriteAsync { seq=%d, ts=%d }\n", data_header_info.seq_num, data_header_info.timestamp);

                // Call playback to send data to IVA for Color Convert
                status = writeFrameBuf(aData, aDataLen, data_header_info);

                PVLOGGER_LOGMSG(PVLOGMSG_INST_REL, iLogger, PVLOGMSG_ERR,
                   (0,"AndroidSurfaceOutput::writeAsync: Playback Progress - frame %d",iFrameNumber++));
            }
            break;

        default:
            PVLOGGER_LOGMSG(PVLOGMSG_INST_REL, iLogger, PVLOGMSG_ERR,
                (0,"AndroidSurfaceOutput::writeAsync: Error - unrecognized format index"));
            status= PVMFFailure;
            break;
        }
        break;

    default:
        PVLOGGER_LOGMSG(PVLOGMSG_INST_REL, iLogger, PVLOGMSG_ERR,
            (0,"AndroidSurfaceOutput::writeAsync: Error - unrecognized format type"));
        status= PVMFFailure;
        break;
    }

    //Schedule asynchronous response
    PVMFCommandId cmdid=iCommandCounter++;
    WriteResponse resp(status,cmdid,aContext,aTimestamp);
    iWriteResponseQueue.push_back(resp);
    RunIfNotReady();

    return cmdid;
}

void AndroidSurfaceOutput::writeComplete(PVMFStatus aStatus, PVMFCommandId  write_cmd_id, OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::writeComplete() called"));
    //won't be called since this component is a sink.
}


PVMFCommandId  AndroidSurfaceOutput::readAsync(uint8* data, uint32 max_data_len, OsclAny* aContext,
                                            int32* formats, uint16 num_formats)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::readAsync() called"));
    //read not supported.
    OsclError::Leave(OsclErrNotSupported);
    return -1;
}


void AndroidSurfaceOutput::readComplete(PVMFStatus aStatus, PVMFCommandId  read_cmd_id, int32 format_index,
                                    const PvmiMediaXferHeader& data_header_info, OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::readComplete() called"));
    //won't be called since this component is a sink.
}


void AndroidSurfaceOutput::statusUpdate(uint32 status_flags)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::statusUpdate() called"));
    //won't be called since this component is a sink.
}


void AndroidSurfaceOutput::cancelCommand(PVMFCommandId  command_id)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::cancelCommand() called"));

    //the purpose of this API is to cancel a writeAsync command and report
    //completion ASAP.

    //in this implementation, the write commands are executed immediately
    //when received so it isn't really possible to cancel.
    //just report completion immediately.
    processWriteResponseQueue(0);
}

void AndroidSurfaceOutput::cancelAllCommands()
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::cancelAllCommands() called"));

    //the purpose of this API is to cancel all writeAsync commands and report
    //completion ASAP.

    //in this implementaiton, the write commands are executed immediately 
    //when received so it isn't really possible to cancel.
    //just report completion immediately.

    for (uint32 i=0;i<iWriteResponseQueue.size();i++)
    {
        //report completion
        if (iPeer)
            iPeer->writeComplete(iWriteResponseQueue[i].iStatus,iWriteResponseQueue[i].iCmdId,(OsclAny*)iWriteResponseQueue[i].iContext);
        iWriteResponseQueue.erase(&iWriteResponseQueue[i]);
    }
}

void AndroidSurfaceOutput::setObserver (PvmiConfigAndCapabilityCmdObserver* aObserver)
{
    OSCL_UNUSED_ARG(aObserver);
    //not needed since this component only supports synchronous capability & config
    //APIs.
}

PVMFStatus AndroidSurfaceOutput::getParametersSync(PvmiMIOSession aSession, PvmiKeyType aIdentifier,
                                              PvmiKvp*& aParameters, int& num_parameter_elements,
                                              PvmiCapabilityContext aContext)
{
    OSCL_UNUSED_ARG(aSession);
    OSCL_UNUSED_ARG(aContext);
    aParameters=NULL;

    // This is a query for the list of supported formats.
    if(pv_mime_strcmp(aIdentifier, INPUT_FORMATS_CAP_QUERY) == 0)
    {
        aParameters=(PvmiKvp*)oscl_malloc(sizeof(PvmiKvp));
        if (aParameters == NULL) return PVMFErrNoMemory;
        aParameters[num_parameter_elements++].value.pChar_value=(char*) PVMF_MIME_YUV420;

        return PVMFSuccess;
    }

    //unrecognized key.
    return PVMFFailure;
}

PVMFStatus AndroidSurfaceOutput::releaseParameters(PvmiMIOSession aSession, PvmiKvp* aParameters, int num_elements)
{
    //release parameters that were allocated by this component.
    if (aParameters)
    {
        oscl_free(aParameters);
        return PVMFSuccess;
    }
    return PVMFFailure;
}

void AndroidSurfaceOutput ::createContext(PvmiMIOSession aSession, PvmiCapabilityContext& aContext)
{
    OsclError::Leave(OsclErrNotSupported);
}

void AndroidSurfaceOutput::setContextParameters(PvmiMIOSession aSession, PvmiCapabilityContext& aContext,
                                           PvmiKvp* aParameters, int num_parameter_elements)
{
    OsclError::Leave(OsclErrNotSupported);
}

void AndroidSurfaceOutput::DeleteContext(PvmiMIOSession aSession, PvmiCapabilityContext& aContext)
{
    OsclError::Leave(OsclErrNotSupported);
}


void AndroidSurfaceOutput::setParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters,
                                        int num_elements, PvmiKvp * & aRet_kvp)
{
    OSCL_UNUSED_ARG(aSession);

    aRet_kvp = NULL;

    LOGV("setParametersSync");
    for (int32 i=0;i<num_elements;i++)
    {
        //Check against known video parameter keys...
        if (pv_mime_strcmp(aParameters[i].key, MOUT_VIDEO_FORMAT_KEY) == 0)
        {
            iVideoFormatString=aParameters[i].value.pChar_value;
            iVideoFormat=iVideoFormatString.get_str();
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                (0,"AndroidSurfaceOutput::setParametersSync() Video Format Key, Value %s",iVideoFormatString.get_str()));
        }
        else if (pv_mime_strcmp(aParameters[i].key, MOUT_VIDEO_WIDTH_KEY) == 0)
        {
            iVideoWidth=(int32)aParameters[i].value.uint32_value;
            iVideoParameterFlags |= VIDEO_WIDTH_VALID;
            LOGV("iVideoWidth=%d", iVideoWidth);
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                (0,"AndroidSurfaceOutput::setParametersSync() Video Width Key, Value %d",iVideoWidth));
        }
        else if (pv_mime_strcmp(aParameters[i].key, MOUT_VIDEO_HEIGHT_KEY) == 0)
        {
            iVideoHeight=(int32)aParameters[i].value.uint32_value;
            iVideoParameterFlags |= VIDEO_HEIGHT_VALID;
            LOGV("iVideoHeight=%d", iVideoHeight);
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                (0,"AndroidSurfaceOutput::setParametersSync() Video Height Key, Value %d",iVideoHeight));
        }
        else if (pv_mime_strcmp(aParameters[i].key, MOUT_VIDEO_DISPLAY_HEIGHT_KEY) == 0)
        {
            iVideoDisplayHeight=(int32)aParameters[i].value.uint32_value;
            iVideoParameterFlags |= DISPLAY_HEIGHT_VALID;
            LOGV("iVideoDisplayHeight=%d", iVideoDisplayHeight);
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                (0,"AndroidSurfaceOutput::setParametersSync() Video Display Height Key, Value %d",iVideoDisplayHeight));
        }
        else if (pv_mime_strcmp(aParameters[i].key, MOUT_VIDEO_DISPLAY_WIDTH_KEY) == 0)
        {
            iVideoDisplayWidth=(int32)aParameters[i].value.uint32_value;
            iVideoParameterFlags |= DISPLAY_WIDTH_VALID;
            LOGV("iVideoDisplayWidth=%d", iVideoDisplayWidth);
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                (0,"AndroidSurfaceOutput::setParametersSync() Video Display Width Key, Value %d",iVideoDisplayWidth));
        }
        else if (pv_mime_strcmp(aParameters[i].key, MOUT_VIDEO_SUBFORMAT_KEY) == 0)
        {
            iVideoSubFormat=aParameters[i].value.pChar_value;
            iVideoParameterFlags |= VIDEO_SUBFORMAT_VALID;
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0,"AndroidSurfaceOutput::setParametersSync() Video SubFormat Key, Value %s",iVideoSubFormat.getMIMEStrPtr()));

LOGV("VIDEO SUBFORMAT SET TO %s\n",iVideoSubFormat.getMIMEStrPtr());
        }
        else
        {
            //if we get here the key is unrecognized.

            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                (0,"AndroidSurfaceOutput::setParametersSync() Error, unrecognized key = %s", aParameters[i].key));

            //set the return value to indicate the unrecognized key
            //and return.
            aRet_kvp = &aParameters[i];
            return;
        }
    }
    uint32 mycache = iVideoParameterFlags ;
    // if initialization is complete, update the app display info
    if( checkVideoParameterFlags() )
    initCheck();
    iVideoParameterFlags = mycache;

    // when all necessary parameters are received, send 
    // PVMFMIOConfigurationComplete event to observer
    if(!iIsMIOConfigured && checkVideoParameterFlags() )
    {
        iIsMIOConfigured = true;
        if(iObserver)
        {
            iObserver->ReportInfoEvent(PVMFMIOConfigurationComplete);
        }
    }
}

PVMFCommandId AndroidSurfaceOutput::setParametersAsync(PvmiMIOSession aSession, PvmiKvp* aParameters,
                                                  int num_elements, PvmiKvp*& aRet_kvp, OsclAny* context)
{
    OsclError::Leave(OsclErrNotSupported);
    return -1;
}

uint32 AndroidSurfaceOutput::getCapabilityMetric (PvmiMIOSession aSession)
{
    return 0;
}

PVMFStatus AndroidSurfaceOutput::verifyParametersSync (PvmiMIOSession aSession, PvmiKvp* aParameters, int num_elements)
{
    OSCL_UNUSED_ARG(aSession);

    // 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_YUV420) == 0) {
                return PVMFSuccess;
            }
            else {
                return PVMFErrNotSupported;
            }
        }
    }
    return PVMFSuccess;
}

//
// Private section
//

void AndroidSurfaceOutput::Run()
{
    //send async command responses
    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
    if (iEosReceived) {
        LOGV("Flushing buffers after EOS");
        processWriteResponseQueue(0);
    } else {
        processWriteResponseQueue(1);
    }
}

// create a frame buffer for software codecs
OSCL_EXPORT_REF bool AndroidSurfaceOutput::initCheck()
{

    // initialize only when we have all the required parameters
    if (!checkVideoParameterFlags())
        return mInitialized;

    // release resources if previously initialized
    closeFrameBuf();

    // reset flags in case display format changes in the middle of a stream
    resetVideoParameterFlags();

    // copy parameters in case we need to adjust them
    int displayWidth = iVideoDisplayWidth;
    int displayHeight = iVideoDisplayHeight;
    int frameWidth = iVideoWidth;
    int frameHeight = iVideoHeight;
    int frameSize;

    // RGB-565 frames are 2 bytes/pixel
    displayWidth = (displayWidth + 1) & -2;
    displayHeight = (displayHeight + 1) & -2;
    frameWidth = (frameWidth + 1) & -2;
    frameHeight = (frameHeight + 1) & -2;
    frameSize = frameWidth * frameHeight * 2;

    // create frame buffer heap and register with surfaceflinger
    sp<MemoryHeapBase> heap = new MemoryHeapBase(frameSize * kBufferCount);
    if (heap->heapID() < 0) {
        LOGE("Error creating frame buffer heap");
        return false;
    }
    
    mBufferHeap = ISurface::BufferHeap(displayWidth, displayHeight,
            frameWidth, frameHeight, PIXEL_FORMAT_RGB_565, heap);
    mSurface->registerBuffers(mBufferHeap);

    // create frame buffers
    for (int i = 0; i < kBufferCount; i++) {
        mFrameBuffers[i] = i * frameSize;
    }

    // initialize software color converter
    iColorConverter = ColorConvert16::NewL();
    iColorConverter->Init(displayWidth, displayHeight, frameWidth, displayWidth, displayHeight, displayWidth, CCROTATE_NONE);
    iColorConverter->SetMemHeight(frameHeight);
    iColorConverter->SetMode(1);

    LOGV("video = %d x %d", displayWidth, displayHeight);
    LOGV("frame = %d x %d", frameWidth, frameHeight);
    LOGV("frame #bytes = %d", frameSize);

    // register frame buffers with SurfaceFlinger
    mFrameBufferIndex = 0;
    mInitialized = true;
    mPvPlayer->sendEvent(MEDIA_SET_VIDEO_SIZE, iVideoDisplayWidth, iVideoDisplayHeight);

    return mInitialized;
}

OSCL_EXPORT_REF PVMFStatus AndroidSurfaceOutput::writeFrameBuf(uint8* aData, uint32 aDataLen, const PvmiMediaXferHeader& data_header_info)
{
    // post to SurfaceFlinger
    if ((mSurface != NULL) && (mBufferHeap.heap != NULL)) {
        if (++mFrameBufferIndex == kBufferCount) mFrameBufferIndex = 0;
        iColorConverter->Convert(aData, static_cast<uint8*>(mBufferHeap.heap->base()) + mFrameBuffers[mFrameBufferIndex]);
        mSurface->postBuffer(mFrameBuffers[mFrameBufferIndex]);
    }
    return PVMFSuccess;
}

OSCL_EXPORT_REF void AndroidSurfaceOutput::closeFrameBuf()
{
    LOGV("closeFrameBuf");
    if (!mInitialized) return;

    mInitialized = false;
    if (mSurface.get()) {
        LOGV("unregisterBuffers");
        mSurface->unregisterBuffers();
    }

    // free frame buffers
    LOGV("free frame buffers");
    for (int i = 0; i < kBufferCount; i++) {
        mFrameBuffers[i] = 0;
    }

    // free heaps
    LOGV("free frame heap");
    mBufferHeap.heap.clear();

    // free color converter
    if (iColorConverter != 0)
    {
        LOGV("free color converter");
        delete iColorConverter;
        iColorConverter = 0;
    }
}

OSCL_EXPORT_REF bool AndroidSurfaceOutput::GetVideoSize(int *w, int *h) {

    *w = iVideoDisplayWidth;
    *h = iVideoDisplayHeight;
    return iVideoDisplayWidth != 0 && iVideoDisplayHeight != 0;
}
