/* ------------------------------------------------------------------
 * Copyright (C) 1998-2009 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.
 * -------------------------------------------------------------------
 */
/**
 * @file pvmf_media_input_node_outport.cpp
 * @brief Output port for media io interface wrapper node
 */

#ifndef PVMF_MEDIA_INPUT_NODE_OUTPORT_H_INCLUDED
#include "pvmf_media_input_node_outport.h"
#endif
#ifndef PVMF_MEDIA_INPUT_NODE_H_INCLUDED
#include "pvmf_media_input_node.h"
#endif
#ifndef PVMF_FORMAT_TYPE_H_INCLUDED
#include "pvmf_format_type.h"
#endif

#ifndef PVMF_MEDIA_MSG_FORMAT_IDS_H_INCLUDED
#include "pvmf_media_msg_format_ids.h"
#endif
#ifndef PVMF_MEDIA_CMD_H_INCLUDED
#include "pvmf_media_cmd.h"
#endif

#define PVMIO_MEDIADATA_POOLNUM 9

// Logging macros
#define LOG_STACK_TRACE(m) PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, m);
#define LOG_DEBUG(m) PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, m);
#define LOG_ERR(m) PVLOGGER_LOGMSG(PVLOGMSG_INST_REL,iLogger,PVLOGMSG_ERR,m);
#define LOGDATATRAFFIC(m) PVLOGGER_LOGMSG(PVLOGMSG_INST_REL,iDataPathLogger,PVLOGMSG_INFO,m);

////////////////////////////////////////////////////////////////////////////
PvmfMediaInputNodeOutPort::PvmfMediaInputNodeOutPort(PvmfMediaInputNode* aNode, const char* aName)
        : OsclTimerObject(OsclActiveObject::EPriorityNominal, "PvmfMediaInputNodeOutPort")
        , PvmfPortBaseImpl(PVMF_MEDIAIO_NODE_OUTPUT_PORT_TAG
                           //this port handles its own port activity
                           , this, aName)
        , iNode(aNode)
        , iState(PvmfMediaInputNodeOutPort::PORT_STATE_BUFFERING)
        , inum_text_sample(0)
        , imax_num_sample(0)
{
    iCmdId = 0;
    AddToScheduler();
    iFormatType = PVMF_MIME_FORMAT_UNKNOWN;
    iPeer = NULL;
    iWriteState = EWriteOK;
    iMediaDataAllocMemPool = OSCL_NEW(OsclMemPoolFixedChunkAllocator, (PVMIO_MEDIADATA_POOLNUM));
    iMediaDataMemPool = OSCL_NEW(OsclMemPoolFixedChunkAllocator, (PVMIO_MEDIADATA_POOLNUM));
    iMediaDataAlloc = OSCL_NEW(PvmfMediaInputDataBufferAlloc, (iMediaDataAllocMemPool));
    iDataPathLogger = PVLogger::GetLoggerObject("datapath.sourcenode");

    iPrivateDataFsiFragmentAlloc.size(32, sizeof(OsclAny *)); //TODO REMOVE THE HARDCODED VALUE
#ifdef _TEST_AE_EROR_HANDLING
    iTimeStampJunk = 0x000FFFFF;
#endif
}

////////////////////////////////////////////////////////////////////////////
PvmfMediaInputNodeOutPort::~PvmfMediaInputNodeOutPort()
{
    PvmfPortBaseImpl::ClearMsgQueues();


    if (iMediaDataAlloc != NULL)
    {
        OSCL_DELETE(iMediaDataAlloc);
    }

    if (iMediaDataAllocMemPool)
    {
        iMediaDataAllocMemPool->removeRef();
    }

    if (iMediaDataMemPool)
    {
        iMediaDataMemPool->removeRef();
    }
    iDataPathLogger = NULL;

    // we need to clear the activity handler, since otherwise the PvmfPortBaseImpl destructor
    // ends up calling back onto our HandlePortActivity method, which no longer exists because
    // this objects's destructor has already been called.
    SetActivityHandler(NULL);
}

////////////////////////////////////////////////////////////////////////////
void PvmfMediaInputNodeOutPort::Start()
{
    iWriteState = EWriteOK;
#ifdef _TEST_AE_ERROR_HANDLING

    if (iNode->iError_Out_Queue_Busy)
    {
        PvmfPortBaseImpl::SetCapacity(EPVIncomingDataQueue, 0);
        PvmfPortBaseImpl::SetReserve(EPVIncomingDataQueue, 0);
        PvmfPortBaseImpl::SetThreshold(EPVIncomingDataQueue, 0);
        PvmfPortBaseImpl::SetCapacity(EPVOutgoingDataQueue, 1);
        PvmfPortBaseImpl::SetReserve(EPVOutgoingDataQueue, 2);
        PvmfPortBaseImpl::SetThreshold(EPVOutgoingDataQueue, 100);
    }
    else
    {
        PvmfPortBaseImpl::SetCapacity(EPVIncomingDataQueue, 0);
        PvmfPortBaseImpl::SetReserve(EPVIncomingDataQueue, 0);
        PvmfPortBaseImpl::SetThreshold(EPVIncomingDataQueue, 0);
        PvmfPortBaseImpl::SetCapacity(EPVOutgoingDataQueue, 10);
        PvmfPortBaseImpl::SetReserve(EPVOutgoingDataQueue, 10);
        PvmfPortBaseImpl::SetThreshold(EPVOutgoingDataQueue, 70);
    }
#else
    PvmfPortBaseImpl::SetCapacity(EPVIncomingDataQueue, 0);
    PvmfPortBaseImpl::SetReserve(EPVIncomingDataQueue, 0);
    PvmfPortBaseImpl::SetThreshold(EPVIncomingDataQueue, 0);
    PvmfPortBaseImpl::SetCapacity(EPVOutgoingDataQueue, 10);
    PvmfPortBaseImpl::SetReserve(EPVOutgoingDataQueue, 10);
    PvmfPortBaseImpl::SetThreshold(EPVOutgoingDataQueue, 70);

#endif
    iState = PvmfMediaInputNodeOutPort::PORT_STATE_STARTED;
    if (iNode->iMediaIOState == PvmfMediaInputNode::MIO_STATE_STARTED)
    {
        RunIfNotReady();
    }
}

////////////////////////////////////////////////////////////////////////////
void PvmfMediaInputNodeOutPort::MediaIOStarted()
{
    if (iState == PvmfMediaInputNodeOutPort::PORT_STATE_STARTED)
        RunIfNotReady();
}

////////////////////////////////////////////////////////////////////////////
void PvmfMediaInputNodeOutPort::Pause()
{
    iState = PvmfMediaInputNodeOutPort::PORT_STATE_BUFFERING;
}

////////////////////////////////////////////////////////////////////////////
void PvmfMediaInputNodeOutPort::Stop()
{
    iWriteState = EWriteOK;
    PvmfPortBaseImpl::ClearMsgQueues();
    iState = PvmfMediaInputNodeOutPort::PORT_STATE_STOPPED;
}

////////////////////////////////////////////////////////////////////////////
PVMFStatus PvmfMediaInputNodeOutPort::Configure(PVMFFormatType aPortProperty,
        OSCL_String* aMime)
{
    if (iConnectedPort)
    {
        // Must disconnect before changing port properties, so return error
        return PVMFFailure;
    }

    iFormatType = aPortProperty;
    iMimeType = *aMime;
    return PVMFSuccess;
}

////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF PVMFStatus PvmfMediaInputNodeOutPort::Connect(PVMFPortInterface* aPort)
{
    PVMFStatus status = PvmfPortBaseImpl::Connect(aPort);
    if (status != PVMFSuccess)
        return status;

    iMediaInput = iNode->iMediaIOControl->createMediaTransfer(iNode->iMediaIOSession);
    if (iMediaInput)
        iMediaInput->setPeer(this);
    else
        return PVMFFailure;

    return PVMFSuccess;
}

////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF PVMFStatus PvmfMediaInputNodeOutPort::PeerConnect(PVMFPortInterface* aPort)
{
    PVMFStatus status = PvmfPortBaseImpl::PeerConnect(aPort);
    if (status != PVMFSuccess)
        return status;

    iMediaInput = iNode->iMediaIOControl->createMediaTransfer(iNode->iMediaIOSession);
    if (iMediaInput)
        iMediaInput->setPeer(this);
    else
        return PVMFFailure;

    return PVMFSuccess;
}

////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF PVMFStatus PvmfMediaInputNodeOutPort::Disconnect()
{
    PVMFStatus status = PvmfPortBaseImpl::Disconnect();
    if (status != PVMFSuccess)
        return status;

    iNode->iMediaIOControl->deleteMediaTransfer(iNode->iMediaIOSession, iMediaInput);
    if (iMediaInput)
        iMediaInput->setPeer(0);
    return PVMFSuccess;
}

////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF PVMFStatus PvmfMediaInputNodeOutPort::PeerDisconnect()
{
    PVMFStatus status = PvmfPortBaseImpl::PeerDisconnect();
    if (status != PVMFSuccess)
        return status;

    if (iMediaInput)
        iMediaInput->setPeer(0);
    iNode->iMediaIOControl->deleteMediaTransfer(iNode->iMediaIOSession, iMediaInput);
    return PVMFSuccess;
}

////////////////////////////////////////////////////////////////////////////
void PvmfMediaInputNodeOutPort::setPeer(PvmiMediaTransfer *aPeer)
{
    iPeer = aPeer;
}

////////////////////////////////////////////////////////////////////////////
void PvmfMediaInputNodeOutPort::useMemoryAllocators(OsclMemAllocator* write_alloc)
{
    OSCL_UNUSED_ARG(write_alloc);
    OSCL_LEAVE(OsclErrNotSupported);
}

////////////////////////////////////////////////////////////////////////////
PVMFCommandId PvmfMediaInputNodeOutPort::writeAsync(uint8 format_type, int32 format_index,
        uint8* data, uint32 data_len,
        const PvmiMediaXferHeader& data_header_info,
        OsclAny* context)
{
    if (iState == PvmfMediaInputNodeOutPort::PORT_STATE_STOPPED)
    {
        // In Stopped state we are not going to accept any buffers
        OsclError::Leave(OsclErrNotReady);
        LOG_DEBUG((0, "Ignoring PvmfMediaInputNodeOutPort::writeAsync"));
        return -1;
    }
    if (iWriteState == EWriteOK)
    {
        if (PVMI_MEDIAXFER_FMT_TYPE_NOTIFICATION == format_type)
        {
            switch (format_index)
            {
                    //added for timed text support
                    //here it handles the configuration information for timed text and passes it to the composernode

                case PVMI_MEDIAXFER_FMT_INDEX_FMT_SPECIFIC_INFO:
                {
                    //we expect media input components to use cap-config to provide
                    //fmt specific info
                    LOG_ERR((0, "Fmt Specific Info over WriteAsync Not Supported"));
                    iNode->ReportErrorEvent(PVMFErrPortProcessing, (OsclAny*)NULL);
                    OsclError::Leave(OsclErrGeneral);
                }
                break;
                case PVMI_MEDIAXFER_FMT_INDEX_END_OF_STREAM:
                {

                    SendEndOfTrackCommand(data_header_info);
                    MediaIOStarted();

                    return iCmdId++;
                }
                break;
                default:
                {
                    LOG_ERR((0, "Ignoring Format Index :%d since not supported\n", format_index));

                    iNode->ReportErrorEvent(PVMFErrPortProcessing, (OsclAny*)NULL);
                    OsclError::Leave(OsclErrGeneral);

                }
                break;
            }

        }

        // TODO: Handle incoming data here. Create a media data using PvmiMIOSourceDataBufferAlloc::allocate,
        // save the data there, put the media data to outgoing queue.
        // If the port is started, schedule to send in Run

        else if (PVMI_MEDIAXFER_FMT_TYPE_DATA == format_type)
        {
            //if the outgoing queue is full, we can't accept data
            //now.

            if (IsOutgoingQueueBusy())
            {
                iWriteState = EWriteBusy;
                OsclError::Leave(OsclErrBusy);
            }

            // Create new media data buffer
            PVMFSharedMediaDataPtr mediaData;
            int32 err = 0;

            if (iCmdId == 0x7FFFFFFF)
                iCmdId = 0;
#ifdef _TEST_AE_ERROR_HANDLING

            if (data_header_info.stream_id == iNode->iTrackID)
            {
                uint32 ii = 0;
                while (iNode->iChunkCount > 0)
                {
                    uint32 sz = data_len - 5;

                    for (ii = 0; ii <= sz; ii++)
                    {
                        uint8* ptr = data + ii;
                        *ptr = 0;
                    }

                    iNode->iChunkCount--;
                }

            }
#endif
#ifdef _TEST_AE_ERROR_HANDLING
            if (iNode->iError_No_Memory)
            {
                err = OsclErrBusy;
                if (IsAdded())
                {
                    RunIfNotReady();
                }
            }
            else
            {
                OSCL_TRY(err,
                         OsclSharedPtr<PVMFMediaDataImpl> mediaDataImpl = iMediaDataAlloc->allocate(iMediaInput, data,
                                 data_len, iCmdId, context);
                         mediaData = PVMFMediaData::createMediaData(mediaDataImpl, iMediaDataMemPool););
            }
#else
            OSCL_TRY(err,
                     OsclSharedPtr<PVMFMediaDataImpl> mediaDataImpl = iMediaDataAlloc->allocate(iMediaInput, data,
                             data_len, iCmdId, context);
                     mediaData = PVMFMediaData::createMediaData(mediaDataImpl, iMediaDataMemPool););


#endif
            if (err)
            {
                iMediaDataAllocMemPool->notifyfreechunkavailable(*this);
                iWriteState = EWriteBusy;
                OsclError::Leave(OsclErrBusy);
            }
            // Set timestamp
#ifdef _TEST_AE_ERROR_HANDLING

            if ((data_header_info.stream_id == iNode->iErrorTimeStamp.track_no) && (1 == iNode->iErrorTimeStamp.mode))
            {

                if (iTimeStampJunk == 0)
                {
                    iTimeStampJunk = 0x000FFFFF;
                }

                mediaData->setTimestamp(iTimeStampJunk);
                iTimeStampJunk = iTimeStampJunk - 33;
            }
            else if ((data_header_info.stream_id == iNode->iErrorTimeStamp.track_no) && (2 == iNode->iErrorTimeStamp.mode))
            {
                if (data_header_info.timestamp >= iNode->iErrorTimeStamp.duration)
                {
                    mediaData->setTimestamp(0);
                }
            }
            else if ((data_header_info.stream_id == iNode->iErrorTimeStamp.track_no) && (3 == iNode->iErrorTimeStamp.mode))
            {
                mediaData->setTimestamp(0);
            }
            else
            {
                mediaData->setTimestamp(data_header_info.timestamp);
            }
#else
            mediaData->setTimestamp(data_header_info.timestamp);
#endif
            mediaData->setSeqNum(data_header_info.seq_num);
            mediaData->setMediaFragFilledLen(0, data_len);
            mediaData->setStreamID(data_header_info.stream_id);

            PVMFStatus status = PVMFFailure;
            {
                OsclRefCounterMemFrag privatedataFsiMemFrag;
                OsclLeaveCode fsiErrorCode = OsclErrNone;

                OSCL_TRY(fsiErrorCode, privatedataFsiMemFrag = iPrivateDataFsiFragmentAlloc.get(););

                OSCL_FIRST_CATCH_ANY(fsiErrorCode,
                        LOG_ERR((0, "Failed to allocate memory for  FSI for private data"));
                        status = PVMFErrNoMemory;
                        iNode->ReportErrorEvent(PVMFErrPortProcessing, (OsclAny*)status);
                        OSCL_LEAVE(OsclErrNoMemory);
                        return -1; // this is going to make everything go out of scope
                        );

                uint8 *fsiptr = (uint8*) privatedataFsiMemFrag.getMemFragPtr();
                privatedataFsiMemFrag.getMemFrag().len = sizeof(OsclAny*);
                oscl_memcpy(fsiptr, &(data_header_info.private_data_ptr), sizeof(OsclAny *)); // store ptr data into fsi
                mediaData->setFormatSpecificInfo(privatedataFsiMemFrag);
            }

            LOGDATATRAFFIC((0, "PvmfMediaInputNodeOutPort::writeAsync:"
                            "StreamID=%d, TS=%d, Len=%d, SN=%d, MimeType=%s",
                            data_header_info.stream_id,  data_header_info.timestamp, data_len,
                            data_header_info.seq_num, iMimeType.get_cstr()));
            // Convert media data to MediaMsg
            PVMFSharedMediaMsgPtr mediaMsg;
            convertToPVMFMediaMsg(mediaMsg, mediaData);
#ifdef _TEST_AE_ERROR_HANDLING

            if ((iNode->iErrorTrackID > 0) && (data_header_info.stream_id == (uint32)iNode->iErrorTrackID))
            {
                status = PVMFSuccess;
            }
            else
            {
                status = QueueOutgoingMsg(mediaMsg);
            }
#else
            status = QueueOutgoingMsg(mediaMsg);

#endif
            if (status != PVMFSuccess)
            {
                iNode->ReportErrorEvent(PVMFErrPortProcessing, (OsclAny*)status);
                OsclError::Leave(OsclErrGeneral);
            }

            if (iState == PvmfMediaInputNodeOutPort::PORT_STATE_STARTED)
                RunIfNotReady();

            return iCmdId++;
        }
        else
        {
            LOG_DEBUG((0, "Ignoring Format Type :%d since not supported\n", format_type));
            iNode->ReportErrorEvent(PVMFErrPortProcessing, (OsclAny*)NULL);
            OsclError::Leave(OsclErrGeneral);
        }
    }
    else
    {
        OsclError::Leave(OsclErrBusy);
    }

    return 0;

}

////////////////////////////////////////////////////////////////////////////
void PvmfMediaInputNodeOutPort::writeComplete(PVMFStatus status, PVMFCommandId write_cmd_id, OsclAny* context)
{
    OSCL_UNUSED_ARG(context);
    OSCL_UNUSED_ARG(status);
    OSCL_UNUSED_ARG(write_cmd_id);
    OSCL_LEAVE(OsclErrNotSupported);
}

////////////////////////////////////////////////////////////////////////////
PVMFCommandId PvmfMediaInputNodeOutPort::readAsync(uint8* data, uint32 max_data_len, OsclAny* context,
        int32* formats, uint16 num_formats)
{
    OSCL_UNUSED_ARG(data);
    OSCL_UNUSED_ARG(max_data_len);
    OSCL_UNUSED_ARG(context);
    OSCL_UNUSED_ARG(formats);
    OSCL_UNUSED_ARG(num_formats);
    OSCL_LEAVE(OsclErrNotSupported);
    return -1;
}

////////////////////////////////////////////////////////////////////////////
void PvmfMediaInputNodeOutPort::readComplete(PVMFStatus status, PVMFCommandId read_cmd_id,
        int32 format_index, const PvmiMediaXferHeader& data_header_info,
        OsclAny* context)
{
    OSCL_UNUSED_ARG(status);
    OSCL_UNUSED_ARG(read_cmd_id);
    OSCL_UNUSED_ARG(format_index);
    OSCL_UNUSED_ARG(data_header_info);
    OSCL_UNUSED_ARG(context);
    OSCL_LEAVE(OsclErrNotSupported);
}

////////////////////////////////////////////////////////////////////////////
void PvmfMediaInputNodeOutPort::statusUpdate(uint32 status_flags)
{
    OSCL_UNUSED_ARG(status_flags);
}

////////////////////////////////////////////////////////////////////////////
void PvmfMediaInputNodeOutPort::cancelCommand(PVMFCommandId command_id)
{
    OSCL_UNUSED_ARG(command_id);
    OSCL_LEAVE(OsclErrNotSupported);
}

////////////////////////////////////////////////////////////////////////////
void PvmfMediaInputNodeOutPort::cancelAllCommands()
{
    OSCL_LEAVE(OsclErrNotSupported);
}

////////////////////////////////////////////////////////////////////////////
//                  PvmiCapabilityAndConfig
////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF void PvmfMediaInputNodeOutPort::setObserver(PvmiConfigAndCapabilityCmdObserver* aObserver)
{
    // Not supported
    OSCL_UNUSED_ARG(aObserver);
}

////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF PVMFStatus PvmfMediaInputNodeOutPort::getParametersSync(PvmiMIOSession session,
        PvmiKeyType identifier,
        PvmiKvp*& parameters,
        int& num_parameter_elements,
        PvmiCapabilityContext context)
{
    LOG_STACK_TRACE((0, "PvmfMediaInputNodeOutPort::getParametersSync"));

    if (!iNode || !iNode->iMediaIOConfig)
    {
        LOG_ERR((0, "PvmfMediaInputNodeOutPort::getParametersSync: Error - Config object for media IO not available"));
        return PVMFFailure;

    }

    return iNode->iMediaIOConfig->getParametersSync(session, identifier, parameters,
            num_parameter_elements, context);
}

////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF PVMFStatus PvmfMediaInputNodeOutPort::releaseParameters(PvmiMIOSession session,
        PvmiKvp* parameters,
        int num_elements)
{
    LOG_STACK_TRACE((0, "PvmfMediaInputNodeOutPort::releaseParameters"));

    if (!iNode || !iNode->iMediaIOConfig)
    {
        LOG_ERR((0, "PvmfMediaInputNodeOutPort::releaseParameters: Error - Config object for media IO not available"));
        return PVMFFailure;

    }

    return iNode->iMediaIOConfig->releaseParameters(session, parameters, num_elements);
}

////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF void PvmfMediaInputNodeOutPort::createContext(PvmiMIOSession session, PvmiCapabilityContext& context)
{
    OSCL_UNUSED_ARG(session);
    OSCL_UNUSED_ARG(context);
}

////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF void PvmfMediaInputNodeOutPort::setContextParameters(PvmiMIOSession session,
        PvmiCapabilityContext& context,
        PvmiKvp* parameters, int num_parameter_elements)
{
    OSCL_UNUSED_ARG(session);
    OSCL_UNUSED_ARG(context);
    OSCL_UNUSED_ARG(parameters);
    OSCL_UNUSED_ARG(num_parameter_elements);
}

////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF void PvmfMediaInputNodeOutPort::DeleteContext(PvmiMIOSession session, PvmiCapabilityContext& context)
{
    OSCL_UNUSED_ARG(session);
    OSCL_UNUSED_ARG(context);
}

////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF void PvmfMediaInputNodeOutPort::setParametersSync(PvmiMIOSession session, PvmiKvp* parameters,
        int num_elements, PvmiKvp*& ret_kvp)
{
    LOG_STACK_TRACE((0, "PvmfMediaInputNodeOutPort::setParametersSync"));

    if (!iNode || !iNode->iMediaIOConfig)
    {
        LOG_ERR((0, "PvmfMediaInputNodeOutPort::setParametersSync: Error - Config object for media IO not available"));
        ret_kvp = parameters;
        OSCL_LEAVE(OsclErrGeneral);
    }

    iNode->iMediaIOConfig->setParametersSync(session, parameters, num_elements, ret_kvp);
}

////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF PVMFCommandId PvmfMediaInputNodeOutPort::setParametersAsync(PvmiMIOSession session,
        PvmiKvp* parameters,
        int num_elements,
        PvmiKvp*& ret_kvp,
        OsclAny* context)
{
    OSCL_UNUSED_ARG(session);
    OSCL_UNUSED_ARG(parameters);
    OSCL_UNUSED_ARG(num_elements);
    OSCL_UNUSED_ARG(ret_kvp);
    OSCL_UNUSED_ARG(context);
    OsclError::Leave(OsclErrNotSupported);
    return -1;
}

////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF uint32 PvmfMediaInputNodeOutPort::getCapabilityMetric(PvmiMIOSession session)
{
    OSCL_UNUSED_ARG(session);
    return 0;
}

////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF PVMFStatus PvmfMediaInputNodeOutPort::verifyParametersSync(PvmiMIOSession session,
        PvmiKvp* parameters, int num_elements)
{
    LOG_STACK_TRACE((0, "PvmfMediaInputNodeOutPort::verifyParametersSync"));

    if (!iNode || !iNode->iMediaIOConfig)
    {
        LOG_ERR((0, "PvmfMediaInputNodeOutPort::verifyParametersSync: Error - Config object for media IO not available"));
        return PVMFFailure;
    }

    return iNode->iMediaIOConfig->verifyParametersSync(session, parameters, num_elements);
}

////////////////////////////////////////////////////////////////////////////
void PvmfMediaInputNodeOutPort::Run()
{
    if (iState == PvmfMediaInputNodeOutPort::PORT_STATE_BUFFERING)
        return;

#ifdef _TEST_AE_ERROR_HANDLING
    if (iNode->iError_No_Memory)
    {
        if (iMediaInput && iWriteState == EWriteBusy)
        {
            iWriteState = EWriteOK;
            iMediaInput->statusUpdate(PVMI_MEDIAXFER_STATUS_WRITE);
            iNode->iError_No_Memory = false;
        }
    }
#endif
    if ((OutgoingMsgQueueSize() > 0) && (!IsConnectedPortBusy()))
    {
        //transfer data to connected port.
        PVMFStatus status = Send();
        if (status != PVMFSuccess)
            iNode->ReportErrorEvent(PVMFErrPortProcessing, (OsclAny*)status);

        //reschedule as long as there's data queued...
        if (OutgoingMsgQueueSize() > 0
                && !IsConnectedPortBusy())
        {
            RunIfNotReady();
        }

        if (iNode->IsFlushPending())
        {
            if (IncomingMsgQueueSize() == 0 && OutgoingMsgQueueSize() == 0)
                iNode->FlushComplete();
        }
    }
}

////////////////////////////////////////////////////////////////////////////
void PvmfMediaInputNodeOutPort::HandlePortActivity(const PVMFPortActivity& aActivity)
{
    switch (aActivity.iType)
    {
        case PVMF_PORT_ACTIVITY_CONNECT:
        {
            //get the mimetype
            OsclAny* temp = NULL;
            iConnectedPort->QueryInterface(PVMI_CAPABILITY_AND_CONFIG_PVUUID, temp);
            PvmiCapabilityAndConfig *config = OSCL_STATIC_CAST(PvmiCapabilityAndConfig*, temp);

            if (config != NULL)
            {
                int numKvp = 0;
                PvmiKvp* kvpPtr = NULL;
                PVMFStatus status =
                    config->getParametersSync(NULL,
                                              (char*)INPUT_FORMATS_CUR_QUERY, kvpPtr, numKvp, NULL);
                if (status == PVMFSuccess)
                {
                    iFormatType = kvpPtr[0].value.pChar_value;
                    iMimeType = iFormatType.getMIMEStrPtr();
                }
                config->releaseParameters(NULL, kvpPtr, numKvp);
            }
        }
        break;

        case PVMF_PORT_ACTIVITY_DISCONNECT:
            break;

        case PVMF_PORT_ACTIVITY_OUTGOING_MSG:
            //wakeup the AO when the first message arrives.
            if (OutgoingMsgQueueSize() == 1)
                RunIfNotReady();
            break;

        case PVMF_PORT_ACTIVITY_CONNECTED_PORT_READY:
            //wakeup the AO when the connected port is
            //ready to accept data again.
            RunIfNotReady();
            break;

        case PVMF_PORT_ACTIVITY_OUTGOING_QUEUE_READY:
            if (iMediaInput && (iWriteState == EWriteBusy))
            {
                iWriteState = EWriteOK;
                //let the peer know they can try to write again.
                iMediaInput->statusUpdate(PVMI_MEDIAXFER_STATUS_WRITE);
            }
            break;
        case PVMF_PORT_ACTIVITY_OUTGOING_QUEUE_BUSY:
        {
            iWriteState = EWriteBusy;
        }
        break;
        case PVMF_PORT_ACTIVITY_CONNECTED_PORT_BUSY:
            break;
        default:
            break;
    }
}

////////////////////////////////////////////////////////////////////////////
void PvmfMediaInputNodeOutPort::SendEndOfTrackCommand(const PvmiMediaXferHeader& data_header_info)
{
    PVMFSharedMediaCmdPtr sharedMediaCmdPtr = PVMFMediaCmd::createMediaCmd();

    sharedMediaCmdPtr->setFormatID(PVMF_MEDIA_CMD_EOS_FORMAT_ID);

    // Set the timestamp
    sharedMediaCmdPtr->setTimestamp(data_header_info.timestamp);

    // Set the sequence number
    sharedMediaCmdPtr->setSeqNum(data_header_info.seq_num);

    PVMFSharedMediaMsgPtr mediaMsgOut;
    convertToPVMFMediaCmdMsg(mediaMsgOut, sharedMediaCmdPtr);

    PVMFStatus status = QueueOutgoingMsg(mediaMsgOut);
    if (status != PVMFSuccess)
    {
        iNode->ReportErrorEvent(PVMFErrPortProcessing, (OsclAny*)status);
        OsclError::Leave(OsclErrGeneral);
    }

    LOGDATATRAFFIC((0, "PvmfMediaInputNodeOutPort::SendEndOfTrackCommand - EOS Sent:"
                    "StreamID=%d, TS=%d, SN=%d, MimeType=%s",
                    data_header_info.stream_id,  data_header_info.timestamp,
                    data_header_info.seq_num, iMimeType.get_cstr()));
}

void PvmfMediaInputNodeOutPort :: freechunkavailable(OsclAny*)
{
    if (iWriteState == EWriteBusy)
    {
        iWriteState = EWriteOK;
        if (IsAdded())
        {
            iMediaInput->statusUpdate(PVMI_MEDIAXFER_STATUS_WRITE);
        }
    }
}
