/* ------------------------------------------------------------------
 * 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.
 * -------------------------------------------------------------------
 */
#include "pvmf_omx_enc_node.h"
#include "pvlogger.h"
#include "oscl_error_codes.h"
#include "pvmf_omx_enc_port.h"
#include "pv_mime_string_utils.h"
#include "oscl_snprintf.h"
#include "pvmf_media_cmd.h"
#include "pvmf_media_msg_format_ids.h"
#include "pvmi_kvp_util.h"

#ifdef _DEBUG
#include <stdio.h>
#endif

#include "OMX_Core.h"
#include "pvmf_omx_enc_callbacks.h"     //used for thin AO in encoder's callbacks
#include "pv_omxcore.h"

#define CONFIG_SIZE_AND_VERSION(param)                  \
    param.nSize=sizeof(param);                          \
    param.nVersion.s.nVersionMajor = SPECVERSIONMAJOR;  \
    param.nVersion.s.nVersionMinor = SPECVERSIONMINOR;  \
    param.nVersion.s.nRevision = SPECREVISION;          \
    param.nVersion.s.nStep = SPECSTEP;


#define CHECK_OMX_ERR_AND_RETURN(Err, str)                              \
    if (Err != OMX_ErrorNone)                                           \
    {                                                                   \
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, str)); \
    }


#define PVOMXENC_EXTRA_YUVBUFFER_POOLNUM 3
#define PVOMXENC_MEDIADATA_POOLNUM (PVOMXENCMAXNUMDPBFRAMESPLUS1 + PVOMXENC_EXTRA_YUVBUFFER_POOLNUM)
#define PVOMXENC_MEDIADATA_CHUNKSIZE 128

#include "utils/Log.h"
#undef LOG_TAG
#define LOG_TAG "PVOMXEncNode"

const uint32 DEFAULT_VOL_HEADER_LENGTH = 28;
const uint8 DEFAULT_VOL_HEADER[DEFAULT_VOL_HEADER_LENGTH] =
{
    0x00, 0x00, 0x01, 0xB0, 0x08, 0x00, 0x00, 0x01,
    0xB5, 0x09, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
    0x01, 0x20, 0x00, 0x84, 0x40, 0xFA, 0x28, 0x2C,
    0x20, 0x90, 0xA2, 0x1F
};


#ifdef _TEST_AE_ERROR_HANDLING
const uint32 FAIL_NODE_CMD_START = 2;
const uint32 FAIL_NODE_CMD_STOP = 3;
const uint32 FAIL_NODE_CMD_FLUSH = 4;
const uint32 FAIL_NODE_CMD_PAUSE = 5;
const uint32 FAIL_NODE_CMD_RELEASE_PORT = 7;
#endif

#define PVMF_OMXENC_NUM_METADATA_VALUES 6

// Constant character strings for metadata keys
static const char PVOMXENCMETADATA_CODECINFO_VIDEO_FORMAT_KEY[] = "codec-info/video/format";
static const char PVOMXENCMETADATA_CODECINFO_VIDEO_WIDTH_KEY[] = "codec-info/video/width";
static const char PVOMXENCMETADATA_CODECINFO_VIDEO_HEIGHT_KEY[] = "codec-info/video/height";
static const char PVOMXENCMETADATA_CODECINFO_VIDEO_PROFILE_KEY[] = "codec-info/video/profile";
static const char PVOMXENCMETADATA_CODECINFO_VIDEO_LEVEL_KEY[] = "codec-info/video/level";
static const char PVOMXENCMETADATA_CODECINFO_VIDEO_AVGBITRATE_KEY[] = "codec-info/video/avgbitrate";//(bits per sec)


static const char PVOMXENCMETADATA_SEMICOLON[] = ";";

static const char LOG_ID_AUDIO_AMRNB[]  = "Audio_AMRNB";
static const char LOG_ID_AUDIO_AMRWB[]  = "Audio_AMRWB";
static const char LOG_ID_AUDIO_AAC[]  = "Audio_AAC";
static const char LOG_ID_VIDEO_H263[] = "Video_H263";
static const char LOG_ID_VIDEO_M4V[] =  "Video_M4V";
static const char LOG_ID_VIDEO_AVC[] =  "Video_AVC";
static const char LOG_ID_UNKNOWN[] = "TypeNotSetYet";

// OMX CALLBACKS
// 1) AO OMX component running in the same thread as the OMX node
//  In this case, the callbacks can be called directly from the component
//  The callback: OMX Component->CallbackEventHandler->EventHandlerProcessing
//  The callback can perform do RunIfNotReady

// 2) Multithreaded component
//  In this case, the callback is made using the threadsafe callback (TSCB) AO
//  Component thread : OMX Component->CallbackEventHandler->TSCB(ReceiveEvent) => event is queued
//  Node thread      : dequeue event => TSCB(ProcessEvent)->ProcessCallbackEventHandler->EventHandlerProcessing



// callback for Event Handler - in multithreaded case, event is queued to be processed later
//  in AO case, event is processed immediately by calling EventHandlerProcessing
OMX_ERRORTYPE CallbackEventHandlerEnc(OMX_OUT OMX_HANDLETYPE aComponent,
                                      OMX_OUT OMX_PTR aAppData,
                                      OMX_OUT OMX_EVENTTYPE aEvent,
                                      OMX_OUT OMX_U32 aData1,
                                      OMX_OUT OMX_U32 aData2,
                                      OMX_OUT OMX_PTR aEventData)
{

    PVMFOMXEncNode *Node = (PVMFOMXEncNode *) aAppData;

    if (Node->IsComponentMultiThreaded())
    {
        // allocate the memory for the callback event specific data
        //EventHandlerSpecificData* ED = (EventHandlerSpecificData*) oscl_malloc(sizeof (EventHandlerSpecificData));
        EventHandlerSpecificData* ED = (EventHandlerSpecificData*) Node->iThreadSafeHandlerEventHandler->iMemoryPool->allocate(sizeof(EventHandlerSpecificData));

        // pack the relevant data into the structure
        ED->hComponent = aComponent;
        ED->pAppData = aAppData;
        ED->eEvent = aEvent;
        ED->nData1 = aData1;
        ED->nData2 = aData2;
        ED->pEventData = aEventData;

        // convert the pointer into OsclAny ptr
        OsclAny* P = (OsclAny*) ED;


        // CALL the generic callback AO API:
        Node->iThreadSafeHandlerEventHandler->ReceiveEvent(P);

        return OMX_ErrorNone;
    }
    else
    {

        OMX_ERRORTYPE status;
        status = Node->EventHandlerProcessing(aComponent, aAppData, aEvent, aData1, aData2, aEventData);
        return status;
    }

}


// callback for EmptyBufferDone - in multithreaded case, event is queued to be processed later
//  in AO case, event is processed immediately by calling EmptyBufferDoneProcessing
OMX_ERRORTYPE CallbackEmptyBufferDoneEnc(OMX_OUT OMX_HANDLETYPE aComponent,
        OMX_OUT OMX_PTR aAppData,
        OMX_OUT OMX_BUFFERHEADERTYPE* aBuffer)
{

    PVMFOMXEncNode *Node = (PVMFOMXEncNode *) aAppData;
    if (Node->IsComponentMultiThreaded())
    {

        // allocate the memory for the callback event specific data
        //EmptyBufferDoneSpecificData* ED = (EmptyBufferDoneSpecificData*) oscl_malloc(sizeof (EmptyBufferDoneSpecificData));
        EmptyBufferDoneSpecificData* ED = (EmptyBufferDoneSpecificData*) Node->iThreadSafeHandlerEmptyBufferDone->iMemoryPool->allocate(sizeof(EmptyBufferDoneSpecificData));

        // pack the relevant data into the structure
        ED->hComponent = aComponent;
        ED->pAppData = aAppData;
        ED->pBuffer = aBuffer;

        // convert the pointer into OsclAny ptr
        OsclAny* P = (OsclAny*) ED;

        // CALL the generic callback AO API:
        Node->iThreadSafeHandlerEmptyBufferDone->ReceiveEvent(P);

        return OMX_ErrorNone;
    }
    else
    {
        OMX_ERRORTYPE status;
        status = Node->EmptyBufferDoneProcessing(aComponent, aAppData, aBuffer);
        return status;
    }

}

// callback for FillBufferDone - in multithreaded case, event is queued to be processed later
//  in AO case, event is processed immediately by calling FillBufferDoneProcessing
OMX_ERRORTYPE CallbackFillBufferDoneEnc(OMX_OUT OMX_HANDLETYPE aComponent,
                                        OMX_OUT OMX_PTR aAppData,
                                        OMX_OUT OMX_BUFFERHEADERTYPE* aBuffer)
{
    PVMFOMXEncNode *Node = (PVMFOMXEncNode *) aAppData;
    if (Node->IsComponentMultiThreaded())
    {

        // allocate the memory for the callback event specific data
        //FillBufferDoneSpecificData* ED = (FillBufferDoneSpecificData*) oscl_malloc(sizeof (FillBufferDoneSpecificData));
        FillBufferDoneSpecificData* ED = (FillBufferDoneSpecificData*) Node->iThreadSafeHandlerFillBufferDone->iMemoryPool->allocate(sizeof(FillBufferDoneSpecificData));

        // pack the relevant data into the structure
        ED->hComponent = aComponent;
        ED->pAppData = aAppData;
        ED->pBuffer = aBuffer;

        // convert the pointer into OsclAny ptr
        OsclAny* P = (OsclAny*) ED;

        // CALL the generic callback AO API:
        Node->iThreadSafeHandlerFillBufferDone->ReceiveEvent(P);

        return OMX_ErrorNone;
    }
    else
    {
        OMX_ERRORTYPE status;
        status = Node->FillBufferDoneProcessing(aComponent, aAppData, aBuffer);
        return status;
    }

}

// Callback processing in multithreaded case - dequeued event - call EventHandlerProcessing
OsclReturnCode PVMFOMXEncNode::ProcessCallbackEventHandler_MultiThreaded(OsclAny* P)
{

    // re-cast the pointer

    EventHandlerSpecificData* ED = (EventHandlerSpecificData*) P;

    OMX_HANDLETYPE aComponent = ED->hComponent;
    OMX_PTR aAppData = ED->pAppData;
    OMX_EVENTTYPE aEvent = ED->eEvent;
    OMX_U32 aData1 = ED->nData1;
    OMX_U32 aData2 = ED->nData2;
    OMX_PTR aEventData = ED->pEventData;


    EventHandlerProcessing(aComponent, aAppData, aEvent, aData1, aData2, aEventData);


    // release the allocated memory when no longer needed

    iThreadSafeHandlerEventHandler->iMemoryPool->deallocate(ED);
    ED = NULL;

    return OsclSuccess;
}



// Callback processing in multithreaded case - dequeued event - call EmptyBufferDoneProcessing
OsclReturnCode PVMFOMXEncNode::ProcessCallbackEmptyBufferDone_MultiThreaded(OsclAny* P)
{


    // re-cast the pointer
    EmptyBufferDoneSpecificData* ED = (EmptyBufferDoneSpecificData*) P;

    OMX_HANDLETYPE aComponent = ED->hComponent;
    OMX_PTR aAppData = ED->pAppData;
    OMX_BUFFERHEADERTYPE* aBuffer = ED->pBuffer;

    EmptyBufferDoneProcessing(aComponent, aAppData, aBuffer);

    // release the allocated memory when no longer needed

    iThreadSafeHandlerEmptyBufferDone->iMemoryPool->deallocate(ED);
    ED = NULL;

    return OsclSuccess;
}


// Callback processing in multithreaded case - dequeued event - call FillBufferDoneProcessing
OsclReturnCode PVMFOMXEncNode::ProcessCallbackFillBufferDone_MultiThreaded(OsclAny* P)
{

    // re-cast the pointer
    FillBufferDoneSpecificData* ED = (FillBufferDoneSpecificData*) P;

    OMX_HANDLETYPE aComponent = ED->hComponent;
    OMX_PTR aAppData = ED->pAppData;
    OMX_BUFFERHEADERTYPE* aBuffer = ED->pBuffer;


    FillBufferDoneProcessing(aComponent, aAppData, aBuffer);


    // release the allocated memory when no longer needed

    iThreadSafeHandlerFillBufferDone->iMemoryPool->deallocate(ED);
    ED = NULL;

    return OsclSuccess;
}
/////////////////////////////////////////////////////////////////////////////
// Class Destructor
/////////////////////////////////////////////////////////////////////////////
PVMFOMXEncNode::~PVMFOMXEncNode()
{
    LogDiagnostics();

    //Clearup encoder
    DeleteOMXEncoder();

    // Cleanup callback AOs and Mempools
    if (iThreadSafeHandlerEventHandler)
    {
        OSCL_DELETE(iThreadSafeHandlerEventHandler);
        iThreadSafeHandlerEventHandler = NULL;
    }
    if (iThreadSafeHandlerEmptyBufferDone)
    {
        OSCL_DELETE(iThreadSafeHandlerEmptyBufferDone);
        iThreadSafeHandlerEmptyBufferDone = NULL;
    }
    if (iThreadSafeHandlerFillBufferDone)
    {
        OSCL_DELETE(iThreadSafeHandlerFillBufferDone);
        iThreadSafeHandlerFillBufferDone = NULL;
    }

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

    if (iOutBufMemoryPool)
    {
        iOutBufMemoryPool->removeRef();
        iOutBufMemoryPool = NULL;
    }

    ipFixedSizeBufferAlloc = NULL;
    if(ipExternalInputBufferAllocatorInterface)
    {
        ipExternalInputBufferAllocatorInterface->removeRef();
        ipExternalInputBufferAllocatorInterface = NULL;
    }

    if (iInBufMemoryPool)
    {
        iInBufMemoryPool->removeRef();
        iInBufMemoryPool = NULL;
    }

    if (in_ctrl_struct_ptr)
    {
        oscl_free(in_ctrl_struct_ptr);
        in_ctrl_struct_ptr = NULL;
    }

    if (in_buff_hdr_ptr)
    {
        oscl_free(in_buff_hdr_ptr);
        in_buff_hdr_ptr = NULL;
    }

    if (out_ctrl_struct_ptr)
    {
        oscl_free(out_ctrl_struct_ptr);
        out_ctrl_struct_ptr = NULL;
    }

    if (out_buff_hdr_ptr)
    {
        oscl_free(out_buff_hdr_ptr);
        out_buff_hdr_ptr = NULL;
    }

    //Thread logoff
    if (IsAdded())
    {
        RemoveFromScheduler();
        iIsAdded = false;
    }

    //Cleanup allocated interfaces

    //Cleanup allocated ports
    ReleaseAllPorts();

    //Cleanup commands
    //The command queues are self-deleting, but we want to
    //notify the observer of unprocessed commands.
    while (!iCurrentCommand.empty())
    {
        CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFFailure);
    }
    while (!iInputCommands.empty())
    {
        CommandComplete(iInputCommands, iInputCommands.front(), PVMFFailure);
    }

    if (iNALSizeArray != NULL)
    {
        oscl_free(iNALSizeArray);
    }

    if (iNALPtrArray != NULL)
    {
        oscl_free(iNALPtrArray);
    }

    //Release Input buffer
    iDataIn.Unbind();

}

/////////////////////////////////////////////////////////////////////////////
// Add AO to the scheduler
/////////////////////////////////////////////////////////////////////////////
PVMFStatus PVMFOMXEncNode::ThreadLogon()
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFOMXEncNode:ThreadLogon"));

    switch (iInterfaceState)
    {
        case EPVMFNodeCreated:
            if (!IsAdded())
            {
                AddToScheduler();
                iIsAdded = true;
            }

            SetState(EPVMFNodeIdle);
            return PVMFSuccess;
            // break;   This break statement was removed to avoid compiler warning for Unreachable Code
        default:
            return PVMFErrInvalidState;
            // break;   This break statement was removed to avoid compiler warning for Unreachable Code
    }
}

/////////////////////////////////////////////////////////////////////////////
// Remove AO from the scheduler
/////////////////////////////////////////////////////////////////////////////
PVMFStatus PVMFOMXEncNode::ThreadLogoff()
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFOMXEncNode-%s::ThreadLogoff", iNodeTypeId));

    switch (iInterfaceState)
    {
        case EPVMFNodeIdle:
            if (IsAdded())
            {
                RemoveFromScheduler();
                iIsAdded = false;
            }
            iLogger = NULL;
            SetState(EPVMFNodeCreated);
            return PVMFSuccess;
            // break;   This break statement was removed to avoid compiler warning for Unreachable Code

        default:
            return PVMFErrInvalidState;
            // break;   This break statement was removed to avoid compiler warning for Unreachable Code
    }
}

/////////////////////////////////////////////////////////////////////////////
PVMFStatus PVMFOMXEncNode::GetCapability(PVMFNodeCapability& aNodeCapability)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::GetCapability() called", iNodeTypeId));

    aNodeCapability = iCapability;
    return PVMFSuccess;
}

/////////////////////////////////////////////////////////////////////////////
PVMFPortIter* PVMFOMXEncNode::GetPorts(const PVMFPortFilter* aFilter)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::GetPorts() %s called", iNodeTypeId));

    OSCL_UNUSED_ARG(aFilter);

    return NULL;
}

/////////////////////////////////////////////////////////////////////////////
PVMFCommandId PVMFOMXEncNode::QueueCommandL(PVMFOMXEncNodeCommand& aCmd)
{
    PVMFCommandId id;

    id = iInputCommands.AddL(aCmd);

    if (iInputCommands.size() == 1)
    {
        //wakeup the AO all the rest of input commands will reschedule the AO in Run
        RunIfNotReady();
    }
    return id;
}

/////////////////////////////////////////////////////////////////////////////
PVMFCommandId PVMFOMXEncNode::QueryUUID(PVMFSessionId s, const PvmfMimeString& aMimeType,
                                        Oscl_Vector<PVUuid, PVMFOMXEncNodeAllocator>& aUuids,
                                        bool aExactUuidsOnly,
                                        const OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::QueryUUID() called", iNodeTypeId));
    PVMFOMXEncNodeCommand cmd;
    cmd.PVMFOMXEncNodeCommandBase::Construct(s, PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_QUERYUUID, aMimeType, aUuids, aExactUuidsOnly, aContext);
    return QueueCommandL(cmd);
}

/////////////////////////////////////////////////////////////////////////////
PVMFCommandId PVMFOMXEncNode::QueryInterface(PVMFSessionId s, const PVUuid& aUuid,
        PVInterface*& aInterfacePtr,
        const OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::QueryInterface() called", iNodeTypeId));
    PVMFOMXEncNodeCommand cmd;
    cmd.PVMFOMXEncNodeCommandBase::Construct(s, PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_QUERYINTERFACE, aUuid, aInterfacePtr, aContext);
    return QueueCommandL(cmd);
}

/////////////////////////////////////////////////////////////////////////////
PVMFCommandId PVMFOMXEncNode::RequestPort(PVMFSessionId s, int32 aPortTag, const PvmfMimeString* aPortConfig, const OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::RequestPort() called", iNodeTypeId));
    PVMFOMXEncNodeCommand cmd;

    // IMPORTANT NOTE - ENGINE IS SENDING THE MIME TYPE FOR THE ENCODER INPUT/OUTPUT FORMAT THRU THE PORT PARAMETER
    cmd.PVMFOMXEncNodeCommandBase::Construct(s, PVMF_GENERIC_NODE_REQUESTPORT, aPortTag, aPortConfig, aContext);
    return QueueCommandL(cmd);

}

/////////////////////////////////////////////////////////////////////////////
PVMFStatus PVMFOMXEncNode::ReleasePort(PVMFSessionId s, PVMFPortInterface& aPort, const OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::ReleasePort() called", iNodeTypeId));
    PVMFOMXEncNodeCommand cmd;
    cmd.PVMFOMXEncNodeCommandBase::Construct(s, PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_RELEASEPORT, aPort, aContext);
    return QueueCommandL(cmd);
}

/////////////////////////////////////////////////////////////////////////////
PVMFCommandId PVMFOMXEncNode::Init(PVMFSessionId s, const OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::Init() called", iNodeTypeId));
    PVMFOMXEncNodeCommand cmd;
    cmd.PVMFOMXEncNodeCommandBase::Construct(s, PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_INIT, aContext);
    return QueueCommandL(cmd);
}

/////////////////////////////////////////////////////////////////////////////
PVMFCommandId PVMFOMXEncNode::Prepare(PVMFSessionId s, const OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::Prepare() called", iNodeTypeId));
    PVMFOMXEncNodeCommand cmd;
    cmd.PVMFOMXEncNodeCommandBase::Construct(s, PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_PREPARE, aContext);
    return QueueCommandL(cmd);
}

/////////////////////////////////////////////////////////////////////////////
PVMFCommandId PVMFOMXEncNode::Start(PVMFSessionId s, const OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::Start() called", iNodeTypeId));
    PVMFOMXEncNodeCommand cmd;
    cmd.PVMFOMXEncNodeCommandBase::Construct(s, PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_START, aContext);
    return QueueCommandL(cmd);
}

/////////////////////////////////////////////////////////////////////////////
PVMFCommandId PVMFOMXEncNode::Stop(PVMFSessionId s, const OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::Stop() called", iNodeTypeId));
    PVMFOMXEncNodeCommand cmd;
    cmd.PVMFOMXEncNodeCommandBase::Construct(s, PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_STOP, aContext);
    return QueueCommandL(cmd);
}

/////////////////////////////////////////////////////////////////////////////
PVMFCommandId PVMFOMXEncNode::Flush(PVMFSessionId s, const OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::Flush() called", iNodeTypeId));
    PVMFOMXEncNodeCommand cmd;
    cmd.PVMFOMXEncNodeCommandBase::Construct(s, PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_FLUSH, aContext);
    return QueueCommandL(cmd);
}

/////////////////////////////////////////////////////////////////////////////
PVMFCommandId PVMFOMXEncNode::Pause(PVMFSessionId s, const OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::Pause() called", iNodeTypeId));
    PVMFOMXEncNodeCommand cmd;
    cmd.PVMFOMXEncNodeCommandBase::Construct(s, PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_PAUSE, aContext);
    return QueueCommandL(cmd);
}

/////////////////////////////////////////////////////////////////////////////
PVMFCommandId PVMFOMXEncNode::Reset(PVMFSessionId s, const OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::Reset() called", iNodeTypeId));
    PVMFOMXEncNodeCommand cmd;
    cmd.PVMFOMXEncNodeCommandBase::Construct(s, PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_RESET, aContext);
    return QueueCommandL(cmd);
}

/////////////////////////////////////////////////////////////////////////////
PVMFCommandId PVMFOMXEncNode::CancelAllCommands(PVMFSessionId s, const OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::CancelAllCommands() called", iNodeTypeId));
    PVMFOMXEncNodeCommand cmd;
    cmd.PVMFOMXEncNodeCommandBase::Construct(s, PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_CANCELALL, aContext);
    return QueueCommandL(cmd);
}

/////////////////////////////////////////////////////////////////////////////
PVMFCommandId PVMFOMXEncNode::CancelCommand(PVMFSessionId s, PVMFCommandId aCmdId, const OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::CancelCommand() called", iNodeTypeId));
    PVMFOMXEncNodeCommand cmd;
    cmd.PVMFOMXEncNodeCommandBase::Construct(s, PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_CANCELCMD, aCmdId, aContext);
    return QueueCommandL(cmd);
}





/////////////////////
// Private Section //
/////////////////////

/////////////////////////////////////////////////////////////////////////////
// Class Constructor
/////////////////////////////////////////////////////////////////////////////
PVMFOMXEncNode::PVMFOMXEncNode(int32 aPriority) :
        OsclActiveObject(aPriority, "PVMFOMXEncNode"),
        iInPort(NULL),
        iOutPort(NULL),
        iOutBufMemoryPool(NULL),
        iMediaDataMemPool(NULL),
        iOMXComponentOutputBufferSize(0),
        iOutputAllocSize(0),
        iNumOutstandingOutputBuffers(0),
        iNumOutstandingInputBuffers(0),
        iProcessingState(EPVMFOMXEncNodeProcessingState_Idle),
        iOMXEncoder(NULL),
        iSendBOS(false),
        iStreamID(0),
        iBOSTimestamp(0),
        iSeqNum(0),
        iSeqNum_In(0),
        iIsAdded(true),
        iLogger(NULL),
        iDataPathLogger(NULL),
        iClockLogger(NULL),
        iExtensionRefCount(0),
        iEndOfDataReached(false),
        iEndOfDataTimestamp(0),
        iDiagnosticsLogger(NULL),
        iDiagnosticsLogged(false),
        iAvgBitrateValue(0),
        iResetInProgress(false),
        iResetMsgSent(false),
        iStopInResetMsgSent(false),
        ipExternalInputBufferAllocatorInterface(NULL),
        ipFixedSizeBufferAlloc(NULL)
{
    iInterfaceState = EPVMFNodeCreated;


    // Allocate memory for VOL header
    uint refCounterSize = oscl_mem_aligned_size(sizeof(OsclRefCounterDA));
    uint VolHdrSize = refCounterSize + DEFAULT_VOL_HEADER_LENGTH;
    uint8 *memBufferVOLHeader = NULL;

    uint ParamSetSize = refCounterSize + DEFAULT_PARAMS_SET_LENGTH;
    uint8 *memBufferParamSet = NULL;


    int32 err;
    OSCL_TRY(err,

             //Create the input command queue.  Use a reserve to avoid lots of
             //dynamic memory allocation.
             iInputCommands.Construct(PVMF_OMXENC_NODE_COMMAND_ID_START, PVMF_OMXENC_NODE_COMMAND_VECTOR_RESERVE);

             //Create the "current command" queue.  It will only contain one
             //command at a time, so use a reserve of 1.
             iCurrentCommand.Construct(0, 1);

             //Set the node capability data.
             //This node can support an unlimited number of ports.
             iCapability.iCanSupportMultipleInputPorts = false;
             iCapability.iCanSupportMultipleOutputPorts = false;
             iCapability.iHasMaxNumberOfPorts = true;
             iCapability.iMaxNumberOfPorts = 2;

             // video output
             iCapability.iOutputFormatCapability.push_back(PVMF_MIME_H264_VIDEO_MP4);
             iCapability.iOutputFormatCapability.push_back(PVMF_MIME_H264_VIDEO_RAW);
             //iCapability.iOutputFormatCapability.push_back(PVMF_MIME_H264_VIDEO);
             iCapability.iOutputFormatCapability.push_back(PVMF_MIME_M4V);
             iCapability.iOutputFormatCapability.push_back(PVMF_MIME_H2631998);
             iCapability.iOutputFormatCapability.push_back(PVMF_MIME_H2632000);
             //iCapability.iOutputFormatCapability.push_back(PVMF_MIME_WMV);
             // audio output
             iCapability.iOutputFormatCapability.push_back(PVMF_MIME_AMR_IETF);
             iCapability.iOutputFormatCapability.push_back(PVMF_MIME_AMRWB_IETF);
             iCapability.iOutputFormatCapability.push_back(PVMF_MIME_AMR_IF2);
             iCapability.iOutputFormatCapability.push_back(PVMF_MIME_ADTS);
             iCapability.iOutputFormatCapability.push_back(PVMF_MIME_ADIF);
             iCapability.iOutputFormatCapability.push_back(PVMF_MIME_MPEG4_AUDIO);

             // video input
             iCapability.iInputFormatCapability.push_back(PVMF_MIME_YUV420);
             iCapability.iInputFormatCapability.push_back(PVMF_MIME_YUV422);
             iCapability.iInputFormatCapability.push_back(PVMF_MIME_YUV422_INTERLEAVED_UYVY);
             iCapability.iInputFormatCapability.push_back(PVMF_MIME_YUV422_INTERLEAVED_YUYV);
             iCapability.iInputFormatCapability.push_back(PVMF_MIME_RGB24);
             iCapability.iInputFormatCapability.push_back(PVMF_MIME_RGB12);

             // audio input
             iCapability.iInputFormatCapability.push_back(PVMF_MIME_PCM16);



             iAvailableMetadataKeys.reserve(PVMF_OMXENC_NUM_METADATA_VALUES);
             iAvailableMetadataKeys.clear();

             // for VOL header
             memBufferVOLHeader = (uint8*)iAlloc.allocate(VolHdrSize);
             if (!memBufferVOLHeader)
{
    OSCL_LEAVE(PVMFErrNoMemory);
    }

    memBufferParamSet = (uint8*) iAlloc.allocate(ParamSetSize);
    if (!memBufferParamSet)
{
    OSCL_LEAVE(PVMFErrNoMemory);
    }

            );

    // Save default VOL header
    oscl_memset(memBufferVOLHeader, 0, DEFAULT_VOL_HEADER_LENGTH);
    OsclMemoryFragment volHeader;
    OsclRefCounter* refCounterVOLHeader = new(memBufferVOLHeader) OsclRefCounterDA(memBufferVOLHeader,
            (OsclDestructDealloc*)&iAlloc);
    memBufferVOLHeader += refCounterSize;
    volHeader.ptr = memBufferVOLHeader;
    oscl_memcpy(volHeader.ptr, (OsclAny*)DEFAULT_VOL_HEADER, DEFAULT_VOL_HEADER_LENGTH);
    volHeader.len = DEFAULT_VOL_HEADER_LENGTH;
    iVolHeader = OsclRefCounterMemFrag(volHeader, refCounterVOLHeader, DEFAULT_VOL_HEADER_LENGTH);


    // construct SPS&PPS placeholder
    oscl_memset(memBufferParamSet, 0, DEFAULT_PARAMS_SET_LENGTH);
    OsclMemoryFragment paramSet;
    OsclRefCounter* refCounterParamSet = new(memBufferParamSet) OsclRefCounterDA(memBufferParamSet,
            (OsclDestructDealloc*)&iAlloc);
    memBufferParamSet += refCounterSize;
    paramSet.ptr = memBufferParamSet;
    paramSet.len = DEFAULT_PARAMS_SET_LENGTH;

    iParamSet = OsclRefCounterMemFrag(paramSet, refCounterParamSet, DEFAULT_PARAMS_SET_LENGTH);

    // initialize length and number of sps/ppss
    iParamSet.getMemFrag().len = 0;
    iNumPPSs = 0;
    iNumSPSs = 0;
    iSpsPpsSequenceOver = false;
    iFirstNAL = false; //set this to false so that mp4 can proceed without a problem.
    // in case of AVC, this flag will be set after spspps

    iNALSizeArray = NULL;
    iNALPtrArray = NULL;
    iNALSizeArrayMaxElems = 0;
    iNumNALs = 0;
    iFirstNALStartCodeSize = 0;

    iThreadSafeHandlerEventHandler = NULL;
    iThreadSafeHandlerEmptyBufferDone = NULL;
    iThreadSafeHandlerFillBufferDone = NULL;

    iInBufMemoryPool = NULL;
    iOutBufMemoryPool = NULL;

    in_ctrl_struct_ptr = NULL;
    in_buff_hdr_ptr = NULL;
    out_ctrl_struct_ptr = NULL;
    out_buff_hdr_ptr = NULL;

    // init to some value
    iOMXComponentOutputBufferSize = 0;
    iNumOutputBuffers = 0;
    iOMXComponentInputBufferSize = 0;
    iNumInputBuffers = 0;

    iDoNotSendOutputBuffersDownstreamFlag = false;
    iDoNotSaveInputBuffersFlag = false;


    iOutputBuffersFreed = true;// buffers have not been created yet, so they can be considered freed
    iInputBuffersFreed = true;

    // dynamic port reconfig init vars
    iSecondPortReportedChange = false;
    iDynamicReconfigInProgress = false;

    // EOS flag init
    iIsEOSSentToComponent = false;
    iIsEOSReceivedFromComponent = false;

    // init state of component
    iCurrentEncoderState = OMX_StateInvalid;

    iTimeStampOut = 0;
    iTimeStampPrevious = 0;
    iBufferLenOut = 0;
    iBufferLenPrevious = 0;
    iEndOfFrameFlagPrevious = 0;
    iKeyFrameFlagPrevious = 0;
    iEndOfNALFlagPrevious = 0;


    iEndOfFrameFlagOut = 0;
    iKeyFrameFlagOut = 0;
    iEndOfNALFlagOut = 0;

    //if timescale value is 1 000 000 - it means that
    //timestamp is expressed in units of 1/10^6 (i.e. microseconds)

    iTimeScale = 1000000;
    iInTimeScale = 1000;
    iOutTimeScale = 1000;

    iInputTimestampClock.set_timescale(iInTimeScale); // keep the timescale set to input timestamp



    // counts output frames (for logging)
    iFrameCounter = 0;
    iInFormat = PVMF_MIME_FORMAT_UNKNOWN;
    iOutFormat = PVMF_MIME_FORMAT_UNKNOWN;

    // zero out encoder param structure

    oscl_memset(&iVideoInputFormat, 0, sizeof(iVideoInputFormat));

    // set default values
    iVideoInputFormat.iFrameWidth = DEFAULT_FRAME_WIDTH;
    iVideoInputFormat.iFrameHeight = DEFAULT_FRAME_HEIGHT;
    iVideoInputFormat.iFrameRate = (float)DEFAULT_FRAME_RATE;
    iVideoInputFormat.iFrameOrientation = 0;

    oscl_memset(&iVideoEncodeParam, 0, sizeof(iVideoEncodeParam));

    iVideoEncodeParam.iEncodeID = 0;
    iVideoEncodeParam.iNumLayer = 1;
    iVideoEncodeParam.iFrameWidth[0] = DEFAULT_FRAME_WIDTH;
    iVideoEncodeParam.iFrameHeight[0] = DEFAULT_FRAME_HEIGHT;
    iVideoEncodeParam.iBitRate[0] = DEFAULT_BITRATE;
    iVideoEncodeParam.iFrameRate[0] = (float)DEFAULT_FRAME_RATE;
    iVideoEncodeParam.iFrameQuality = 10;
    iVideoEncodeParam.iSceneDetection = false;
    iVideoEncodeParam.iRVLCEnable = false;
    iVideoEncodeParam.iIFrameInterval = DEFAULT_I_FRAME_INTERVAL;
    iVideoEncodeParam.iBufferDelay = (float)0.2;
    iVideoEncodeParam.iShortHeader = false;
    iVideoEncodeParam.iDataPartitioning = false;
    iVideoEncodeParam.iResyncMarker = true;

    // set the default rate control type to variable bit rate control
    // since it has better performance
    iVideoEncodeParam.iRateControlType = PVMFVEN_RATE_CONTROL_VBR;
    iVideoEncodeParam.iIquant[0] = 15;
    iVideoEncodeParam.iPquant[0] = 12;
    iVideoEncodeParam.iBquant[0] = 12;
    iVideoEncodeParam.iSearchRange = 16;
    iVideoEncodeParam.iMV8x8 = false;
    iVideoEncodeParam.iMVHalfPel = true;
    iVideoEncodeParam.iPacketSize = 256;
    iVideoEncodeParam.iNoCurrentSkip = false;
    iVideoEncodeParam.iNoFrameSkip = false;
    iVideoEncodeParam.iClipDuration = 0;
    iVideoEncodeParam.iProfileLevel = EI_CORE_LEVEL2;
    /////////////////AVC SPECIFIC///////////////////////////
    iVideoEncodeParam.iEncMode = EI_ENCMODE_RECORDER;
    iVideoEncodeParam.iAVCProfile = EI_PROFILE_BASELINE;
    iVideoEncodeParam.iAVCLevel = EI_LEVEL_11;


    oscl_memset(&iAudioInputFormat, 0, sizeof(iAudioInputFormat));
    // Currently, set according to AMR values
    iAudioInputFormat.iInputInterleaveMode = EINTERLEAVE_LR;
    iAudioInputFormat.iInputBitsPerSample = 16;
    iAudioInputFormat.iInputNumChannels = 1;
    iAudioInputFormat.iInputSamplingRate = 8000;

    oscl_memset(&iAudioEncodeParam, 0, sizeof(iAudioEncodeParam));

    iAudioEncodeParam.iMaxNumOutputFramesPerBuffer = MAX_NUM_AMR_FRAMES_PER_BUFFER;
    iAudioEncodeParam.iAMRBitrate = GSM_AMR_12_2;
    iAudioEncodeParam.iOutputBitrate = 24000;
    iAudioEncodeParam.iOutputNumChannels = iAudioInputFormat.iInputNumChannels;
    iAudioEncodeParam.iOutputSamplingRate = iAudioInputFormat.iInputSamplingRate;


#ifdef _TEST_AE_ERROR_HANDLING
    iErrorHandlingInit = false;
    iErrorHandlingEncodeCount = 0;
    iCountFrames = 0;
    iErrorDataPathStall = 0;
    iErrorNodeCmd = 0;
    iErrorConfigHeader = false;
    iErrorEncodeFlag = 0;
#endif

    iInputTimestampClock.set_clock(iBOSTimestamp, 0);
    iOMXTicksTimestamp = ConvertTimestampIntoOMXTicks(iInputTimestampClock);

    sendYuvFsi = true;

    iNodeTypeId = LOG_ID_UNKNOWN;
    iLogger = PVLogger::GetLoggerObject("PVMFOMXEncNode");
    iRunlLogger = PVLogger::GetLoggerObject("Run.PVMFOMXEncNode");
    iDataPathLogger = PVLogger::GetLoggerObject("datapath");
    iClockLogger = PVLogger::GetLoggerObject("clock");
    iDiagnosticsLogger = PVLogger::GetLoggerObject("pvplayerdiagnostics.encnode.OMXEncnode");
}

/////////////////////////////////////////////////////////////////////////////
// Local Run Routine
/////////////////////////////////////////////////////////////////////////////
void PVMFOMXEncNode::Run()
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::Run() In", iNodeTypeId));

    // if reset is in progress, call DoReset again until Reset Msg is sent
    if ((iResetInProgress == true) &&
            (iResetMsgSent == false) &&
            (iCurrentCommand.size() > 0) &&
            (iCurrentCommand.front().iCmd == PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_RESET)
       )
    {
        DoReset(iCurrentCommand.front());
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, (0, "PVMFOMXEncNode-%s::Run() - Calling DoReset", iNodeTypeId));
        return; // don't do anything else
    }
    //Check for NODE commands...
    if (!iInputCommands.empty())
    {
        if (ProcessCommand(iInputCommands.front()))
        {
            if (iInterfaceState != EPVMFNodeCreated
                    && (!iInputCommands.empty() || (iInPort && (iInPort->IncomingMsgQueueSize() > 0)) ||
                        (iDataIn.GetRep() != NULL)))
            {
                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, (0, "PVMFOMXEncNode-%s::Run() - rescheduling after process command", iNodeTypeId));
                RunIfNotReady();
            }
            return;
        }

        if (!iInputCommands.empty())
        {
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, (0, "PVMFOMXEncNode-%s::Run() - rescheduling to process more commands", iNodeTypeId));
            RunIfNotReady();
        }
    }
    else
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, (0, "PVMFOMXEncNode-%s::Run() - Input commands empty", iNodeTypeId));
    }

    if (((iCurrentCommand.size() == 0) && (iInterfaceState != EPVMFNodeStarted)) ||
            ((iCurrentCommand.size() > 0) && (iCurrentCommand.front().iCmd == PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_START) && (iInterfaceState != EPVMFNodeStarted)))
    {
        // rescheduling because of input data will be handled in Command Processing Part
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, (0, "PVMFOMXEncNode-%s::Run() - Node not in Started state yet", iNodeTypeId));
        return;
    }


    // Process port activity, push out all outgoing messages
    if (iOutPort)
    {
        while (iOutPort->OutgoingMsgQueueSize())
        {
            // if port is busy it is going to wakeup from port ready event
            if (!ProcessOutgoingMsg(iOutPort))
            {
                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, (0, "PVMFOMXEncNode-%s::Run() - Outgoing Port Busy, cannot send more msgs", iNodeTypeId));
                break;
            }
        }
    }
    int loopCount = 0;
#if (PVLOGGER_INST_LEVEL >= PVLOGMSG_INST_REL)
    uint32 startticks = OsclTickCount::TickCount();
    uint32 starttime = OsclTickCount::TicksToMsec(startticks);
#endif
    do // Try to consume all the data from the Input port
    {
        // Process port activity if there is no input data that is being processed
        // Do not accept any input if EOS needs to be sent out
        if (iInPort && (iInPort->IncomingMsgQueueSize() > 0) && (iDataIn.GetRep() == NULL) && !iEndOfDataReached)
        {
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, (0, "PVMFOMXEncNode-%s::Run() - Getting more input", iNodeTypeId));
            if (!ProcessIncomingMsg(iInPort))
            {
                //Re-schedule to come back.
                RunIfNotReady();
                return;
            }
        }

        if (iSendBOS)
        {
            SendBeginOfMediaStreamCommand();
        }

        // If in init or ready to encode state, process data in the input port if there is input available and input buffers are present
        // (note: at EOS, iDataIn will not be available)
        if ((iDataIn.GetRep() != NULL) ||
                ((iNumOutstandingOutputBuffers < iNumOutputBuffers) &&
                 (iProcessingState == EPVMFOMXEncNodeProcessingState_ReadyToEncode) &&
                 (iResetMsgSent == false)) ||
                ((iDynamicReconfigInProgress == true) && (iResetMsgSent == false))
           )
        {
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
                            (0, "PVMFOMXEncNode-%s::Run() - Calling HandleProcessingState", iNodeTypeId));

            // input data is available, that means there is data to be encoded
            if (HandleProcessingState() != PVMFSuccess)
            {
                // If HandleProcessingState does not return Success, we must wait for an event
                // no point in  rescheduling
                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
                                (0, "PVMFOMXEncNode-%s::Run() - HandleProcessingState did not return Success", iNodeTypeId));
                return;
            }
        }
        loopCount++;
    }
    while (iInPort &&
            (((iInPort->IncomingMsgQueueSize() > 0) || (iDataIn.GetRep() != NULL)) && (iNumOutstandingInputBuffers < iNumInputBuffers))
            && (!iEndOfDataReached)
            && (iResetMsgSent == false)
          );
#if (PVLOGGER_INST_LEVEL >= PVLOGMSG_INST_REL)
    uint32 endticks = OsclTickCount::TickCount();
    uint32 endtime = OsclTickCount::TicksToMsec(endticks);
    uint32 timeinloop;
    timeinloop  = (endtime - starttime);
    PVLOGGER_LOGMSG(PVLOGMSG_INST_REL, iRunlLogger, PVLOGMSG_INFO,
                    (0, "PVMFOMXEncNode-%s::Run() - LoopCount = %d, Time spent in loop(in ms) = %d, iNumOutstandingInputBuffers = %d, iNumOutstandingOutputBuffers = %d ", iNodeTypeId,
                     loopCount, timeinloop, iNumOutstandingInputBuffers, iNumOutstandingOutputBuffers));
#endif
    // EOS processing:
    // first send an empty buffer to OMX component and mark the EOS flag
    // wait for the OMX component to send async event to indicate that it has reached this EOS buffer
    // then, create and send the EOS message downstream

    if (iEndOfDataReached && !iDynamicReconfigInProgress)
    {

        // if EOS was not sent yet and we have an available input buffer, send EOS buffer to component
        if (!iIsEOSSentToComponent && (iNumOutstandingInputBuffers < iNumInputBuffers))
        {
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
                            (0, "PVMFOMXEncNode-%s::Run() - Sending EOS marked buffer To Component ", iNodeTypeId));

            iIsEOSSentToComponent = true;


            // if the component is not yet initialized or if it's in the middle of port reconfig,
            // don't send EOS buffer to component. It does not care. Just set the flag as if we received
            // EOS from the component to enable sending EOS downstream
            if (iProcessingState != EPVMFOMXEncNodeProcessingState_ReadyToEncode)
            {

                iIsEOSReceivedFromComponent = true;
            }
            else if (!SendEOSBufferToOMXComponent())
            {
                // for some reason, Component can't receive the EOS buffer
                // it could be that it is not initialized yet (because EOS could be the first msg). In this case,
                // send the EOS downstream anyway
                iIsEOSReceivedFromComponent = true;
            }
        }

        // DV: we must wait for event (acknowledgment from component)
        // before sending EOS downstream. This is because OMX Component will send
        // the EOS event only after processing remaining buffers

        if (iIsEOSReceivedFromComponent)
        {

            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
                            (0, "PVMFOMXEncNode-%s::Run() - Received EOS from component, Sending EOS msg downstream ", iNodeTypeId));

            if (iOutPort && iOutPort->IsOutgoingQueueBusy())
            {
                // note: we already tried to empty the outgoing q. If it's still busy,
                // it means that output port is busy. Just return and wait for the port to become free.
                // this will wake up the node and it will send out a msg from the q etc.
                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
                                (0, "PVMFOMXEncNode-%s::Run() - - EOS cannot be sent downstream, outgoing queue busy - wait", iNodeTypeId));
                return;
            }

            if (SendEndOfTrackCommand()) // this will only q the EOS
            {
                // EOS send downstream OK, so reset the flag
                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
                                (0, "PVMFOMXEncNode-%s::Run() - EOS was queued to be sent downstream", iNodeTypeId));

                iEndOfDataReached = false; // to resume normal processing, reset the flags
                iIsEOSSentToComponent = false;
                iIsEOSReceivedFromComponent = false;

                RunIfNotReady(); // Run again to send out the EOS msg from the outgoing q, and resume
                // normal processing

                // END OF STREAM EVENT reported by the downstream node.
                //ReportInfoEvent(PVMFInfoEndOfData);
            }
        }
        else
        {
            // keep sending output buffers, it's possible that the component needs to flush output
            //  data at the end
            while (iNumOutstandingOutputBuffers < iNumOutputBuffers)
            {
                if (!SendOutputBufferToOMXComponent())
                    break;
            }
        }

    }


    //Check for flash command complition...
    if (iInPort && iOutPort && (iCurrentCommand.size() > 0) &&
            (iCurrentCommand.front().iCmd == PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_FLUSH) &&
            (iInPort->IncomingMsgQueueSize() == 0) &&
            (iOutPort->OutgoingMsgQueueSize() == 0) &&
            (iDataIn.GetRep() == NULL) &&
            (iNumOutstandingOutputBuffers == iNumOutputBuffers) && // all output buffers are with the component or outstanding
            (iNumOutstandingInputBuffers == 0) // all input buffers were processed and returned. These 2 conditions mean the component is idle
       )
    {
        //flush command is almost completed
        //Debug check-- all the port queues should be empty at this point.
        OMX_ERRORTYPE err = OMX_ErrorNone;
        OMX_STATETYPE sState = OMX_StateInvalid;

        OSCL_ASSERT(iInPort->IncomingMsgQueueSize() == 0 && iOutPort->OutgoingMsgQueueSize() == 0);

        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, (0, "PVMFOMXEncNode-%s::Run() - Flush pending", iNodeTypeId));

        // now, drive the state of the omx component to IDLE - wait for the callback from the component and send cmd complete from there
        iDataIn.Unbind();
        iPreviousMediaData.Unbind(); // make sure nothing is holding this data
        if ((iOutFormat == PVMF_MIME_H264_VIDEO_MP4) || (iOutFormat == PVMF_MIME_H264_VIDEO_RAW))
        {
            // prepare for next start
            iFirstNAL = true;
        }

        // Clear the data flags

        iEndOfDataReached = false;
        iIsEOSSentToComponent = false;
        iIsEOSReceivedFromComponent = false;


        iDoNotSendOutputBuffersDownstreamFlag = true; // stop sending output buffers downstream
        iDoNotSaveInputBuffersFlag = true;


        //Get state of OpenMAX encoder
        err = OMX_GetState(iOMXEncoder, &sState);
        if (err != OMX_ErrorNone)
        {
            //Error condition report
            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                            (0, "PVMFOMXEncNode-%s::Run(): Flush pending - Can't get State of encoder!", iNodeTypeId));

            sState = OMX_StateInvalid;
        }

        if ((sState == OMX_StateExecuting) || (sState == OMX_StatePause))
        {
            /* Change state to OMX_StateIdle from OMX_StateExecuting or OMX_StatePause. */

            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "PVMFOMXEncNode-%s::Run(): Flush pending:  Changing Component State Executing->Idle or Pause->Idle", iNodeTypeId));

            err = OMX_SendCommand(iOMXEncoder, OMX_CommandStateSet, OMX_StateIdle, NULL);
            if (err != OMX_ErrorNone)
            {
                //Error condition report
                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                                (0, "PVMFOMXEncNode-%s::Run(): Flush pending : Can't send StateSet command to encoder!", iNodeTypeId));

                CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFErrInvalidState);
                return;
            }

            // prevent the node from sending more buffers etc.
            // if port reconfiguration is in process, let the state remain one of the port config states
            //  if there is a start command, we can do it seemlessly (by continuing the port reconfig)
            if (iProcessingState == EPVMFOMXEncNodeProcessingState_ReadyToEncode)
                iProcessingState = EPVMFOMXEncNodeProcessingState_Stopping;

        }
        else
        {
            //Error condition report
            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                            (0, "PVMFOMXEncNode-%s::Run(): Flush pending : Encoder is not in the Executing or Pause state!", iNodeTypeId));

            CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFErrInvalidState);
            return;
        }


    }

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::Run() Out", iNodeTypeId));
}

/////////////////////////////////////////////////////////////////////////////
// This routine will dispatch recived commands
/////////////////////////////////////////////////////////////////////////////
bool PVMFOMXEncNode::ProcessCommand(PVMFOMXEncNodeCommand& aCmd)
{
    //normally this node will not start processing one command
    //until the prior one is finished.  However, a hi priority
    //command such as Cancel must be able to interrupt a command
    //in progress.
    if (!iCurrentCommand.empty() && !aCmd.hipri())
        return false;

    switch (aCmd.iCmd)
    {
        case PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_QUERYUUID:
            DoQueryUuid(aCmd);
            break;

        case PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_QUERYINTERFACE:
            DoQueryInterface(aCmd);
            break;

        case PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_REQUESTPORT:
            DoRequestPort(aCmd);
            break;

        case PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_RELEASEPORT:
            DoReleasePort(aCmd);
            break;

        case PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_INIT:
            DoInit(aCmd);
            break;

        case PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_PREPARE:
            DoPrepare(aCmd);
            break;

        case PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_START:
            DoStart(aCmd);
            break;

        case PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_STOP:
            DoStop(aCmd);
            break;

        case PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_FLUSH:
            DoFlush(aCmd);
            break;

        case PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_PAUSE:
            DoPause(aCmd);
            break;

        case PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_RESET:
            DoReset(aCmd);
            break;

        case PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_CANCELCMD:
            DoCancelCommand(aCmd);
            break;

        case PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_CANCELALL:
            DoCancelAllCommands(aCmd);
            break;

        case PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_GETNODEMETADATAKEY:
        {
            PVMFStatus retval = DoGetNodeMetadataKey(aCmd);
            CommandComplete(iInputCommands, aCmd, retval);
        }
        break;

        case PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_GETNODEMETADATAVALUE:
        {
            PVMFStatus retval = DoGetNodeMetadataValue(aCmd);
            CommandComplete(iInputCommands, aCmd, retval);
        }
        break;

        default://unknown command type
            CommandComplete(iInputCommands, aCmd, PVMFFailure);
            break;
    }

    return true;
}

/////////////////////////////////////////////////////////////////////////////
// This routine will process incomming message from the port
/////////////////////////////////////////////////////////////////////////////
bool PVMFOMXEncNode::ProcessIncomingMsg(PVMFPortInterface* aPort)
{
    //Called by the AO to process one buffer off the port's
    //incoming data queue.  This routine will dequeue and
    //dispatch the data.

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "0x%x PVMFOMXEncNode-%s::ProcessIncomingMsg: aPort=0x%x", this, iNodeTypeId, aPort));

    PVMFStatus status = PVMFFailure;


    //#define SIMULATE_BOS
#ifdef SIMULATE_BOS

    if (((PVMFOMXEncPort*)aPort)->iNumFramesConsumed == 6))
    {

        PVMFSharedMediaCmdPtr BOSCmdPtr = PVMFMediaCmd::createMediaCmd();

        // Set the format ID to BOS
        BOSCmdPtr->setFormatID(PVMF_MEDIA_CMD_BOS_FORMAT_ID);

        // Set the timestamp
        BOSCmdPtr->setTimestamp(201);
        BOSCmdPtr->setStreamID(0);

        // Convert to media message and send it out
        PVMFSharedMediaMsgPtr mediaMsgOut;
        convertToPVMFMediaCmdMsg(mediaMsgOut, BOSCmdPtr);

        //store the stream id and time stamp of bos message
        iStreamID = mediaMsgOut->getStreamID();
        iBOSTimestamp = mediaMsgOut->getTimestamp();

        iInputTimestampClock.set_clock(iBOSTimestamp, 0);
        iOMXTicksTimestamp = ConvertTimestampIntoOMXTicks(iInputTimestampClock);

        iSendBOS = true;

#ifdef _DEBUG
        printf("PVMFOMXEncNode-%s::ProcessIncomingMsg() SIMULATED BOS\n", iNodeTypeId);
#endif
        ((PVMFOMXEncPort*)aPort)->iNumFramesConsumed++;
        return true;

    }
#endif
//#define SIMULATE_PREMATURE_EOS
#ifdef SIMULATE_PREMATURE_EOS
    if (((PVMFOMXEncPort*)aPort)->iNumFramesConsumed == 5)
    {
        PVMFSharedMediaCmdPtr EOSCmdPtr = PVMFMediaCmd::createMediaCmd();

        // Set the format ID to EOS
        EOSCmdPtr->setFormatID(PVMF_MEDIA_CMD_EOS_FORMAT_ID);

        // Set the timestamp
        EOSCmdPtr->setTimestamp(200);

        // Convert to media message and send it out
        PVMFSharedMediaMsgPtr mediaMsgOut;
        convertToPVMFMediaCmdMsg(mediaMsgOut, EOSCmdPtr);

        ((PVMFOMXEncPort*)aPort)->iNumFramesConsumed++;

        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::ProcessIncomingMsg: SIMULATED EOS", iNodeTypeId));
#ifdef _DEBUG
        printf("PVMFOMXEncNode-%s::ProcessIncomingMsg() SIMULATED EOS\n", iNodeTypeId);
#endif
        // Set EOS flag
        iEndOfDataReached = true;
        // Save the timestamp for the EOS cmd
        iEndOfDataTimestamp = mediaMsgOut->getTimestamp();

        return true;
    }

#endif



    PVMFSharedMediaMsgPtr msg;

    status = aPort->DequeueIncomingMsg(msg);
    if (status != PVMFSuccess)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
                    (0, "0x%x PVMFOMXEncNode-%s::ProcessIncomingMsg: Error - DequeueIncomingMsg failed", this, iNodeTypeId));
        return false;
    }

    if (msg->getFormatID() == PVMF_MEDIA_CMD_BOS_FORMAT_ID)
    {
        //store the stream id and time stamp of bos message
        iStreamID = msg->getStreamID();
        iBOSTimestamp = msg->getTimestamp();

        // we need to initialize the timestamp here - so that updates later on are accurate (in terms of rollover etc)
        iInputTimestampClock.set_clock(iBOSTimestamp, 0);
        iOMXTicksTimestamp = ConvertTimestampIntoOMXTicks(iInputTimestampClock);

        iSendBOS = true;

        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::ProcessIncomingMsg: Received BOS stream %d, timestamp %d", iNodeTypeId, iStreamID, iBOSTimestamp));
        ((PVMFOMXEncPort*)aPort)->iNumFramesConsumed++;
        return true;
    }
    else if (msg->getFormatID() == PVMF_MEDIA_CMD_EOS_FORMAT_ID)
    {
        // Set EOS flag
        iEndOfDataReached = true;
        // Save the timestamp for the EOS cmd
        iEndOfDataTimestamp = msg->getTimestamp();

        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::ProcessIncomingMsg: Received EOS", iNodeTypeId));

        ((PVMFOMXEncPort*)aPort)->iNumFramesConsumed++;
        return true; // do not do conversion into media data, just set the flag and leave
    }

    convertToPVMFMediaData(iDataIn, msg);


    iCurrFragNum = 0; // for new message, reset the fragment counter


    ((PVMFOMXEncPort*)aPort)->iNumFramesConsumed++;
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::ProcessIncomingMsg() Received %d frames", iNodeTypeId, ((PVMFOMXEncPort*)aPort)->iNumFramesConsumed));

//return true if we processed an activity...
    return true;
}

/////////////////////////////////////////////////////////////////////////////
// This routine will process outgoing message by sending it into output the port
/////////////////////////////////////////////////////////////////////////////
bool PVMFOMXEncNode::ProcessOutgoingMsg(PVMFPortInterface* aPort)
{
    //Called by the AO to process one message off the outgoing
    //message queue for the given port.  This routine will
    //try to send the data to the connected port.

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "0x%x PVMFOMXEncNode-%s::ProcessOutgoingMsg: aPort=0x%x", this, iNodeTypeId, aPort));

    PVMFStatus status = aPort->Send();
    if (status == PVMFErrBusy)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
                        (0, "0x%x PVMFOMXEncNode-%s::ProcessOutgoingMsg: Connected port goes into busy state", this, iNodeTypeId));
    }

    //Report any unexpected failure in port processing...
    //(the InvalidState error happens when port input is suspended,
    //so don't report it.)
    if (status != PVMFErrBusy
            && status != PVMFSuccess
            && status != PVMFErrInvalidState)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
                        (0, "0x%x PVMFOMXEncNode-%s::ProcessOutgoingMsg: Error - ProcessPortActivity failed. port=0x%x, type=%d",
                         this, iNodeTypeId, iOutPort, PVMF_PORT_ACTIVITY_OUTGOING_MSG));
        ReportErrorEvent(PVMFErrPortProcessing);
    }

    //return true if we processed an activity...
    return (status != PVMFErrBusy);
}

/////////////////////////////////////////////////////////////////////////////
// This routine will process received data usign State Machine
/////////////////////////////////////////////////////////////////////////////
PVMFStatus PVMFOMXEncNode::HandleProcessingState()
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::HandleProcessingState() In", iNodeTypeId));

    PVMFStatus status = PVMFSuccess;

    switch (iProcessingState)
    {

            // The FOLLOWING 4 states handle Dynamic Port Reconfiguration
        case EPVMFOMXEncNodeProcessingState_PortReconfig:
        {
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "PVMFOMXEncNode-%s::HandleProcessingState() Port Reconfiguration -> Sending Port Disable Command", iNodeTypeId));

            // port reconfiguration is required. Only one port at a time is disabled and then re-enabled after buffer resizing
            OMX_SendCommand(iOMXEncoder, OMX_CommandPortDisable, iPortIndexForDynamicReconfig, NULL);
            // the port will now start returning outstanding buffers
            // set the flag to prevent output from going downstream (in case of output port being reconfigd)
            // set the flag to prevent input from being saved and returned to component (in case of input port being reconfigd)
            // set the state to wait for port saying it is disabled
            if (iPortIndexForDynamicReconfig == iOutputPortIndex)
            {
                iDoNotSendOutputBuffersDownstreamFlag = true;
            }
            else if (iPortIndexForDynamicReconfig == iInputPortIndex)
            {
                iDoNotSaveInputBuffersFlag = true;

            }
            iProcessingState = EPVMFOMXEncNodeProcessingState_WaitForBufferReturn;


            // fall through to the next case to check if all buffers are already back
        }

        case EPVMFOMXEncNodeProcessingState_WaitForBufferReturn:
        {
            // as buffers are coming back, Run may be called, wait until all buffers are back, then Free them all

            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "PVMFOMXEncNode-%s::HandleProcessingState() Port Reconfiguration -> WaitForBufferReturn ", iNodeTypeId));
            // check if it's output port being reconfigured
            if (iPortIndexForDynamicReconfig == iOutputPortIndex)
            {
                // if all buffers have returned, free them
                if (iNumOutstandingOutputBuffers == 0)
                {
                    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                                    (0, "PVMFOMXEncNode-%s::HandleProcessingState() Port Reconfiguration -> all output buffers are back, free them", iNodeTypeId));
                    if (false == iOutputBuffersFreed)
                    {
                        if (!FreeBuffersFromComponent(iOutBufMemoryPool, // allocator
                                                      iOutputAllocSize,  // size to allocate from pool (hdr only or hdr+ buffer)
                                                      iNumOutputBuffers, // number of buffers
                                                      iOutputPortIndex, // port idx
                                                      false // this is not input
                                                     ))
                        {
                            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                                            (0, "PVMFOMXEncNode-%s::HandleProcessingState() Port Reconfiguration -> Cannot free output buffers ", iNodeTypeId));

                            SetState(EPVMFNodeError);
                            ReportErrorEvent(PVMFErrNoMemory);
                            return PVMFErrNoMemory;
                        }
                    }
                    // if the callback (that port is disabled) has not arrived yet, wait for it
                    // if it has arrived, it will set the state to PortReEnable
                    if (iProcessingState != EPVMFOMXEncNodeProcessingState_PortReEnable)
                        iProcessingState = EPVMFOMXEncNodeProcessingState_WaitForPortDisable;

                    status = PVMFSuccess; // allow rescheduling of the node potentially
                }
                else
                    status = PVMFErrNoMemory; // must wait for buffers to come back. No point in automatic rescheduling
                // but each buffer will reschedule the node when it comes in
            }
            else
            {
                // this is input port

                // if all buffers have returned, free them
                if (iNumOutstandingInputBuffers == 0)
                {

                    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                                    (0, "PVMFOMXEncNode-%s::HandleProcessingState() Port Reconfiguration -> all input buffers are back, free them", iNodeTypeId));
                    if (false == iInputBuffersFreed)
                    {
                        if (!FreeBuffersFromComponent(iInBufMemoryPool, // allocator
                                                      iInputAllocSize,   // size to allocate from pool (hdr only or hdr+ buffer)
                                                      iNumInputBuffers, // number of buffers
                                                      iInputPortIndex, // port idx
                                                      true // this is input
                                                     ))
                        {
                            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                                            (0, "PVMFOMXEncNode-%s::HandleProcessingState() Port Reconfiguration -> Cannot free input buffers ", iNodeTypeId));

                            SetState(EPVMFNodeError);
                            ReportErrorEvent(PVMFErrNoMemory);
                            return PVMFErrNoMemory;

                        }
                    }
                    // if the callback (that port is disabled) has not arrived yet, wait for it
                    // if it has arrived, it will set the state to PortReEnable
                    if (iProcessingState != EPVMFOMXEncNodeProcessingState_PortReEnable)
                        iProcessingState = EPVMFOMXEncNodeProcessingState_WaitForPortDisable;

                    status = PVMFSuccess; // allow rescheduling of the node
                }
                else
                    status = PVMFErrNoMemory; // must wait for buffers to come back. No point in automatic
                // rescheduling. Each buffer will reschedule the node
                // when it comes in
            }


            // the state will be changed to PortReEnable once we get confirmation that Port was actually disabled
            break;
        }

        case EPVMFOMXEncNodeProcessingState_WaitForPortDisable:
        {

            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "PVMFOMXEncNode-%s::HandleProcessingState() Port Reconfiguration -> wait for port disable callback", iNodeTypeId));
            // do nothing. Just wait for the port to become disabled (we'll get event from component, which will
            // transition the state to PortReEnable
            status = PVMFErrNoMemory; // prevent Rescheduling the node
            break;
        }

        case EPVMFOMXEncNodeProcessingState_PortReEnable:
        {

            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "PVMFOMXEncNode-%s::HandleProcessingState() Port Reconfiguration -> Sending reenable port command", iNodeTypeId));
            // set the port index so that we get parameters for the proper port
            iParamPort.nPortIndex = iPortIndexForDynamicReconfig;
            // iParamPort.nVersion = OMX_VERSION;

            // get new parameters of the port
            OMX_GetParameter(iOMXEncoder, OMX_IndexParamPortDefinition, &iParamPort);

            // send command for port re-enabling (for this to happen, we must first recreate the buffers)
            OMX_SendCommand(iOMXEncoder, OMX_CommandPortEnable, iPortIndexForDynamicReconfig, NULL);

            // is this output port?
            if (iPortIndexForDynamicReconfig == iOutputPortIndex)
            {
                iOMXComponentOutputBufferSize = ((iParamPort.format.video.nFrameWidth + 15) & (~15)) * ((iParamPort.format.video.nFrameHeight + 15) & (~15)) * 3 / 2;

                // check the new buffer size
                if (iInPort)
                {
                    if (((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO ||
                            ((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO_MP4 ||
                            ((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO_RAW ||
                            ((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_M4V ||
                            ((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_H2631998 ||
                            ((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_H2632000)
                    {
                        iOMXComponentOutputBufferSize = ((iParamPort.format.video.nFrameWidth + 15) & (~15)) * ((iParamPort.format.video.nFrameHeight + 15) & (~15)) * 3 / 2;
                    }
                    else if (((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_WMV)
                    {
                        // This is a requirement for the WMV encoder that we have currently
                        iOMXComponentOutputBufferSize = ((iParamPort.format.video.nFrameWidth + 3) & (~3)) * (iParamPort.format.video.nFrameHeight) * 3 / 2;
                    }
                    else
                    {
                        OSCL_ASSERT(false);
                    }
                }
                // set the new width / height
                iYUVWidth =  iParamPort.format.video.nFrameWidth;
                iYUVHeight = iParamPort.format.video.nFrameHeight;

                if (iOMXComponentOutputBufferSize < iParamPort.nBufferSize)
                    iOMXComponentOutputBufferSize = iParamPort.nBufferSize;

                // do we need to increase the number of buffers?
                if (iNumOutputBuffers < iParamPort.nBufferCountMin)
                    iNumOutputBuffers = iParamPort.nBufferCountMin;

                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                                (0, "PVMFOMXEncNode-%s::HandleProcessingState() new output buffers %d, size %d", iNodeTypeId, iNumOutputBuffers, iOMXComponentOutputBufferSize));

                /* Allocate output buffers */
                if (!CreateOutMemPool(iNumOutputBuffers))
                {

                    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                                    (0, "PVMFOMXEncNode-%s::HandleProcessingState() Port Reconfiguration -> Cannot allocate output buffers ", iNodeTypeId));

                    SetState(EPVMFNodeError);
                    ReportErrorEvent(PVMFErrNoMemory);
                    return PVMFErrNoMemory;
                }

                if (!ProvideBuffersToComponent(iOutBufMemoryPool, // allocator
                                               iOutputAllocSize,     // size to allocate from pool (hdr only or hdr+ buffer)
                                               iNumOutputBuffers, // number of buffers
                                               iOMXComponentOutputBufferSize, // actual buffer size
                                               iOutputPortIndex, // port idx
                                               iOMXComponentSupportsExternalOutputBufferAlloc, // can component use OMX_UseBuffer
                                               false // this is not input
                                              ))
                {


                    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                                    (0, "PVMFOMXEncNode-%s::HandleProcessingState() Port Reconfiguration -> Cannot provide output buffers to component", iNodeTypeId));

                    SetState(EPVMFNodeError);
                    ReportErrorEvent(PVMFErrNoMemory);
                    return PVMFErrNoMemory;

                }

                // do not drop output any more, i.e. enable output to be sent downstream
                iDoNotSendOutputBuffersDownstreamFlag = false;


            }
            else
            {
                // this is input port

                iOMXComponentInputBufferSize = iParamPort.nBufferSize;
                // do we need to increase the number of buffers?
                if (iNumInputBuffers < iParamPort.nBufferCountMin)
                    iNumInputBuffers = iParamPort.nBufferCountMin;

                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                                (0, "PVMFOMXEncNode-%s::HandleProcessingState() new buffers %d, size %d", iNodeTypeId, iNumInputBuffers, iOMXComponentInputBufferSize));

                /* Allocate input buffers */
                if (!CreateInputMemPool(iNumInputBuffers))
                {
                    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                                    (0, "PVMFOMXEncNode-%s::HandleProcessingState() Port Reconfiguration -> Cannot allocate new input buffers to component", iNodeTypeId));

                    SetState(EPVMFNodeError);
                    ReportErrorEvent(PVMFErrNoMemory);
                    return PVMFErrNoMemory;
                }

                if (!ProvideBuffersToComponent(iInBufMemoryPool, // allocator
                                               iInputAllocSize,  // size to allocate from pool (hdr only or hdr+ buffer)
                                               iNumInputBuffers, // number of buffers
                                               iOMXComponentInputBufferSize, // actual buffer size
                                               iInputPortIndex, // port idx
                                               iOMXComponentSupportsExternalInputBufferAlloc, // can component use OMX_UseBuffer
                                               true // this is input
                                              ))
                {


                    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                                    (0, "PVMFOMXEncNode-%s::HandleProcessingState() Port Reconfiguration -> Cannot provide new input buffers to component", iNodeTypeId));

                    SetState(EPVMFNodeError);
                    ReportErrorEvent(PVMFErrNoMemory);
                    return PVMFErrNoMemory;

                }
                // do not drop partially consumed input
                iDoNotSaveInputBuffersFlag = false;


            }

            // if the callback that the port was re-enabled has not arrived yet, wait for it
            // if it has arrived, it will set the state to either PortReconfig or to ReadyToEncode
            if (iProcessingState != EPVMFOMXEncNodeProcessingState_PortReconfig &&
                    iProcessingState != EPVMFOMXEncNodeProcessingState_ReadyToEncode)
                iProcessingState = EPVMFOMXEncNodeProcessingState_WaitForPortEnable;

            status = PVMFSuccess; // allow rescheduling of the node
            break;
        }

        case EPVMFOMXEncNodeProcessingState_WaitForPortEnable:
        {
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "PVMFOMXEncNode-%s::HandleProcessingState() Port Reconfiguration -> wait for port enable callback", iNodeTypeId));
            // do nothing. Just wait for the port to become enabled (we'll get event from component, which will
            // transition the state to ReadyToEncode
            status = PVMFErrNoMemory; // prevent ReScheduling
            break;
        }

        // NORMAL DATA FLOW STATE:
        case EPVMFOMXEncNodeProcessingState_ReadyToEncode:
        {

            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "PVMFOMXEncNode-%s::HandleProcessingState() Ready To Encode start", iNodeTypeId));
            // In normal data flow and decoding state
            // Send all available output buffers to the encoder

            while (iNumOutstandingOutputBuffers < iNumOutputBuffers)
            {
                // grab buffer header from the mempool if possible, and send to component
                if (!SendOutputBufferToOMXComponent())

                    break;

            }


            // next, see if partially consumed input buffer needs to be resent back to OMX component
            // NOTE: it is not allowed that the component returns more than 1 partially consumed input buffers
            //       i.e. if a partially consumed input buffer is returned, it is assumed that the OMX component
            //       will be waiting to get data

            if (iInputBufferToResendToComponent != NULL)
            {
                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
                                (0, "PVMFOMXEncNode-%s::HandleProcessingState() Sending previous - partially consumed input back to the OMX component", iNodeTypeId));

                OMX_EmptyThisBuffer(iOMXEncoder, iInputBufferToResendToComponent);
                iInputBufferToResendToComponent = NULL; // do this only once
            }
            else if ((iNumOutstandingInputBuffers < iNumInputBuffers) && (iDataIn.GetRep() != NULL))
            {
                // try to get an input buffer header
                // and send the input data over to the component
                SendInputBufferToOMXComponent();
            }

            status = PVMFSuccess;
            break;


        }
        case EPVMFOMXEncNodeProcessingState_Stopping:
        {

            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "PVMFOMXEncNode-%s::HandleProcessingState() Stopping -> wait for Component to move from Executing->Idle", iNodeTypeId));


            status = PVMFErrNoMemory; // prevent rescheduling
            break;
        }

        case EPVMFOMXEncNodeProcessingState_WaitForOutgoingQueue:
            status = PVMFErrNoMemory;
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::HandleProcessingState() Do nothing since waiting for output port queue to become available", iNodeTypeId));
            break;

        default:
            break;
    }

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::HandleProcessingState() Out", iNodeTypeId));

    return status;

}
/////////////////////////////////////////////////////////////////////////////
bool PVMFOMXEncNode::SendOutputBufferToOMXComponent()
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFOMXEncNode-%s::SendOutputBufferToOMXComponent() In", iNodeTypeId));


    OutputBufCtrlStruct *output_buf = NULL;
    int32  errcode = 0;
    uint32 ii;

    // try to get output buffer header
    OSCL_TRY(errcode, output_buf = (OutputBufCtrlStruct *) iOutBufMemoryPool->allocate(iOutputAllocSize));
    if (errcode != 0)
    {
        if (errcode == OsclErrNoResources)
        {

            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger,
                            PVLOGMSG_DEBUG, (0, "PVMFOMXEncNode-%s::SendOutputBufferToOMXComponent() No more output buffers in the mempool", iNodeTypeId));

            iOutBufMemoryPool->notifyfreechunkavailable(*this, (OsclAny *) iOutBufMemoryPool); // To signal when next deallocate() is called on mempool

            return false;
        }
        else
        {
            // Memory allocation for the pool failed
            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                            (0, "PVMFOMXEncNode-%s::SendOutputBufferToOMXComponent() Output mempool error", iNodeTypeId));


            SetState(EPVMFNodeError);
            ReportErrorEvent(PVMFErrNoMemory);
            return false;
        }

    }

    //for every allocated buffer, make sure you notify when buffer is released. Keep track of allocated buffers
    // use mempool as context to recognize which buffer (input or output) was returned
    iOutBufMemoryPool->notifyfreechunkavailable(*this, (OsclAny *)iOutBufMemoryPool);
    iNumOutstandingOutputBuffers++;

    for (ii = 0; ii < iNumOutputBuffers; ii++)
    {
        if (output_buf == out_ctrl_struct_ptr[ii])
        {
            break;
        }
    }

    if (ii == iNumOutputBuffers)
        return false;

    output_buf->pBufHdr = (OMX_BUFFERHEADERTYPE *)out_buff_hdr_ptr[ii];



    output_buf->pBufHdr->nFilledLen = 0; // make sure you tell OMX component buffer is empty
    output_buf->pBufHdr->nOffset = 0;
    output_buf->pBufHdr->pAppPrivate = output_buf; // set pAppPrivate to be pointer to output_buf
    // (this is context for future release of this buffer to the mempool)
    // this was done during buffer creation, but still repeat just in case

    output_buf->pBufHdr->nFlags = 0; // zero out the flags
    OMX_FillThisBuffer(iOMXEncoder, output_buf->pBufHdr);



    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFOMXEncNode-%s::SendOutputBufferToOMXComponent() Out", iNodeTypeId));

    return true;
}
////////////////////////////////////////////////////////////////////////////////
bool PVMFOMXEncNode::NegotiateVideoComponentParameters()
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFOMXEncNode-%s::NegotiateVideoParameters() In", iNodeTypeId));

    OMX_ERRORTYPE Err;
    OMX_CONFIG_ROTATIONTYPE InputRotationType;

    // first get the number of ports and port indices
    OMX_PORT_PARAM_TYPE VideoPortParameters;
    uint32 NumPorts;
    uint32 ii;

    // get starting number
    CONFIG_SIZE_AND_VERSION(VideoPortParameters);

    Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamVideoInit, &VideoPortParameters);
    NumPorts = VideoPortParameters.nPorts; // must be at least 2 of them (in&out)

    if (Err != OMX_ErrorNone || NumPorts < 2)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::NegotiateVideoComponentParameters() There is insuffucient (%d) ports", iNodeTypeId, NumPorts));
        return false;
    }


    // loop through video ports starting from the starting index to find index of the first input port
    for (ii = VideoPortParameters.nStartPortNumber ; ii < VideoPortParameters.nStartPortNumber + NumPorts; ii++)
    {
        // get port parameters, and determine if it is input or output
        // if there are more than 2 ports, the first one we encounter that has input direction is picked


        CONFIG_SIZE_AND_VERSION(iParamPort);
        //port
        iParamPort.nPortIndex = ii; // iInputPortIndex; //OMF_MC_H264D_PORT_INDEX_OF_STREAM;
        Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamPortDefinition, &iParamPort);

        if (Err != OMX_ErrorNone)
        {
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "PVMFOMXEncNode-%s::NegotiateVideoComponentParameters() Problem negotiating with port %d ", iNodeTypeId, ii));

            return false;
        }

        if (iParamPort.eDir == OMX_DirInput)
        {
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "PVMFOMXEncNode-%s::NegotiateVideoComponentParameters() Found Input port index %d ", iNodeTypeId, ii));

            iInputPortIndex = ii;
            break;
        }
    }
    if (ii == VideoPortParameters.nStartPortNumber + NumPorts)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::NegotiateVideoComponentParameters() Cannot find any input port ", iNodeTypeId));
        return false;
    }


    // loop through video ports starting from the starting index to find index of the first output port
    for (ii = VideoPortParameters.nStartPortNumber ; ii < VideoPortParameters.nStartPortNumber + NumPorts; ii++)
    {
        // get port parameters, and determine if it is input or output
        // if there are more than 2 ports, the first one we encounter that has output direction is picked


        CONFIG_SIZE_AND_VERSION(iParamPort);
        //port
        iParamPort.nPortIndex = ii;
        Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamPortDefinition, &iParamPort);

        if (Err != OMX_ErrorNone)
        {
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "PVMFOMXEncNode-%s::NegotiateVideoComponentParameters() Problem negotiating with port %d ", iNodeTypeId, ii));

            return false;
        }

        if (iParamPort.eDir == OMX_DirOutput)
        {
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "PVMFOMXEncNode-%s::NegotiateVideoComponentParameters() Found Output port index %d ", iNodeTypeId, ii));

            iOutputPortIndex = ii;
            break;
        }
    }
    if (ii == VideoPortParameters.nStartPortNumber + NumPorts)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::NegotiateVideoComponentParameters() Cannot find any output port ", iNodeTypeId));
        return false;
    }



    // now get input parameters


    //INPUT PORT

    // first check if encode parameters have been set correctly
    if ((0 == iVideoEncodeParam.iFrameWidth[0]) ||
            (0 == iVideoEncodeParam.iFrameHeight[0]) ||
            (0 == iVideoEncodeParam.iFrameRate[0])   ||
            (0 == iVideoEncodeParam.iBitRate[0]) ||
            (0 == iVideoInputFormat.iFrameWidth) ||
            (0 == iVideoInputFormat.iFrameHeight) ||
            (0 == iVideoInputFormat.iFrameRate)
       )
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::NegotiateVideoComponentParameters() Encode parameters not set correctly", iNodeTypeId));
        return false;
    }

    // first of all, check if the port supports the adequate port format
    OMX_VIDEO_PARAM_PORTFORMATTYPE Video_port_format;
    OMX_COLOR_FORMATTYPE DesiredPortColorFormat;

    if (iInFormat == PVMF_MIME_RGB24)
    {
        DesiredPortColorFormat = OMX_COLOR_Format24bitRGB888;
    }
    else if (iInFormat == PVMF_MIME_RGB12)
    {
        DesiredPortColorFormat = OMX_COLOR_Format12bitRGB444;
    }
    else if (iInFormat == PVMF_MIME_YUV420)
    {
        //TODO: get color format from MIO. JJ 03/09/09
        DesiredPortColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
        //DesiredPortColorFormat = OMX_COLOR_FormatYUV420Planar;
    }
    else if (iInFormat == PVMF_MIME_YUV422_INTERLEAVED_UYVY)
    {
        DesiredPortColorFormat = OMX_COLOR_FormatCbYCrY;
    }
    else if (iInFormat == PVMF_MIME_YUV422_INTERLEAVED_YUYV)
    {
        DesiredPortColorFormat = OMX_COLOR_FormatYCbYCr;
    }
    else
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::NegotiateVideoComponentParameters() Problem with input port %d color format", iNodeTypeId, iInputPortIndex));
        return false;
    }

    CONFIG_SIZE_AND_VERSION(Video_port_format);

    Video_port_format.nPortIndex = iInputPortIndex; // set input port as target

    // loop over supported formats until we hit the one we want
    // or until the component has no more supported formats (in which case it returns OMX_ErrorNoMore
    Err = OMX_ErrorNone;
    Video_port_format.nIndex = 0; //init the format counter
    while (OMX_ErrorNone == Err)
    {

        Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamVideoPortFormat, &Video_port_format);
        if ((OMX_ErrorNone != Err))
        {
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "PVMFOMXEncNode-%s::NegotiateVideoComponentParameters() Problem getting port format for input port %d or no desired port format found", iNodeTypeId, iInputPortIndex));
            return false;
        }

        if ((Video_port_format.eColorFormat == DesiredPortColorFormat))
            break;

        Video_port_format.nIndex ++;
    }

    // OK, we've found the desired format, set it as the one used
    Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamVideoPortFormat, &Video_port_format);
    if ((OMX_ErrorNone != Err))
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::NegotiateVideoComponentParameters() Problem setting port format for input port %d ", iNodeTypeId, iInputPortIndex));
        return false;
    }



    CONFIG_SIZE_AND_VERSION(iParamPort);
    iParamPort.nPortIndex = iInputPortIndex;
    Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamPortDefinition, &iParamPort);
    if (Err != OMX_ErrorNone)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::NegotiateVideoComponentParameters() Problem negotiating with input port %d ", iNodeTypeId, iInputPortIndex));
        return false;
    }

    if (iInFormat == PVMF_MIME_RGB24)
    {
        iOMXComponentInputBufferSize = (iVideoInputFormat.iFrameWidth * iVideoInputFormat.iFrameHeight * 3);
        iParamPort.format.video.eColorFormat = OMX_COLOR_Format24bitRGB888;
    }
    else if (iInFormat == PVMF_MIME_RGB12)
    {
        iOMXComponentInputBufferSize = (iVideoInputFormat.iFrameWidth * iVideoInputFormat.iFrameHeight * 2);
        iParamPort.format.video.eColorFormat = OMX_COLOR_Format12bitRGB444;
    }
    else if (iInFormat == PVMF_MIME_YUV420)
    {
        iOMXComponentInputBufferSize = (iVideoInputFormat.iFrameWidth * iVideoInputFormat.iFrameHeight * 3) >> 1;
        //TODO: get color format from MIO. JJ 03/09/09
        iParamPort.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
        //iParamPort.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar;
    }
    else if (iInFormat == PVMF_MIME_YUV422_INTERLEAVED_UYVY)
    {
        iOMXComponentInputBufferSize = iVideoInputFormat.iFrameWidth * iVideoInputFormat.iFrameHeight * 2;
        iParamPort.format.video.eColorFormat = OMX_COLOR_FormatCbYCrY;
    }
    else if (iInFormat == PVMF_MIME_YUV422_INTERLEAVED_YUYV)
    {
        iOMXComponentInputBufferSize = iVideoInputFormat.iFrameWidth * iVideoInputFormat.iFrameHeight * 2;
        iParamPort.format.video.eColorFormat = OMX_COLOR_FormatYCbYCr;
    }
    else
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::NegotiateVideoComponentParameters() Problem with input port %d color format", iNodeTypeId, iInputPortIndex));
        return false;
    }

    //The input buffer size is a read-only parameter and the encoder component needs to adjust it.
    // We (the client) determine the size of the buffers based on width/height -
    // the component doesn't know width/height yet

    //iParamPort.nBufferSize = iOMXComponentInputBufferSize;

    // set the width and height of video frame and input framerate

    iParamPort.format.video.nFrameWidth = iVideoInputFormat.iFrameWidth;
    iParamPort.format.video.nFrameHeight = iVideoInputFormat.iFrameHeight;
    // This is Q16 value, so shift by 16 first and cast to preserve accuracy
    iParamPort.format.video.xFramerate = (uint32)(iVideoInputFormat.iFrameRate * (1 << 16));

    // indicate that input is uncompressed so that color format is valid
    iParamPort.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;


    // let the component decide about the number of input buffers
    iNumInputBuffers = iParamPort.nBufferCountActual;

    // do we need to increase the number of buffers?
    if (iNumInputBuffers < iParamPort.nBufferCountMin)
        iNumInputBuffers = iParamPort.nBufferCountMin;


    /*  OMX_UseBuffer, ie. if OMX client instead of OMX component is to allocate buffers,
    *   if the buffers are allocated in MIO, check MIO allocator the max number of buffers;
    *   else (the buffer is allocated by OMX client itself) floor the number of buffers to  NUMBER_INPUT_BUFFER
    *   validate with OMX component whether it is ok with the number decided above.
    *   Note: the spec says in OMX_UseBuffer, the OMX client can decide number of input buffers.
    */
    if(iOMXComponentSupportsExternalInputBufferAlloc)
    {
        ipExternalInputBufferAllocatorInterface = NULL;
        PvmiKvp* kvp = NULL;
        int numKvp = 0;
        PvmiKeyType aIdentifier = (PvmiKeyType)PVMF_BUFFER_ALLOCATOR_KEY;
        int32 err, err1;
        OSCL_TRY(err, ((PVMFOMXEncPort*)iInPort)->pvmiGetBufferAllocatorSpecificInfoSync(aIdentifier, kvp, numKvp););

        if ((err == OsclErrNone) && (NULL != kvp))
        {
            ipExternalInputBufferAllocatorInterface = (PVInterface*) kvp->value.key_specific_value;

            if (ipExternalInputBufferAllocatorInterface)
            {
                PVInterface* pTempPVInterfacePtr = NULL;

                OSCL_TRY(err, ipExternalInputBufferAllocatorInterface->queryInterface(PVMFFixedSizeBufferAllocUUID, pTempPVInterfacePtr););

                OSCL_TRY(err1, ((PVMFOMXEncPort*)iInPort)->releaseParametersSync(kvp, numKvp););
                OSCL_FIRST_CATCH_ANY(err1,
                        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
                            (0, "PVMFOMXEncNode-%s::NegotiateComponentParameters() - Unable to Release Parameters", iNodeTypeId));
                        );

                if ((err == OsclErrNone) && (NULL != pTempPVInterfacePtr))
                {
                    ipFixedSizeBufferAlloc = OSCL_STATIC_CAST(PVMFFixedSizeBufferAlloc*, pTempPVInterfacePtr);

                    uint32 iNumBuffers = ipFixedSizeBufferAlloc->getNumBuffers();
                    uint32 iBufferSize = ipFixedSizeBufferAlloc->getBufferSize();

                    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
                            (0, "PVMFOMXEncNode-%s iNumBuffers %d iBufferSize %d iOMXComponentInputBufferSize %d iParamPort.nBufferCountMin %d", iNodeTypeId, iNumBuffers , iBufferSize , iOMXComponentInputBufferSize, iParamPort.nBufferCountMin ) );

                    //TODO should let camera decide number of buffers.
                    if ((iNumBuffers < iParamPort.nBufferCountMin) || (iBufferSize < iOMXComponentInputBufferSize ))
                    {
                        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
                            (0, "PVMFOMXEncNode-%s::NegotiateComponentParameters() - not enough buffer. Got %d x %d. Require %d x %d", iNodeTypeId, iNumBuffers , iBufferSize , iOMXComponentInputBufferSize, iParamPort.nBufferCountMin));
                        //ipFixedSizeBufferAlloc = NULL;

                        ipExternalInputBufferAllocatorInterface->removeRef();
                        ipExternalInputBufferAllocatorInterface = NULL;
                    }
                    else
                    {
                        iNumInputBuffers = iNumBuffers;
                        iOMXComponentInputBufferSize = iBufferSize;
                    }
                }
                else
                {
                    ipExternalInputBufferAllocatorInterface->removeRef();
                    ipExternalInputBufferAllocatorInterface = NULL;

                }
            }
        }
    }

    // if component allows us to allocate buffers, we'll decide how many to allocate
    if (iOMXComponentSupportsExternalInputBufferAlloc && (iParamPort.nBufferCountMin < NUMBER_INPUT_BUFFER))
    {
        if(NULL == ipFixedSizeBufferAlloc)
        {
        // preset the number of input buffers
        iNumInputBuffers = NUMBER_INPUT_BUFFER;
        }
    }

    // set the number of input buffer
    iParamPort.nBufferCountActual = iNumInputBuffers;

    // set the number of actual input buffers
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFOMXEncNode-%s::NegotiateVideoComponentParameters() Inport buffers %d,size %d", iNodeTypeId, iNumInputBuffers, iOMXComponentInputBufferSize));

    // lock in the input port parameters
    CONFIG_SIZE_AND_VERSION(iParamPort);
    Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamPortDefinition, &iParamPort);
    if (Err != OMX_ErrorNone)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::NegotiateVideoComponentParameters() Problem setting parameters in input port %d ", iNodeTypeId, iInputPortIndex));
        return false;
    }


    //////////////////// OUTPUT PORT //////////////////////////////////////////////
    CONFIG_SIZE_AND_VERSION(Video_port_format);

    Video_port_format.nPortIndex = iOutputPortIndex; // set output port as target
    OMX_VIDEO_CODINGTYPE DesiredPortFormat = OMX_VIDEO_CodingUnused;
    if (iOutFormat == PVMF_MIME_M4V)
    {
        DesiredPortFormat = OMX_VIDEO_CodingMPEG4;
    }
    else if (iOutFormat == PVMF_MIME_H2631998 ||
             iOutFormat == PVMF_MIME_H2632000)
    {
        DesiredPortFormat = OMX_VIDEO_CodingH263;
    }
    else if (iOutFormat == PVMF_MIME_H264_VIDEO_RAW ||
             iOutFormat == PVMF_MIME_H264_VIDEO_MP4)
    {
        DesiredPortFormat = OMX_VIDEO_CodingAVC;
    }
    else
    {
        DesiredPortFormat = OMX_VIDEO_CodingUnused;
    }

    if (DesiredPortFormat == OMX_VIDEO_CodingUnused)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::NegotiateVideoComponentParameters() Problem with output port %d format", iNodeTypeId, iOutputPortIndex));
        return false;
    }
    // loop over supported formats until we hit the one we want
    // or until the component has no more supported formats (in which case it returns OMX_ErrorNoMore
    Err = OMX_ErrorNone;
    Video_port_format.nIndex = 0; //init the format counter
    while (OMX_ErrorNone == Err)
    {

        Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamVideoPortFormat, &Video_port_format);
        if ((OMX_ErrorNone != Err))
        {
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "PVMFOMXEncNode-%s::NegotiateVideoComponentParameters() Problem getting port format for output port %d or no desired port format found", iNodeTypeId, iOutputPortIndex));
            return false;
        }

        if ((Video_port_format.eCompressionFormat == DesiredPortFormat))
            break;

        Video_port_format.nIndex ++;
    }

    // OK, we've found the desired format, set it as the one used
    Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamVideoPortFormat, &Video_port_format);
    if ((OMX_ErrorNone != Err))
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::NegotiateVideoComponentParameters() Problem setting port format for output port %d ", iNodeTypeId, iOutputPortIndex));
        return false;
    }




    //Port 1 for output port
    CONFIG_SIZE_AND_VERSION(iParamPort);
    iParamPort.nPortIndex = iOutputPortIndex;
    Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamPortDefinition, &iParamPort);
    if (Err != OMX_ErrorNone)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::NegotiateVideoComponentParameters() Problem negotiating with output port %d ", iNodeTypeId, iOutputPortIndex));
        return false;
    }

    // let the component decide num output buffers
    iNumOutputBuffers = iParamPort.nBufferCountActual;


    //check the number
    if (iNumOutputBuffers < iParamPort.nBufferCountMin)
        iNumOutputBuffers = iParamPort.nBufferCountMin;


    // set the number ourselves
    if (iOMXComponentSupportsExternalOutputBufferAlloc && (iParamPort.nBufferCountMin < NUMBER_OUTPUT_BUFFER))
    {
        iNumOutputBuffers = NUMBER_OUTPUT_BUFFER;
    }

    iParamPort.nBufferCountActual = iNumOutputBuffers;


    // set the output (target) bitrate, framerate, width/height etc.
    iParamPort.format.video.nFrameWidth = iVideoEncodeParam.iFrameWidth[0];
    iParamPort.format.video.nFrameHeight = iVideoEncodeParam.iFrameHeight[0];
    // Q16 value, cast after the shift to preserve the accuracy.
    iParamPort.format.video.xFramerate = (uint32)(iVideoEncodeParam.iFrameRate[0] * (1 << 16));

    iParamPort.format.video.nBitrate = iVideoEncodeParam.iBitRate[0];
    iParamPort.format.video.eColorFormat = OMX_COLOR_FormatUnused;

    if (iOutFormat == PVMF_MIME_M4V)
    {
        iParamPort.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4;
    }
    else if (iOutFormat == PVMF_MIME_H2631998 ||
             iOutFormat == PVMF_MIME_H2632000)
    {
        iParamPort.format.video.eCompressionFormat = OMX_VIDEO_CodingH263;
    }
    else if (iOutFormat == PVMF_MIME_H264_VIDEO_RAW ||
             iOutFormat == PVMF_MIME_H264_VIDEO_MP4)
    {
        iParamPort.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
    }
    else
    {
        iParamPort.format.video.eCompressionFormat = OMX_VIDEO_CodingAutoDetect;
    }

    CONFIG_SIZE_AND_VERSION(iParamPort);
    Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamPortDefinition, &iParamPort);
    if (Err != OMX_ErrorNone)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::NegotiateVideoComponentParameters() Problem setting parameters in output port %d ", iNodeTypeId, iOutputPortIndex));
        return false;
    }

    //ask for the calculated buffer size
    Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamPortDefinition, &iParamPort);
    if (Err != OMX_ErrorNone)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::NegotiateVideoComponentParameters() Problem negotiating with output port %d ", iNodeTypeId, iOutputPortIndex));
        return false;
    }

    iOMXComponentOutputBufferSize = iParamPort.nBufferSize;
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFOMXEncNode-%s::NegotiateVideoComponentParameters() Outport buffers %d size %d", iNodeTypeId, iNumOutputBuffers, iOMXComponentOutputBufferSize));

    CONFIG_SIZE_AND_VERSION(InputRotationType);
    InputRotationType.nPortIndex = iInputPortIndex;
    Err = OMX_GetParameter(iOMXEncoder, OMX_IndexConfigCommonRotate, &InputRotationType);
    if (Err != OMX_ErrorNone)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::NegotiateVideoComponentParameters() Problem getting OMX_IndexConfigCommonRotate param ", iNodeTypeId));
    }

    //Set the OMX_CONFIG_ROTATIONTYPE parameters
    InputRotationType.nRotation = ((iVideoInputFormat.iFrameOrientation == 1) ? 180 : 0);
    Err = OMX_SetParameter(iOMXEncoder, OMX_IndexConfigCommonRotate, &InputRotationType);
    if (Err != OMX_ErrorNone)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::NegotiateVideoComponentParameters() Problem setting OMX_IndexConfigCommonRotate param ", iNodeTypeId));
    }


    // now call codec specific parameter setting
    bool status = true;
    if (iOutFormat == PVMF_MIME_M4V)
    {
        status = SetMP4EncoderParameters();
    }
    else if (iOutFormat == PVMF_MIME_H2631998 ||
             iOutFormat == PVMF_MIME_H2632000)
    {
        status = SetH263EncoderParameters();
    }
    else if (iOutFormat == PVMF_MIME_H264_VIDEO_RAW ||
             iOutFormat == PVMF_MIME_H264_VIDEO_MP4)
    {
        status = SetH264EncoderParameters();
    }

    return status;
}
bool PVMFOMXEncNode::SetMP4EncoderParameters()
{
    OMX_ERRORTYPE Err = OMX_ErrorNone;

    OMX_VIDEO_PARAM_MPEG4TYPE Mpeg4Type;
    OMX_VIDEO_PARAM_BITRATETYPE BitRateType;
    OMX_VIDEO_PARAM_QUANTIZATIONTYPE QuantParam;
    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE ErrCorrType;

    // DV: VALUES HERE ARE FOR THE MOST PART HARDCODED BASED ON PV DEFAULTS
    OMX_VIDEO_PARAM_MOTIONVECTORTYPE MotionVector;
    OMX_VIDEO_PARAM_INTRAREFRESHTYPE RefreshParam;


    CONFIG_SIZE_AND_VERSION(Mpeg4Type);
    Mpeg4Type.nPortIndex = iOutputPortIndex;

    Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamVideoMpeg4, &Mpeg4Type);
    if (OMX_ErrorNone != Err)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::SetMP4EncoderParameters Parameter Invalid", iNodeTypeId));
    }


    //Set the OMX_VIDEO_PARAM_MPEG4TYPE parameters

    Mpeg4Type.nPortIndex = iOutputPortIndex;
    // extra parameters - hardcoded
    Mpeg4Type.nSliceHeaderSpacing = 0;
    Mpeg4Type.bSVH = OMX_FALSE; //((iEncoderParam.iContentType == EI_H263)? true: false);
    Mpeg4Type.bGov = OMX_FALSE; // disable or enable GOV header
    // extra parameters - hardcoded
    Mpeg4Type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;


    // params based on iFrame interval
    if (iVideoEncodeParam.iIFrameInterval == -1) // encode only one frame
    {
        Mpeg4Type.nPFrames = 0xFFFFFFFF;
    }
    else if (iVideoEncodeParam.iIFrameInterval == 0) // no P frames
    {
        Mpeg4Type.nPFrames = 0;
        Mpeg4Type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI; // maps to only supporting I-frames
    }
    else
    {
        Mpeg4Type.nPFrames = (OMX_U32)(iVideoEncodeParam.iIFrameInterval * iVideoEncodeParam.iFrameRate[0] - 1);
    }

    // extra parameters - hardcoded
    Mpeg4Type.nBFrames = 0;
    Mpeg4Type.nIDCVLCThreshold = 0;
    Mpeg4Type.bACPred = OMX_TRUE;
    Mpeg4Type.nMaxPacketSize = iVideoEncodeParam.iPacketSize;
    Mpeg4Type.nTimeIncRes = 1000; // (in relation to (should be higher than) frame rate )
    Mpeg4Type.nHeaderExtension = 0;
    Mpeg4Type.bReversibleVLC = ((iVideoEncodeParam.iRVLCEnable == true) ? OMX_TRUE : OMX_FALSE);

    switch (iVideoEncodeParam.iProfileLevel)
    {

        case EI_SIMPLE_LEVEL0:
            Mpeg4Type.eProfile = OMX_VIDEO_MPEG4ProfileSimple;
            Mpeg4Type.eLevel = OMX_VIDEO_MPEG4Level0;
            break;

        case EI_SIMPLE_LEVEL1:
            Mpeg4Type.eProfile = OMX_VIDEO_MPEG4ProfileSimple;
            Mpeg4Type.eLevel = OMX_VIDEO_MPEG4Level1;
            break;

        case EI_SIMPLE_LEVEL2:
            Mpeg4Type.eProfile = OMX_VIDEO_MPEG4ProfileSimple;
            Mpeg4Type.eLevel = OMX_VIDEO_MPEG4Level2;
            break;

        case EI_SIMPLE_LEVEL3:
            Mpeg4Type.eProfile = OMX_VIDEO_MPEG4ProfileSimple;
            Mpeg4Type.eLevel = OMX_VIDEO_MPEG4Level3;
            break;

        case EI_CORE_LEVEL1:
            Mpeg4Type.eProfile = OMX_VIDEO_MPEG4ProfileCore;
            Mpeg4Type.eLevel = OMX_VIDEO_MPEG4Level1;
            break;

        case EI_CORE_LEVEL2:
            Mpeg4Type.eProfile = OMX_VIDEO_MPEG4ProfileCore;
            Mpeg4Type.eLevel = OMX_VIDEO_MPEG4Level2;
            break;

        case EI_SIMPLE_SCALABLE_LEVEL0:
            Mpeg4Type.eProfile = OMX_VIDEO_MPEG4ProfileSimpleScalable;
            Mpeg4Type.eLevel = OMX_VIDEO_MPEG4Level0;
            break;

        case EI_SIMPLE_SCALABLE_LEVEL1:
            Mpeg4Type.eProfile = OMX_VIDEO_MPEG4ProfileSimpleScalable;
            Mpeg4Type.eLevel = OMX_VIDEO_MPEG4Level1;
            break;

        case EI_SIMPLE_SCALABLE_LEVEL2:
            Mpeg4Type.eProfile = OMX_VIDEO_MPEG4ProfileSimpleScalable;
            Mpeg4Type.eLevel = OMX_VIDEO_MPEG4Level2;
            break;

        case EI_CORE_SCALABLE_LEVEL1:
            Mpeg4Type.eProfile = OMX_VIDEO_MPEG4ProfileCoreScalable;
            Mpeg4Type.eLevel = OMX_VIDEO_MPEG4Level1;
            break;

        case EI_CORE_SCALABLE_LEVEL2:
            Mpeg4Type.eProfile = OMX_VIDEO_MPEG4ProfileCoreScalable;
            Mpeg4Type.eLevel = OMX_VIDEO_MPEG4Level2;
            break;

        case EI_CORE_SCALABLE_LEVEL3:
            Mpeg4Type.eProfile = OMX_VIDEO_MPEG4ProfileCoreScalable;
            Mpeg4Type.eLevel = OMX_VIDEO_MPEG4Level3;
            break;

    }

    Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamVideoMpeg4, &Mpeg4Type);
    if (OMX_ErrorNone != Err)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::SetMP4EncoderParameters Parameter Invalid", iNodeTypeId));
    }

    //OMX_VIDEO_PARAM_BITRATETYPE Settings
    CONFIG_SIZE_AND_VERSION(BitRateType);

    BitRateType.nPortIndex = iOutputPortIndex;
    Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamVideoBitrate, &BitRateType);

    if (OMX_ErrorNone != Err)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::SetMP4EncoderParameters Parameter Invalid", iNodeTypeId));
    }

    //Set the parameters now
    BitRateType.nPortIndex = iOutputPortIndex;
    BitRateType.eControlRate = static_cast<OMX_VIDEO_CONTROLRATETYPE>(iVideoEncodeParam.iRateControlType);
    BitRateType.nTargetBitrate = iVideoEncodeParam.iBitRate[0];
    Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamVideoBitrate, &BitRateType);

    if (OMX_ErrorNone != Err)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::SetMP4EncoderParameters Parameter Invalid", iNodeTypeId));
    }

    //OMX_VIDEO_PARAM_QUANTIZATIONTYPE Settings
    if (BitRateType.eControlRate == OMX_Video_ControlRateDisable)
    {
        CONFIG_SIZE_AND_VERSION(QuantParam);
        QuantParam.nPortIndex = iOutputPortIndex;

        Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamVideoQuantization, &QuantParam);
        if (OMX_ErrorNone != Err)
        {
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "PVMFOMXEncNode-%s::SetMP4EncoderParameters Parameter Invalid", iNodeTypeId));
        }

        //Set the parameters now
        QuantParam.nPortIndex = iOutputPortIndex;
        QuantParam.nQpI = DEFAULT_OMX_MP4ENC_QPI;
        QuantParam.nQpP = DEFAULT_OMX_MP4ENC_QPP;
        QuantParam.nQpB = DEFAULT_OMX_MP4ENC_QPB;
        Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamVideoQuantization, &QuantParam);
        if (OMX_ErrorNone != Err)
        {
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "PVMFOMXEncNode-%s::SetMP4EncoderParameters Parameter Invalid", iNodeTypeId));
        }
    }



    //OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE Settings (For streaming/2-way)

    CONFIG_SIZE_AND_VERSION(ErrCorrType);
    ErrCorrType.nPortIndex = iOutputPortIndex;
    Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamVideoErrorCorrection, &ErrCorrType);
    if (OMX_ErrorNone != Err)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::SetMP4EncoderParameters Parameter Invalid", iNodeTypeId));
    }

    //Set the parameters now
    ErrCorrType.nPortIndex = iOutputPortIndex;
    ErrCorrType.bEnableDataPartitioning = ((iVideoEncodeParam.iDataPartitioning == true) ? OMX_TRUE : OMX_FALSE);
    ErrCorrType.bEnableResync = ((iVideoEncodeParam.iResyncMarker == true) ? OMX_TRUE : OMX_FALSE);

    // extra parameters - hardcoded
    ErrCorrType.bEnableHEC = OMX_FALSE;
    ErrCorrType.nResynchMarkerSpacing = iVideoEncodeParam.iPacketSize;
    ErrCorrType.bEnableRVLC = ((iVideoEncodeParam.iRVLCEnable == true) ? OMX_TRUE : OMX_FALSE); // corresponds to encode param rvlcEnable

    Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamVideoErrorCorrection, &ErrCorrType);
    if (OMX_ErrorNone != Err)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::SetMP4EncoderParameters Parameter Invalid", iNodeTypeId));
    }


    //OMX_VIDEO_PARAM_MOTIONVECTORTYPE Settings
    CONFIG_SIZE_AND_VERSION(MotionVector);
    MotionVector.nPortIndex = iOutputPortIndex;

    Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamVideoMotionVector, &MotionVector);
    if (OMX_ErrorNone != Err)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::SetMP4EncoderParameters Parameter Invalid", iNodeTypeId));
    }

    MotionVector.nPortIndex = iOutputPortIndex;

    // extra parameters - hardcoded
    MotionVector.sXSearchRange = iVideoEncodeParam.iSearchRange;
    MotionVector.sYSearchRange = iVideoEncodeParam.iSearchRange;
    MotionVector.bFourMV = ((iVideoEncodeParam.iMV8x8 == true) ? OMX_TRUE : OMX_FALSE);
    MotionVector.eAccuracy = ((iVideoEncodeParam.iMVHalfPel == true) ? OMX_Video_MotionVectorHalfPel : OMX_Video_MotionVectorPixel);
    MotionVector.bUnrestrictedMVs = OMX_TRUE;

    Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamVideoMotionVector, &MotionVector);
    if (OMX_ErrorNone != Err)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::SetMP4EncoderParameters Parameter Invalid", iNodeTypeId));
    }


    //OMX_VIDEO_PARAM_INTRAREFRESHTYPE Settings
    CONFIG_SIZE_AND_VERSION(RefreshParam);
    RefreshParam.nPortIndex = iOutputPortIndex;

    Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamVideoIntraRefresh, &RefreshParam);
    if (OMX_ErrorNone != Err)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::SetMP4EncoderParameters Parameter Invalid", iNodeTypeId));
    }

    // extra parameters - hardcoded based on PV defaults
    RefreshParam.nPortIndex = iOutputPortIndex;
    RefreshParam.eRefreshMode = OMX_VIDEO_IntraRefreshBoth;
    RefreshParam.nCirMBs = iVideoEncodeParam.iNumIntraMBRefresh;

    Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamVideoIntraRefresh, &RefreshParam);
    if (OMX_ErrorNone != Err)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::SetMP4EncoderParameters Parameter Invalid", iNodeTypeId));
    }

    return true;
}

bool PVMFOMXEncNode::SetH263EncoderParameters()
{

    OMX_ERRORTYPE Err = OMX_ErrorNone;

    OMX_VIDEO_PARAM_H263TYPE H263Type;
    OMX_VIDEO_PARAM_BITRATETYPE BitRateType;
    OMX_VIDEO_PARAM_QUANTIZATIONTYPE QuantParam;
    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE ErrCorrType;

    // DV: VALUES HERE ARE FOR THE MOST PART HARDCODED BASED ON PV DEFAULTS
    OMX_VIDEO_PARAM_MOTIONVECTORTYPE MotionVector;
    OMX_VIDEO_PARAM_INTRAREFRESHTYPE RefreshParam;


    CONFIG_SIZE_AND_VERSION(H263Type);
    H263Type.nPortIndex = iOutputPortIndex;

    Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamVideoH263, &H263Type);
    if (OMX_ErrorNone != Err)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::SetH263EncoderParameters OMX_GetParameter() failed for index(0x%x)", iNodeTypeId, OMX_IndexParamVideoH263));
    }


    //Set the OMX_VIDEO_PARAM_H263TYPE parameters

    //DV: Here, we only set the nPFrames and AllowedFrameTypes, i.e. iIFrameInterval related variables

    H263Type.nPortIndex = iOutputPortIndex;

    H263Type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
    if (iVideoEncodeParam.iIFrameInterval == -1) // encode only one I frame followed by P frames
    {
        H263Type.nPFrames = 0xFFFFFFFF;
    }
    else if (iVideoEncodeParam.iIFrameInterval == 0) // no P frames
    {
        H263Type.nPFrames = 0;
        H263Type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI; // maps to only supporting I-frames
    }
    else
    {
        H263Type.nPFrames = (OMX_U32)(iVideoEncodeParam.iIFrameInterval * iVideoEncodeParam.iFrameRate[0] - 1);
    }

    // extra parameters - hardcoded
    H263Type.nBFrames = 0;
    H263Type.eProfile = OMX_VIDEO_H263ProfileBaseline;

    // the supported level is up to OMX_VIDEO_H263Level45
    if (H263Type.eLevel > OMX_VIDEO_H263Level45)
    {
        H263Type.eLevel = OMX_VIDEO_H263Level45;
    }
    H263Type.bPLUSPTYPEAllowed = OMX_FALSE;
    H263Type.bForceRoundingTypeToZero = OMX_FALSE;
    H263Type.nPictureHeaderRepetition = 0;
    H263Type.nGOBHeaderInterval = 0;

    Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamVideoH263, &H263Type);
    if (OMX_ErrorNone != Err)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::SetH263EncoderParameters OMX_SetParameter() failed for index(0x%x)", iNodeTypeId, OMX_IndexParamVideoH263));
    }

    //OMX_VIDEO_PARAM_BITRATETYPE Settings
    CONFIG_SIZE_AND_VERSION(BitRateType);

    BitRateType.nPortIndex = iOutputPortIndex;
    Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamVideoBitrate, &BitRateType);
    if (OMX_ErrorNone != Err)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::SetH263EncoderParameters OMX_GetParameter() failed for index(0x%x)", iNodeTypeId, OMX_IndexParamVideoBitrate));
    }

    //Set the parameters now
    BitRateType.nPortIndex = iOutputPortIndex;
    BitRateType.eControlRate = static_cast<OMX_VIDEO_CONTROLRATETYPE>(iVideoEncodeParam.iRateControlType);
    BitRateType.nTargetBitrate = iVideoEncodeParam.iBitRate[0];
    Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamVideoBitrate, &BitRateType);
    if (OMX_ErrorNone != Err)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::SetH263EncoderParameters OMX_SetParameter() failed for index(0x%x)", iNodeTypeId, OMX_IndexParamVideoBitrate));
    }


    //OMX_VIDEO_PARAM_QUANTIZATIONTYPE Settings
    if (BitRateType.eControlRate == OMX_Video_ControlRateDisable)
    {
        CONFIG_SIZE_AND_VERSION(QuantParam);
        QuantParam.nPortIndex = iOutputPortIndex;

        Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamVideoQuantization, &QuantParam);
        if (OMX_ErrorNone != Err)
        {
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "PVMFOMXEncNode-%s::SetH263EncoderParameters OMX_GetParameter() failed for index(0x%x", iNodeTypeId, OMX_IndexParamVideoQuantization));
        }

        //Set the parameters now
        QuantParam.nPortIndex = iOutputPortIndex;
        QuantParam.nQpI = DEFAULT_OMX_MP4ENC_QPI;
        QuantParam.nQpP = DEFAULT_OMX_MP4ENC_QPP;
        QuantParam.nQpB = DEFAULT_OMX_MP4ENC_QPB;
        Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamVideoQuantization, &QuantParam);
        if (OMX_ErrorNone != Err)
        {
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "PVMFOMXEncNode-%s::SetH263EncoderParameters OMX_SetParameter() failed for index(0x%x)", iNodeTypeId, OMX_IndexParamVideoQuantization));
        }
    }


    //OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE Settings (For streaming/2-way)

    CONFIG_SIZE_AND_VERSION(ErrCorrType);
    ErrCorrType.nPortIndex = iOutputPortIndex;
    Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamVideoErrorCorrection, &ErrCorrType);
    if (OMX_ErrorNone != Err)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::SetH263EncoderParameters OMX_GetParameter() faile for index(0x%x)", iNodeTypeId, OMX_IndexParamVideoErrorCorrection));
    }

    //Set the parameters now
    ErrCorrType.nPortIndex = iOutputPortIndex;
    //if (iVideoEncodeParam.iContentType == EI_M4V_STREAMING)
    //{
    //    ErrCorrType.bEnableDataPartitioning = OMX_TRUE;
    //}
    //else
    //{
    //    ErrCorrType.bEnableDataPartitioning = OMX_FALSE;
    //}
    ErrCorrType.bEnableHEC = OMX_FALSE;
    ErrCorrType.bEnableResync = OMX_FALSE;
    ErrCorrType.nResynchMarkerSpacing = 0;
    ErrCorrType.bEnableRVLC = OMX_FALSE;        // corresponds to encode param rvlcEnable
    Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamVideoErrorCorrection, &ErrCorrType);
    if (OMX_ErrorNone != Err)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::SetH263EncoderParameters OMX_SetParameter() failed for index(0x%x)", iNodeTypeId, OMX_IndexParamVideoErrorCorrection));
    }



    //OMX_VIDEO_PARAM_MOTIONVECTORTYPE Settings
    CONFIG_SIZE_AND_VERSION(MotionVector);
    MotionVector.nPortIndex = iOutputPortIndex;

    Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamVideoMotionVector, &MotionVector);
    if (OMX_ErrorNone != Err)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::SetH263EncoderParameters OMX_GetParameter() failed for index(0x%x)", iNodeTypeId, OMX_IndexParamVideoMotionVector));
    }

    // extra parameters - hardcoded
    MotionVector.sXSearchRange = iVideoEncodeParam.iSearchRange;
    MotionVector.sYSearchRange = iVideoEncodeParam.iSearchRange;
    MotionVector.bFourMV =  OMX_FALSE;
    MotionVector.eAccuracy = ((iVideoEncodeParam.iMVHalfPel == true) ? OMX_Video_MotionVectorHalfPel : OMX_Video_MotionVectorPixel);
    MotionVector.bUnrestrictedMVs = OMX_FALSE;


    Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamVideoMotionVector, &MotionVector);
    if (OMX_ErrorNone != Err)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::SetH263EncoderParameters OMX_SetParameter() failed for index(0x%x", iNodeTypeId, OMX_IndexParamVideoMotionVector));
    }


    //OMX_VIDEO_PARAM_INTRAREFRESHTYPE Settings

    CONFIG_SIZE_AND_VERSION(RefreshParam);
    RefreshParam.nPortIndex = iOutputPortIndex;

    Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamVideoIntraRefresh, &RefreshParam);
    if (OMX_ErrorNone != Err)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::SetH263EncoderParameters OMX_GetParameter() failed for index(0x%x)", iNodeTypeId, OMX_IndexParamVideoIntraRefresh));
    }

    // extra parameters - hardcoded based on PV defaults
    RefreshParam.nPortIndex = iOutputPortIndex;
    RefreshParam.eRefreshMode = OMX_VIDEO_IntraRefreshBoth;
    RefreshParam.nCirMBs = iVideoEncodeParam.iNumIntraMBRefresh;


    Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamVideoIntraRefresh, &RefreshParam);
    if (OMX_ErrorNone != Err)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::SetH263EncoderParameters OMX_SetParameter() failed for index(0x%x)", iNodeTypeId, OMX_IndexParamVideoIntraRefresh));
    }

    return true;
}

bool PVMFOMXEncNode::SetH264EncoderParameters()
{
    OMX_ERRORTYPE Err = OMX_ErrorNone;

    OMX_VIDEO_PARAM_AVCTYPE H264Type;
    OMX_VIDEO_PARAM_BITRATETYPE BitRateType;
    OMX_VIDEO_PARAM_QUANTIZATIONTYPE QuantParam;

    // to be refined
    OMX_VIDEO_PARAM_MOTIONVECTORTYPE MotionVector;
    OMX_VIDEO_PARAM_INTRAREFRESHTYPE RefreshParam;
    OMX_VIDEO_PARAM_VBSMCTYPE VbsmcType;


    CONFIG_SIZE_AND_VERSION(H264Type);
    H264Type.nPortIndex = iOutputPortIndex;

    Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamVideoAvc, &H264Type);
    if (OMX_ErrorNone != Err)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::SetH264EncoderParameters Parameter Invalid", iNodeTypeId));
    }


    H264Type.nPortIndex = iOutputPortIndex;

    H264Type.nAllowedPictureTypes  = OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
    if (iVideoEncodeParam.iIFrameInterval == -1) // encode only one I frame followed by P frames
    {
        H264Type.nPFrames = 0xFFFFFFFF;
    }
    else if (iVideoEncodeParam.iIFrameInterval == 0) // no P frames
    {
        H264Type.nPFrames = 0;
        H264Type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI; // maps to only supporting I-frames
    }
    else
    {
        H264Type.nPFrames = (OMX_U32)(iVideoEncodeParam.iIFrameInterval * iVideoEncodeParam.iFrameRate[0] - 1);
    }

    // extra parameters -hardcoded
    H264Type.nSliceHeaderSpacing = 0;
    H264Type.nBFrames = 0;
    H264Type.bUseHadamard = OMX_TRUE;
    H264Type.nRefFrames = 1;
    H264Type.nRefIdx10ActiveMinus1 = 0;
    H264Type.nRefIdx11ActiveMinus1 = 0;
    H264Type.bEnableUEP = OMX_FALSE;
    H264Type.bEnableFMO = OMX_FALSE;
    H264Type.bEnableASO = OMX_FALSE;
    H264Type.bEnableRS = OMX_FALSE;
    //H264Type.eProfile = OMX_VIDEO_AVCProfileBaseline;
    //H264Type.eLevel = OMX_VIDEO_AVCLevel1b;
    H264Type.bFrameMBsOnly = OMX_TRUE;
    H264Type.bMBAFF = OMX_FALSE;
    H264Type.bEntropyCodingCABAC = OMX_FALSE;
    H264Type.bWeightedPPrediction = OMX_FALSE;
    H264Type.bconstIpred = OMX_FALSE;
    H264Type.bDirect8x8Inference = OMX_FALSE;
    H264Type.bDirectSpatialTemporal = OMX_FALSE;
    H264Type.nCabacInitIdc = 0;
    H264Type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;


    Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamVideoAvc, &H264Type);
    if (OMX_ErrorNone != Err)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::SetH264EncoderParameters Parameter Invalid", iNodeTypeId));
    }


    //OMX_VIDEO_PARAM_BITRATETYPE Settings
    CONFIG_SIZE_AND_VERSION(BitRateType);

    BitRateType.nPortIndex = iOutputPortIndex;
    Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamVideoBitrate, &BitRateType);
    if (OMX_ErrorNone != Err)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::SetH264EncoderParameters Parameter Invalid", iNodeTypeId));
    }

    //Set the parameters now
    BitRateType.nPortIndex = iOutputPortIndex;
    BitRateType.eControlRate = static_cast<OMX_VIDEO_CONTROLRATETYPE>(iVideoEncodeParam.iRateControlType);
    BitRateType.nTargetBitrate = iVideoEncodeParam.iBitRate[0];
    Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamVideoBitrate, &BitRateType);
    if (OMX_ErrorNone != Err)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::SetH264EncoderParameters Parameter Invalid", iNodeTypeId));
    }


    //OMX_VIDEO_PARAM_QUANTIZATIONTYPE Settings
    if (BitRateType.eControlRate == OMX_Video_ControlRateDisable)
    {
        CONFIG_SIZE_AND_VERSION(QuantParam);
        QuantParam.nPortIndex = iOutputPortIndex;

        Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamVideoQuantization, &QuantParam);
        if (OMX_ErrorNone != Err)
        {
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "PVMFOMXEncNode-%s::SetH264EncoderParameters Parameter Invalid", iNodeTypeId));
        }

        //Set the parameters now
        QuantParam.nPortIndex = iOutputPortIndex;
        QuantParam.nQpI = DEFAULT_OMX_AVCENC_QPI;
        QuantParam.nQpP = DEFAULT_OMX_AVCENC_QPP;
        QuantParam.nQpB = DEFAULT_OMX_AVCENC_QPB;
        Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamVideoQuantization, &QuantParam);
        if (OMX_ErrorNone != Err)
        {
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "PVMFOMXEncNode-%s::SetH264EncoderParameters Parameter Invalid", iNodeTypeId));
        }
    }




    //OMX_VIDEO_PARAM_MOTIONVECTORTYPE Settings
    CONFIG_SIZE_AND_VERSION(MotionVector);
    MotionVector.nPortIndex = iOutputPortIndex;

    Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamVideoMotionVector, &MotionVector);
    if (OMX_ErrorNone != Err)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::SetH264EncoderParameters Parameter Invalid", iNodeTypeId));
    }

    // extra parameters - hardcoded
    MotionVector.sXSearchRange = iVideoEncodeParam.iSearchRange;
    MotionVector.sYSearchRange = iVideoEncodeParam.iSearchRange;
    MotionVector.bFourMV =  OMX_FALSE;
    MotionVector.eAccuracy = OMX_Video_MotionVectorQuarterPel; // hardcoded
    MotionVector.bUnrestrictedMVs = OMX_TRUE;


    Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamVideoMotionVector, &MotionVector);
    if (OMX_ErrorNone != Err)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::SetH264EncoderParameters Parameter Invalid", iNodeTypeId));
    }


    //OMX_VIDEO_PARAM_INTRAREFRESHTYPE Settings

    CONFIG_SIZE_AND_VERSION(RefreshParam);
    RefreshParam.nPortIndex = iOutputPortIndex;

    Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamVideoIntraRefresh, &RefreshParam);
    if (OMX_ErrorNone != Err)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::SetH264EncoderParameters Parameter Invalid", iNodeTypeId));
    }

    // extra parameters - hardcoded based on PV defaults
    RefreshParam.nPortIndex = iOutputPortIndex;
    RefreshParam.eRefreshMode = OMX_VIDEO_IntraRefreshBoth;
    RefreshParam.nCirMBs = iVideoEncodeParam.iNumIntraMBRefresh;


    Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamVideoIntraRefresh, &RefreshParam);
    if (OMX_ErrorNone != Err)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::SetH264EncoderParameters Parameter Invalid", iNodeTypeId));
    }

    CONFIG_SIZE_AND_VERSION(VbsmcType);
    VbsmcType.nPortIndex = iOutputPortIndex;

    Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamVideoVBSMC, &VbsmcType);
    if (OMX_ErrorNone != Err)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::SetH264EncoderParameters Parameter Invalid", iNodeTypeId));
    }

    VbsmcType.b16x16 = OMX_TRUE;
    VbsmcType.b16x8 = VbsmcType.b8x16 = VbsmcType.b8x8 = VbsmcType.b8x4 = VbsmcType.b4x8 = VbsmcType.b4x4 = OMX_FALSE;

    Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamVideoVBSMC, &VbsmcType);
    if (OMX_ErrorNone != Err)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::SetH264EncoderParameters Parameter Invalid", iNodeTypeId));
    }

    return true;
}

////////////////////////////////////////////////////////////////////////////////
bool PVMFOMXEncNode::NegotiateAudioComponentParameters()
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFOMXEncNode-%s::NegotiateAudioParameters() In", iNodeTypeId));

    OMX_ERRORTYPE Err;

    // first get the number of ports and port indices
    OMX_PORT_PARAM_TYPE AudioPortParameters;
    uint32 NumPorts;
    uint32 ii;

    // get starting number
    CONFIG_SIZE_AND_VERSION(AudioPortParameters);

    Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamAudioInit, &AudioPortParameters);
    NumPorts = AudioPortParameters.nPorts; // must be at least 2 of them (in&out)

    if (Err != OMX_ErrorNone || NumPorts < 2)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::NegotiateAudioComponentParameters() There is insuffucient (%d) ports", iNodeTypeId, NumPorts));
        return false;
    }


    // loop through ports starting from the starting index to find index of the first input port
    for (ii = AudioPortParameters.nStartPortNumber ; ii < AudioPortParameters.nStartPortNumber + NumPorts; ii++)
    {
        // get port parameters, and determine if it is input or output
        // if there are more than 2 ports, the first one we encounter that has input direction is picked


        CONFIG_SIZE_AND_VERSION(iParamPort);
        //port
        iParamPort.nPortIndex = ii;
        Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamPortDefinition, &iParamPort);

        if (Err != OMX_ErrorNone)
        {
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "PVMFOMXEncNode-%s::NegotiateAudioComponentParameters() Problem negotiating with port %d ", iNodeTypeId, ii));

            return false;
        }

        if (iParamPort.eDir == OMX_DirInput)
        {
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "PVMFOMXEncNode-%s::NegotiateAudioComponentParameters() Found Input port index %d ", iNodeTypeId, ii));

            iInputPortIndex = ii;
            break;
        }
    }
    if (ii == AudioPortParameters.nStartPortNumber + NumPorts)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::NegotiateAudioComponentParameters() Cannot find any input port ", iNodeTypeId));
        return false;
    }


    // loop through ports starting from the starting index to find index of the first output port
    for (ii = AudioPortParameters.nStartPortNumber ; ii < AudioPortParameters.nStartPortNumber + NumPorts; ii++)
    {
        // get port parameters, and determine if it is input or output
        // if there are more than 2 ports, the first one we encounter that has output direction is picked


        CONFIG_SIZE_AND_VERSION(iParamPort);
        //port
        iParamPort.nPortIndex = ii;
        Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamPortDefinition, &iParamPort);

        if (Err != OMX_ErrorNone)
        {
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "PVMFOMXEncNode-%s::NegotiateAudioComponentParameters() Problem negotiating with port %d ", iNodeTypeId, ii));

            return false;
        }

        if (iParamPort.eDir == OMX_DirOutput)
        {
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "PVMFOMXEncNode-%s::NegotiateAudioComponentParameters() Found Output port index %d ", iNodeTypeId, ii));

            iOutputPortIndex = ii;
            break;
        }
    }
    if (ii == AudioPortParameters.nStartPortNumber + NumPorts)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::NegotiateAudioComponentParameters() Cannot find any output port ", iNodeTypeId));
        return false;
    }



    // now get input parameters


    //INPUT PORT

    // first basic check if encode parameters have been set correctly
    if ((0 == iAudioEncodeParam.iMaxNumOutputFramesPerBuffer) ||
            (0 == iAudioEncodeParam.iAMRBitrate) ||
            (0 == iAudioEncodeParam.iOutputNumChannels) ||
            (2 < iAudioEncodeParam.iOutputNumChannels) ||
            (0 == iAudioEncodeParam.iOutputSamplingRate) ||
            (0 == iAudioInputFormat.iInputBitsPerSample) ||
            (0 == iAudioInputFormat.iInputNumChannels) ||
            (2 < iAudioInputFormat.iInputNumChannels) ||
            (0 == iAudioInputFormat.iInputSamplingRate)
       )
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::NegotiateAudioComponentParameters() Encode parameters not set correctly", iNodeTypeId));
        return false;
    }

    // first of all, check if the port supports the adequate port format
    OMX_AUDIO_PARAM_PORTFORMATTYPE Audio_port_format;
    OMX_AUDIO_CODINGTYPE DesiredPortFormat = OMX_AUDIO_CodingPCM;
    CONFIG_SIZE_AND_VERSION(Audio_port_format);

    Audio_port_format.nPortIndex = iInputPortIndex; // set input port as target

    // loop over supported formats until we hit the one we want
    // or until the component has no more supported formats (in which case it returns OMX_ErrorNoMore
    Err = OMX_ErrorNone;
    Audio_port_format.nIndex = 0; //init the format counter
    while (OMX_ErrorNone == Err)
    {

        Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamAudioPortFormat, &Audio_port_format);
        if ((OMX_ErrorNone != Err))
        {
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "PVMFOMXEncNode-%s::NegotiateAudioComponentParameters() Problem getting port format for input port %d or no desired port format found", iNodeTypeId, iInputPortIndex));
            return false;
        }

        if (Audio_port_format.eEncoding == DesiredPortFormat)
            break;

        Audio_port_format.nIndex ++;
    }

    // OK, we've found the desired format, set it as the one used
    Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamAudioPortFormat, &Audio_port_format);
    if ((OMX_ErrorNone != Err))
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::NegotiateAudioComponentParameters() Problem setting port format for input port %d ", iNodeTypeId, iInputPortIndex));
        return false;
    }




    CONFIG_SIZE_AND_VERSION(iParamPort);
    iParamPort.nPortIndex = iInputPortIndex;
    Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamPortDefinition, &iParamPort);
    if (Err != OMX_ErrorNone)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::NegotiateAudioComponentParameters() Problem negotiating with input port %d ", iNodeTypeId, iInputPortIndex));
        return false;
    }

    // TODO: FIX THIS - JUST READ THE BUFFER SIZE FROM COMPONENT PORT
    if (iInFormat == PVMF_MIME_PCM16)
    {
        iOMXComponentInputBufferSize = MAX_NUM_AMR_FRAMES_PER_BUFFER * (PVMF_AMRENC_DEFAULT_FRAME_DURATION * PVMF_AMRENC_DEFAULT_SAMPLING_RATE * PVMF_AMRENC_DEFAULT_BITSPERSAMPLE) / (1000 * 8);

    }
    else
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::NegotiateAudioComponentParameters() Problem with input port %d color format", iNodeTypeId, iInputPortIndex));
        return false;
    }

    // The buffer size is a read only parameter. If the requested size is larger than what we wish to allocate -
    // we'll allocate what the component desires

    if (iParamPort.nBufferSize > iOMXComponentInputBufferSize)
    {
        iOMXComponentInputBufferSize = iParamPort.nBufferSize;
    }


    // set Encoding type

    //iParamPort.format.audio.bFlagErrorConcealment = OMX_TRUE;

    // indicate that input is uncompressed i.e. PCM
    iParamPort.format.audio.eEncoding = OMX_AUDIO_CodingPCM;

    // let the component decide about the number of input buffers
    iNumInputBuffers = iParamPort.nBufferCountActual;

    // do we need to increase the number of buffers?
    if (iNumInputBuffers < iParamPort.nBufferCountMin)
        iNumInputBuffers = iParamPort.nBufferCountMin;


    // if component allows us to allocate buffers, we'll decide how many to allocate
    if (iOMXComponentSupportsExternalInputBufferAlloc && (iParamPort.nBufferCountMin < NUMBER_INPUT_BUFFER))
    {
        // preset the number of input buffers
        iNumInputBuffers = NUMBER_INPUT_BUFFER;
    }

    // set the number of input buffer
    iParamPort.nBufferCountActual = iNumInputBuffers;

    // set the number of actual input buffers
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFOMXEncNode-%s::NegotiateAudioComponentParameters() Inport buffers %d,size %d", iNodeTypeId, iNumInputBuffers, iOMXComponentInputBufferSize));

    // lock in the input port parameters
    CONFIG_SIZE_AND_VERSION(iParamPort);
    Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamPortDefinition, &iParamPort);
    if (Err != OMX_ErrorNone)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::NegotiateAudioComponentParameters() Problem setting parameters in input port %d ", iNodeTypeId, iInputPortIndex));
        return false;
    }

    // For INPUT, we also need to set the PCM parameters, such as sampling rate, etc.
    // GET the output buffer params and sizes
    OMX_AUDIO_PARAM_PCMMODETYPE Audio_Pcm_Param;
    Audio_Pcm_Param.nPortIndex = iInputPortIndex;

    CONFIG_SIZE_AND_VERSION(Audio_Pcm_Param);


    Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamAudioPcm, &Audio_Pcm_Param);
    if (Err != OMX_ErrorNone)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::NegotiateAudioComponentParameters() Problem getting PCM parameters with input port %d ", iNodeTypeId, iInputPortIndex));
        return false;
    }


    Audio_Pcm_Param.nChannels       = (OMX_U32) iAudioInputFormat.iInputNumChannels;
    Audio_Pcm_Param.eNumData        =   OMX_NumericalDataSigned; // signed
    Audio_Pcm_Param.eEndian         =   OMX_EndianLittle; // little-endian
    Audio_Pcm_Param.bInterleaved    = ((EINTERLEAVE_LR == iAudioInputFormat.iInputInterleaveMode) ? OMX_TRUE : OMX_FALSE);
    Audio_Pcm_Param.nBitPerSample   = (OMX_U32) iAudioInputFormat.iInputBitsPerSample;
    Audio_Pcm_Param.nSamplingRate   = (OMX_U32) iAudioInputFormat.iInputSamplingRate;
    Audio_Pcm_Param.ePCMMode        =   OMX_AUDIO_PCMModeLinear;
    // don't set - let use default Audio_Pcm_Param.eChannelMapping


    CONFIG_SIZE_AND_VERSION(Audio_Pcm_Param);

    Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamAudioPcm, &Audio_Pcm_Param);
    if (Err != OMX_ErrorNone)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::NegotiateAudioComponentParameters() Problem setting PCM parameters with input port %d ", iNodeTypeId, iInputPortIndex));
        return false;
    }

    //////////////////////// OUTPUT PORT////////////////////////////////////////////////

    // first of all, check if the port supports the adequate port format
    if ((iOutFormat == PVMF_MIME_AMR_IETF) ||
            (iOutFormat == PVMF_MIME_AMRWB_IETF) ||
            (iOutFormat == PVMF_MIME_AMR_IF2))
    {
        DesiredPortFormat = OMX_AUDIO_CodingAMR;
    }
    else if ((iOutFormat == PVMF_MIME_ADIF) ||
             (iOutFormat == PVMF_MIME_ADTS) ||
             (iOutFormat == PVMF_MIME_MPEG4_AUDIO))
    {
        DesiredPortFormat = OMX_AUDIO_CodingAAC;
    }
    else
    {
        DesiredPortFormat = OMX_AUDIO_CodingUnused;
    }

    if (DesiredPortFormat == OMX_AUDIO_CodingUnused)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::NegotiateAudioComponentParameters() Problem with output port %d format", iNodeTypeId, iOutputPortIndex));
        return false;
    }

    CONFIG_SIZE_AND_VERSION(Audio_port_format);

    Audio_port_format.nPortIndex = iOutputPortIndex; // set output port as target

    // loop over supported formats until we hit the one we want
    // or until the component has no more supported formats (in which case it returns OMX_ErrorNoMore
    Err = OMX_ErrorNone;
    Audio_port_format.nIndex = 0; //init the format counter
    while (OMX_ErrorNone == Err)
    {

        Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamAudioPortFormat, &Audio_port_format);
        if ((OMX_ErrorNone != Err))
        {
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "PVMFOMXEncNode-%s::NegotiateAudioComponentParameters() Problem getting port format for output port %d or no desired port format found", iNodeTypeId, iOutputPortIndex));
            return false;
        }

        if (Audio_port_format.eEncoding == DesiredPortFormat)
            break;

        Audio_port_format.nIndex ++;
    }

    // OK, we've found the desired format, set it as the one used
    Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamAudioPortFormat, &Audio_port_format);
    if ((OMX_ErrorNone != Err))
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::NegotiateAudioComponentParameters() Problem setting port format for output port %d ", iNodeTypeId, iOutputPortIndex));
        return false;
    }


    //Port 1 for output port
    CONFIG_SIZE_AND_VERSION(iParamPort);
    iParamPort.nPortIndex = iOutputPortIndex;
    Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamPortDefinition, &iParamPort);
    if (Err != OMX_ErrorNone)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::NegotiateAudioComponentParameters() Problem negotiating with output port %d ", iNodeTypeId, iOutputPortIndex));
        return false;
    }

    // let the component decide output buffer size
    iOMXComponentOutputBufferSize = iParamPort.nBufferSize;

    // let the component decide num output buffers
    iNumOutputBuffers = iParamPort.nBufferCountActual;

    //check the number
    if (iNumOutputBuffers < iParamPort.nBufferCountMin)
        iNumOutputBuffers = iParamPort.nBufferCountMin;


    // set the number ourselves
    if (iOMXComponentSupportsExternalOutputBufferAlloc && (iParamPort.nBufferCountMin < NUMBER_OUTPUT_BUFFER))
    {
        iNumOutputBuffers = NUMBER_OUTPUT_BUFFER;
    }

    iParamPort.nBufferCountActual = iNumOutputBuffers;


    // set the output (target) format, etc.
    iParamPort.format.audio.bFlagErrorConcealment = OMX_TRUE;



    if ((iOutFormat == PVMF_MIME_AMR_IETF) ||
            (iOutFormat == PVMF_MIME_AMRWB_IETF) ||
            (iOutFormat == PVMF_MIME_AMR_IF2))
    {
        iParamPort.format.audio.eEncoding = OMX_AUDIO_CodingAMR;
    }
    else if ((iOutFormat == PVMF_MIME_ADTS) ||
             (iOutFormat == PVMF_MIME_ADIF) ||
             (iOutFormat == PVMF_MIME_MPEG4_AUDIO))
    {
        iParamPort.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
    }

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFOMXEncNode-%s::NegotiateAudioComponentParameters() Outport buffers %d,size %d", iNodeTypeId, iNumOutputBuffers, iOMXComponentOutputBufferSize));


    CONFIG_SIZE_AND_VERSION(iParamPort);
    Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamPortDefinition, &iParamPort);
    if (Err != OMX_ErrorNone)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::NegotiateAudioComponentParameters() Problem setting parameters in output port %d ", iNodeTypeId, iOutputPortIndex));
        return false;

    }

    // now call codec specific parameter setting
    bool status = true;
    if ((iOutFormat == PVMF_MIME_AMR_IETF) ||
            (iOutFormat == PVMF_MIME_AMRWB_IETF) ||
            (iOutFormat == PVMF_MIME_AMR_IF2))
    {

        status = SetAMREncoderParameters();
    }
    else if ((iOutFormat == PVMF_MIME_ADTS) ||
             (iOutFormat == PVMF_MIME_ADIF) ||
             (iOutFormat == PVMF_MIME_MPEG4_AUDIO))
    {
        status = SetAACEncoderParameters();
    }


    return status;
}

bool PVMFOMXEncNode::SetAMREncoderParameters()
{

    OMX_ERRORTYPE Err = OMX_ErrorNone;
    OMX_AUDIO_PARAM_AMRTYPE AmrType;

    CONFIG_SIZE_AND_VERSION(AmrType);
    AmrType.nPortIndex = iOutputPortIndex;

    Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamAudioAmr, &AmrType);
    if (Err != OMX_ErrorNone)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::SetAMREncoderParameters - Problem getting AMR parameters in output port %d ", iNodeTypeId, iOutputPortIndex));
        return false;
    }

    AmrType.nChannels = iAudioEncodeParam.iOutputNumChannels; // must be 1

    switch (iAudioEncodeParam.iAMRBitrate)
    {
        case GSM_AMR_4_75:  // AMR NB bitrates
            AmrType.eAMRBandMode = OMX_AUDIO_AMRBandModeNB0;
            break;
        case GSM_AMR_5_15:
            AmrType.eAMRBandMode = OMX_AUDIO_AMRBandModeNB1;
            break;
        case GSM_AMR_5_90:
            AmrType.eAMRBandMode = OMX_AUDIO_AMRBandModeNB2;
            break;
        case GSM_AMR_6_70:
            AmrType.eAMRBandMode = OMX_AUDIO_AMRBandModeNB3;
            break;
        case GSM_AMR_7_40:
            AmrType.eAMRBandMode = OMX_AUDIO_AMRBandModeNB4;
            break;
        case GSM_AMR_7_95:
            AmrType.eAMRBandMode = OMX_AUDIO_AMRBandModeNB5;
            break;
        case GSM_AMR_10_2:
            AmrType.eAMRBandMode = OMX_AUDIO_AMRBandModeNB6;
            break;
        case GSM_AMR_12_2:
            AmrType.eAMRBandMode = OMX_AUDIO_AMRBandModeNB7;
            break;
        case GSM_AMR_6_60: // AMR WB bitrates start here
            AmrType.eAMRBandMode = OMX_AUDIO_AMRBandModeWB0;
            break;
        case GSM_AMR_8_85:
            AmrType.eAMRBandMode = OMX_AUDIO_AMRBandModeWB1;
            break;
        case GSM_AMR_12_65:
            AmrType.eAMRBandMode = OMX_AUDIO_AMRBandModeWB2;
            break;
        case GSM_AMR_14_25:
            AmrType.eAMRBandMode = OMX_AUDIO_AMRBandModeWB3;
            break;
        case GSM_AMR_15_85:
            AmrType.eAMRBandMode = OMX_AUDIO_AMRBandModeWB4;
            break;
        case GSM_AMR_18_25:
            AmrType.eAMRBandMode = OMX_AUDIO_AMRBandModeWB5;
            break;
        case GSM_AMR_19_85:
            AmrType.eAMRBandMode = OMX_AUDIO_AMRBandModeWB6;
            break;
        case GSM_AMR_23_05:
            AmrType.eAMRBandMode = OMX_AUDIO_AMRBandModeWB7;
            break;
        case GSM_AMR_23_85:
            AmrType.eAMRBandMode = OMX_AUDIO_AMRBandModeWB8;
            break;
        default:
            return false;
    }

    AmrType.eAMRDTXMode = OMX_AUDIO_AMRDTXModeOnAuto;

    if ((iOutFormat == PVMF_MIME_AMR_IETF) || (iOutFormat == PVMF_MIME_AMRWB_IETF))
    {
        AmrType.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
    }
    else if (iOutFormat == PVMF_MIME_AMR_IF2)
    {
        AmrType.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatIF2;
    }

    CONFIG_SIZE_AND_VERSION(AmrType);
    AmrType.nPortIndex = iOutputPortIndex;

    Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamAudioAmr, &AmrType);
    if (Err != OMX_ErrorNone)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::SetAMREncoderParameters - Problem setting AMR parameters in output port %d ", iNodeTypeId, iOutputPortIndex));
        return false;
    }

    return true;
}

bool PVMFOMXEncNode::SetAACEncoderParameters()
{

    OMX_ERRORTYPE Err = OMX_ErrorNone;
    OMX_AUDIO_PARAM_AACPROFILETYPE AacType;


    CONFIG_SIZE_AND_VERSION(AacType);
    AacType.nPortIndex = iOutputPortIndex;

    Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamAudioAac, &AacType);
    if (Err != OMX_ErrorNone)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::SetAACEncoderParameters - Problem getting AAC parameters in output port %d ", iNodeTypeId, iOutputPortIndex));
        return false;
    }

    AacType.nChannels = iAudioEncodeParam.iOutputNumChannels;
    // The following parameter could be set to input sampling rate or 0 (i.e. unknown)
    AacType.nSampleRate = iAudioEncodeParam.iOutputSamplingRate;
    // The following parameter could be set to 0 (i.e. unknown)
    AacType.nBitRate = iAudioEncodeParam.iOutputBitrate;

    // Let encoder decide the following parameters - i.e. set to 0
    AacType.nAudioBandWidth =   0;
    AacType.nFrameLength    =   0;
    AacType.nAACtools =         OMX_AUDIO_AACToolAll; // this means all tools are allowed - let encoder decide
    AacType.nAACERtools =       OMX_AUDIO_AACERNone;   // error resilience tools are not allowed

    // Set the AAC profile to use LC
    AacType.eAACProfile = OMX_AUDIO_AACObjectLC;

    // Do set the stream format
    if (iOutFormat == PVMF_MIME_ADTS)
    {
        AacType.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS;
    }
    else if (iOutFormat == PVMF_MIME_ADIF)
    {
        AacType.eAACStreamFormat = OMX_AUDIO_AACStreamFormatADIF;
    }
    else if (iOutFormat == PVMF_MIME_MPEG4_AUDIO)
    {
        AacType.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
    }

    // Set the AAC channel mode - (stereo, or mono)
    if (iAudioEncodeParam.iOutputNumChannels == 1)
    {
        AacType.eChannelMode = OMX_AUDIO_ChannelModeMono;
    }
    else if (iAudioEncodeParam.iOutputNumChannels == 2)
    {
        AacType.eChannelMode = OMX_AUDIO_ChannelModeStereo;
    }

    CONFIG_SIZE_AND_VERSION(AacType);
    AacType.nPortIndex = iOutputPortIndex;

    Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamAudioAac, &AacType);
    if (Err != OMX_ErrorNone)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::SetAACEncoderParameters - Problem setting AAC parameters in output port %d ", iNodeTypeId, iOutputPortIndex));
        return false;
    }

    return true;
}

bool PVMFOMXEncNode::SetDefaultCapabilityFlags()
{

    iIsOMXComponentMultiThreaded = true;

    iOMXComponentSupportsExternalOutputBufferAlloc = false;
    iOMXComponentSupportsExternalInputBufferAlloc = false;
    iOMXComponentSupportsMovableInputBuffers = false;

    iOMXComponentUsesNALStartCodes = true;
    iOMXComponentSupportsPartialFrames = false;
    iOMXComponentCanHandleIncompleteFrames = false;
    iOMXComponentUsesFullAVCFrames = false;

    return true;
}



bool PVMFOMXEncNode::SendEOSBufferToOMXComponent()
{

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFOMXEncNode-%s::SendEOSBufferToOMXComponent() In", iNodeTypeId));


    // first of all, check if the component is running. EOS could be sent prior to component/encoder
    // even being initialized

    // returning false will ensure that the EOS will be sent downstream anyway without waiting for the
    // Component to respond
    if (iCurrentEncoderState != OMX_StateExecuting)
        return false;

    // get an input buffer. Without a buffer, no point in proceeding
    InputBufCtrlStruct *input_buf = NULL;
    int32 errcode = 0;

    // we already checked that the number of buffers is OK, so we don't expect problems
    // try to get input buffer header
    OSCL_TRY(errcode, input_buf = (InputBufCtrlStruct *) iInBufMemoryPool->allocate(iInputAllocSize));
    if (errcode != 0)
    {
        if (errcode == OsclErrNoResources)
        {

            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger,
                            PVLOGMSG_DEBUG, (0, "PVMFOMXEncNode-%s::SendEOSBufferToOMXComponent() No more buffers in the mempool - unexpected", iNodeTypeId));

            iInBufMemoryPool->notifyfreechunkavailable(*this, (OsclAny*) iInBufMemoryPool); // To signal when next deallocate() is called on mempool

            return false;
        }
        else
        {
            // Memory allocation for the pool failed
            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                            (0, "PVMFOMXEncNode-%s::SendEOSBufferToOMXComponent() Input mempool error", iNodeTypeId));


            SetState(EPVMFNodeError);
            ReportErrorEvent(PVMFErrNoMemory);
            return false;
        }

    }

    // keep track of buffers. When buffer is deallocated/released, the counter will be decremented
    iInBufMemoryPool->notifyfreechunkavailable(*this, (OsclAny*) iInBufMemoryPool);
    iNumOutstandingInputBuffers++;

    // in this case, no need to use input msg refcounter. Make sure its unbound
    (input_buf->pMediaData).Unbind();

    // THIS IS AN EMPTY BUFFER. FLAGS ARE THE ONLY IMPORTANT THING
    input_buf->pBufHdr->nFilledLen = 0;
    input_buf->pBufHdr->nOffset = 0;

    iInputTimestampClock.update_clock(iEndOfDataTimestamp); // this will also take into consideration the rollover
    // convert TS in input timescale into OMX_TICKS
    iOMXTicksTimestamp = ConvertTimestampIntoOMXTicks(iInputTimestampClock);

    input_buf->pBufHdr->nTimeStamp = iOMXTicksTimestamp;


    // set ptr to input_buf structure for Context (for when the buffer is returned)
    input_buf->pBufHdr->pAppPrivate = (OMX_PTR) input_buf;

    // do not use Mark here (but init to NULL to prevent problems)
    input_buf->pBufHdr->hMarkTargetComponent = NULL;
    input_buf->pBufHdr->pMarkData = NULL;


    // init buffer flags
    input_buf->pBufHdr->nFlags = 0;

    input_buf->pBufHdr->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
    // most importantly, set the EOS flag:
    input_buf->pBufHdr->nFlags |= OMX_BUFFERFLAG_EOS;

    // send buffer to component
    OMX_EmptyThisBuffer(iOMXEncoder, input_buf->pBufHdr);

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFOMXEncNode-%s::SendEOSBufferToOMXComponent() Out", iNodeTypeId));

    return true;

}


bool PVMFOMXEncNode::SendInputBufferToOMXComponent()
{

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFOMXEncNode-%s::SendInputBufferToOMXComponent() In", iNodeTypeId));

    // first of all , get an input buffer. Without a buffer, no point in proceeding
    InputBufCtrlStruct *input_buf = NULL;
    int32 errcode = 0;
    uint32 ii;

    do
    {
        // do loop to loop over all fragments

        // try to get input buffer header
        InputBufCtrlStruct *temp = NULL;
        OSCL_TRY(errcode, temp = (InputBufCtrlStruct *) iInBufMemoryPool->allocate(iInputAllocSize));
        //input_buf = temp; //JJDBG
        if (errcode != 0)
        {
            if (errcode == OsclErrNoResources)
            {

                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger,
                                PVLOGMSG_DEBUG, (0, "PVMFOMXEncNode-%s::SendInputBufferToOMXComponent() No more buffers in the mempool", iNodeTypeId));

                iInBufMemoryPool->notifyfreechunkavailable(*this, (OsclAny*) iInBufMemoryPool); // To signal when next deallocate() is called on mempool

                return false;
            }
            else
            {
                // Memory allocation for the pool failed
                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                                (0, "PVMFOMXEncNode-%s::SendInputBufferToOMXComponent() Input mempool error", iNodeTypeId));


                SetState(EPVMFNodeError);
                ReportErrorEvent(PVMFErrNoMemory);
                return false;
            }

        }
        input_buf = new(temp)InputBufCtrlStruct ; //JJDBG

        // keep track of buffers. When buffer is deallocated/released, the counter will be decremented
        iInBufMemoryPool->notifyfreechunkavailable(*this, (OsclAny*) iInBufMemoryPool);
        iNumOutstandingInputBuffers++;

        for (ii = 0; ii < iNumInputBuffers; ii++)
        {
            if (input_buf == in_ctrl_struct_ptr[ii])
            {
                break;
            }
        }

        if (ii == iNumInputBuffers)
            return false;

        input_buf->pBufHdr = (OMX_BUFFERHEADERTYPE *)in_buff_hdr_ptr[ii];

        // Now we have the buffer header (i.e. a buffer) to send to component:
        // Depending on OMX component capabilities, either pass the input msg fragment(s) directly
        //  into OMX component without copying (and update the input msg refcount)
        //  or memcopy the content of input msg memfrag(s) into OMX component allocated buffers


        // if this is the first fragment in a new message, extract some info:
        if (iCurrFragNum == 0)
        {

            // NOTE: SeqNum differ in Codec and in Node because of the fact that
            // one msg can contain multiple fragments that are sent to the codec as
            // separate buffers. Node tracks msgs and codec tracks even separate fragments

            iCodecSeqNum += (iDataIn->getSeqNum() - iInPacketSeqNum); // increment the codec seq. # by the same
            // amount that the input seq. number increased

            iInPacketSeqNum = iDataIn->getSeqNum(); // remember input sequence number
            iInTimestamp = iDataIn->getTimestamp();
            iInDuration = iDataIn->getDuration();
            iInNumFrags = iDataIn->getNumFragments();



            iCurrentMsgMarkerBit = iDataIn->getMarkerInfo() & PVMF_MEDIA_DATA_MARKER_INFO_M_BIT;


            // logging info:
            if (iDataIn->getNumFragments() > 1)
            {
                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                                (0, "PVMFOMXEncNode-%s::SendInputBufferToOMXComponent() - New msg has MULTI-FRAGMENTS", iNodeTypeId));
            }

            if (!(iDataIn->getMarkerInfo() & PVMF_MEDIA_DATA_MARKER_INFO_M_BIT))
            {

                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                                (0, "PVMFOMXEncNode-%s::SendInputBufferToOMXComponent() - New msg has NO MARKER BIT", iNodeTypeId));
            }
        }


        // get a memfrag from the message
        OsclRefCounterMemFrag frag;
        iDataIn->getMediaFragment(iCurrFragNum, frag);


        if (iOMXComponentSupportsMovableInputBuffers)
        {
            // no copying required

            // increment the RefCounter of the message associated with the mem fragment/buffer
            // when sending this buffer to OMX component. (When getting the buffer back, the refcounter
            // will be decremented. Thus, when the last fragment is returned, the input mssage is finally released

            iDataIn.GetRefCounter()->addRef();

            // associate the buffer ctrl structure with the message ref counter and ptr
            input_buf->pMediaData = PVMFSharedMediaDataPtr(iDataIn.GetRep(), iDataIn.GetRefCounter());


            // set pointer to the data, length, offset
            input_buf->pBufHdr->pBuffer = (uint8 *)frag.getMemFragPtr();
            input_buf->pBufHdr->nFilledLen = frag.getMemFragSize();
            {//TODO: check whether addRef() is needed for fsi
                OsclRefCounterMemFrag fsifrag;
                iDataIn->getFormatSpecificInfo(fsifrag);
                if(sizeof(OsclAny*) != fsifrag.getMemFrag().len )
                {
                    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
                            (0, "PVMFOMXEncNode-%s::SendInputBufferToOMXComponent() - ERROR buffer size %d", iNodeTypeId, fsifrag.getMemFrag().len ));
                    return false;
                }
                oscl_memcpy(&(input_buf->pBufHdr->pPlatformPrivate), fsifrag.getMemFragPtr(), sizeof(OsclAny*) ); // restore ptr data from fsi
            }

            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "PVMFOMXEncNode-%s::SendInputBufferToOMXComponent() - Buffer 0x%x of size %d, %d frag out of tot. %d, TS=%d, Ticks=%L", iNodeTypeId, input_buf->pBufHdr->pBuffer, frag.getMemFragSize(), iCurrFragNum + 1, iDataIn->getNumFragments(), iInTimestamp, iOMXTicksTimestamp));

            iCurrFragNum++; // increment fragment number and move on to the next


        }
        else
        {

            // in this case, no need to use input msg refcounter, each buffer fragment is copied over and treated separately
            (input_buf->pMediaData).Unbind();


            // init variables
            iCopyPosition = 0;
            iFragmentSizeRemainingToCopy  = frag.getMemFragSize();


            // can the remaining fragment fit into the buffer?
            if (iFragmentSizeRemainingToCopy <= (input_buf->pBufHdr->nAllocLen))
            {

                oscl_memcpy(input_buf->pBufHdr->pBuffer,
                            (void *)((uint8 *)frag.getMemFragPtr() + iCopyPosition),
                            iFragmentSizeRemainingToCopy);

                input_buf->pBufHdr->nFilledLen = iFragmentSizeRemainingToCopy;

                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                                (0, "PVMFOMXEncNode-%s::SendInputBufferToOMXComponent() - Copied %d bytes of fragment %d out of %d into buffer 0x%x of size %d, TS=%d, Ticks=%L ", iNodeTypeId, iFragmentSizeRemainingToCopy, iCurrFragNum + 1, iDataIn->getNumFragments(), input_buf->pBufHdr->pBuffer, input_buf->pBufHdr->nFilledLen, iInTimestamp, iOMXTicksTimestamp));

                iCopyPosition += iFragmentSizeRemainingToCopy;
                iFragmentSizeRemainingToCopy = 0;



            }
            else
            {
                // copy as much as you can of the current fragment into the current buffer
                oscl_memcpy(input_buf->pBufHdr->pBuffer,
                            (void *)((uint8 *)frag.getMemFragPtr() + iCopyPosition),
                            input_buf->pBufHdr->nAllocLen);

                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                                (0, "PVMFOMXEncNode-%s::SendInputBufferToOMXComponent() - Frame cannot fit into input buffer ! Copied %d bytes of fragment %d out of %d into buffer 0x%x of size %d, TS=%d, Ticks=%L", iNodeTypeId, input_buf->pBufHdr->nAllocLen, iCurrFragNum + 1, iDataIn->getNumFragments(), input_buf->pBufHdr->pBuffer, input_buf->pBufHdr->nFilledLen, iInTimestamp, iOMXTicksTimestamp));

                input_buf->pBufHdr->nFilledLen = input_buf->pBufHdr->nAllocLen;
                iCopyPosition += input_buf->pBufHdr->nAllocLen; // move current position within fragment forward
                iFragmentSizeRemainingToCopy -= input_buf->pBufHdr->nAllocLen;

            }

            // proceed to the next fragment regardless of input buffer size
            iCurrFragNum++;
        }


        // set buffer fields (this is the same regardless of whether the input is movable or not
        input_buf->pBufHdr->nOffset = 0;


        iInputTimestampClock.update_clock(iInTimestamp); // this will also take into consideration the timestamp rollover
        // convert TS in input timescale into OMX_TICKS
        iOMXTicksTimestamp = ConvertTimestampIntoOMXTicks(iInputTimestampClock);


        input_buf->pBufHdr->nTimeStamp = iOMXTicksTimestamp;


        // set ptr to input_buf structure for Context (for when the buffer is returned)
        input_buf->pBufHdr->pAppPrivate = (OMX_PTR) input_buf;

        // do not use Mark here (but init to NULL to prevent problems)
        input_buf->pBufHdr->hMarkTargetComponent = NULL;
        input_buf->pBufHdr->pMarkData = NULL;


        // init buffer flags
        input_buf->pBufHdr->nFlags = 0;


        // set the key frame flag if necessary (mark every fragment that belongs to it)
        if (iDataIn->getMarkerInfo() & PVMF_MEDIA_DATA_MARKER_INFO_RANDOM_ACCESS_POINT_BIT)
            input_buf->pBufHdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;


        // in case of encoder, all input frames should be marked
        input_buf->pBufHdr->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
        OMX_ERRORTYPE myret = OMX_EmptyThisBuffer(iOMXEncoder, input_buf->pBufHdr);
        if(OMX_ErrorNone != myret )
        {
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFOMXEncNode-%s::SendInputBufferToOMXComponent() OMX_EmptyThisBuffer ERROR %d", iNodeTypeId, myret));
            return false;
        }

        // if we sent all fragments to OMX component, decouple the input message from iDataIn
        // Input message is "decoupled", so that we can get a new message for processing into iDataIn
        //  However, the actual message is released completely to upstream mempool once all of its fragments
        //  are returned by the OMX component

        if (iCurrFragNum == iDataIn->getNumFragments())
        {
            iDataIn.Unbind();

        }


    }
    while (iCurrFragNum < iInNumFrags); //iDataIn->getNumFragments());


    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFOMXEncNode-%s::SendInputBufferToOMXComponent() Out", iNodeTypeId));

    return true;

}



/////////////////////////////////////////////////////////////////////////////
bool PVMFOMXEncNode::CreateOutMemPool(uint32 num_buffers)
{

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFOMXEncNode-%s::CreateOutMemPool() start", iNodeTypeId));
    // In the case OMX component wants to allocate its own buffers,
    // mempool only contains OutputBufCtrlStructures (i.e. ptrs to buffer headers)
    // In case OMX component uses pre-allocated buffers (here),
    // mempool allocates OutputBufCtrlStructure (i.e. ptrs to buffer hdrs), followed by actual buffers

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFOMXEncNode-%s::CreateOutMemPool() Allocating output buffer header pointers", iNodeTypeId));

    iOutputAllocSize = oscl_mem_aligned_size((uint32)sizeof(OutputBufCtrlStruct));

    if (iOMXComponentSupportsExternalOutputBufferAlloc)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::CreateOutMemPool() Allocating output buffers of size %d as well", iNodeTypeId, iOMXComponentOutputBufferSize));

        //pre-negotiated output buffer size
        iOutputAllocSize += iOMXComponentOutputBufferSize;
    }

    // ENCODER SPECIFIC FOR AVC RAW (BYTESTREAM) FORMAT
    if ((iOutFormat == PVMF_MIME_H264_VIDEO_RAW) &&
            (!iOMXComponentUsesFullAVCFrames) &&
            (!iOMXComponentUsesNALStartCodes))
    {
        iOutputAllocSize += 4; // NAL SYNC WORD SIZE
    }

    // for media data wrapper
    if (iMediaDataMemPool)
    {
        iMediaDataMemPool->removeRef();
        iMediaDataMemPool = NULL;
    }

    if (iOutBufMemoryPool)
    {
        iOutBufMemoryPool->removeRef();
        iOutBufMemoryPool = NULL;
    }

    int32 leavecode = 0;
    OSCL_TRY(leavecode, iOutBufMemoryPool = OSCL_NEW(OsclMemPoolFixedChunkAllocator, (num_buffers)););
    if (leavecode || iOutBufMemoryPool == NULL)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger,
                        PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::CreateOutMemPool() Memory pool structure for output buffers failed to allocate", iNodeTypeId));
        return false;
    }



    // allocate a dummy buffer to actually create the mempool
    OsclAny *dummy_alloc = NULL; // this dummy buffer will be released at end of scope
    leavecode = 0;
    OSCL_TRY(leavecode, dummy_alloc = iOutBufMemoryPool->allocate(iOutputAllocSize));
    if (leavecode || dummy_alloc == NULL)
    {

        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger,
                        PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::CreateOutMemPool() Memory pool for output buffers failed to allocate", iNodeTypeId));
        return false;
    }
    iOutBufMemoryPool->deallocate(dummy_alloc);
    // init the counter
    iNumOutstandingOutputBuffers = 0;

    // allocate mempool for media data message wrapper
    leavecode = 0;
    OSCL_TRY(leavecode, iMediaDataMemPool = OSCL_NEW(OsclMemPoolFixedChunkAllocator, (num_buffers, PVOMXENC_MEDIADATA_CHUNKSIZE)));
    if (leavecode || iMediaDataMemPool == NULL)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::CreateOutMemPool() Media Data Buffer pool for output buffers failed to allocate", iNodeTypeId));
        return false;
    }

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::CreateOutMemPool() done", iNodeTypeId));
    return true;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////// Creates memory pool for input buffer management ///////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////
bool PVMFOMXEncNode::CreateInputMemPool(uint32 num_buffers)
{
    // 3 cases in order of preference and simplicity

    // Case 1 (buffers allocated upstream - no memcpy needed):
    //  PV OMX Component - We use buffers allocated outside the OMX node (i.e. allocated upstream)
    // Mempool contains InputBufCtrlStructures (ptrs to buffer headers and PMVFMediaData ptrs - to keep track of when to unbind input msgs)

    // NOTE:    in this case, when providing input buffers to OMX component,
    //          OMX_UseBuffer calls will provide some initial pointers and sizes of buffers, but these
    //          are dummy values. Actual buffer pointers and filled sizes will be obtained from the input msg fragments.
    //          The PV OMX component will use the buffers even if the ptrs differ from the ones during initialization
    //          3rd party OMX components can also use this case if they are capable of ignoring the actual buffer pointers in
    //          buffer header field (i.e. if after OMX_UseBuffer(...) call, they allow the ptr to actual buffer data to change at a later time

    // CASE 2 (buffers allocated in the node - memcpy needed)
    //          If 3rd party OMX component can use buffers allocated outside the OMX component, but it cannot
    //          change buffer ptr allocations dynamically (i.e. after initialization with OMX_UseBuffer call is complete)

    //      Mempool contains InputBufCtrlStructures (ptrs to buffer headers, PVMFMediaData ptrs to keep track of when to unbind input msgs) +
    //              actual buffers.
    //          NOTE: Data must be copied from input message into the local buffer before the buffer is given to the OMX component

    // CASE 3 (buffers allocated in the component - memcpy needed)
    //          If 3rd party OMX component must allocate its own buffers
    //          Mempool only contains InputBufCtrlStruct (ptrs to buffer headers + PMVFMediaData ptrs to keep track of when to unbind input msgs)
    //          NOTE: Data must be copied from input message into the local buffer before the buffer is given to the OMX component (like in case 2)

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFOMXEncNode-%s::CreateInputMemPool() start ", iNodeTypeId));

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFOMXEncNode-%s::CreateInputMemPool() allocating buffer header pointers and shared media data ptrs ", iNodeTypeId));



    iInputAllocSize = oscl_mem_aligned_size((uint32) sizeof(InputBufCtrlStruct)); //aligned_size_buffer_header_ptr+aligned_size_media_data_ptr;

    // Need to allocate buffers in the node either if component supports external buffers buffers
    // but they are not movable

    if ((iOMXComponentSupportsExternalInputBufferAlloc && !iOMXComponentSupportsMovableInputBuffers))
    {
        //pre-negotiated input buffer size
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::CreateOutMemPool() Allocating input buffers of size %d as well", iNodeTypeId, iOMXComponentInputBufferSize));

        iInputAllocSize += iOMXComponentInputBufferSize;
    }

    if (iInBufMemoryPool)
    {
        iInBufMemoryPool->removeRef();
        iInBufMemoryPool = NULL;
    }

    int32 leavecode = 0;
    OSCL_TRY(leavecode, iInBufMemoryPool = OSCL_NEW(OsclMemPoolFixedChunkAllocator, (num_buffers)););
    if (leavecode || iInBufMemoryPool == NULL)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger,
                        PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::CreateInputMemPool() Memory pool structure for input buffers failed to allocate", iNodeTypeId));
        return false;
    }
    // try to allocate a dummy buffer to actually create the mempool and allocate the needed memory
    // allocate a dummy buffer to actually create the mempool, this dummy buffer will be released at end of scope of this method
    OsclAny *dummy_alloc = NULL;
    leavecode = 0;
    OSCL_TRY(leavecode, dummy_alloc = iInBufMemoryPool->allocate(iInputAllocSize));
    if (leavecode || dummy_alloc == NULL)
    {

        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger,
                        PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::CreateInputMemPool() Memory pool for input buffers failed to allocate", iNodeTypeId));
        return false;
    }

    // init the counter
    iNumOutstandingInputBuffers = 0;


    iInputBufferToResendToComponent = NULL; // nothing to resend yet
    iInBufMemoryPool->deallocate(dummy_alloc);

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::CreateInputMemPool() done", iNodeTypeId));
    return true;
}
////////////////////////////////////////////////////////////////////////////
bool PVMFOMXEncNode::ProvideBuffersToComponent(OsclMemPoolFixedChunkAllocator *aMemPool, // allocator
        uint32 aAllocSize,    // size to allocate from pool (hdr only or hdr+ buffer)
        uint32 aNumBuffers,    // number of buffers
        uint32 aActualBufferSize, // aactual buffer size
        uint32 aPortIndex,      // port idx
        bool aUseBufferOK,       // can component use OMX_UseBuffer or should it use OMX_AllocateBuffer
        bool aIsThisInputBuffer      // is this input or output
                                              )
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::ProvideBuffersToComponent() enter", iNodeTypeId));

    uint32 ii = 0;
    OMX_ERRORTYPE err = OMX_ErrorNone;
    OsclAny **ctrl_struct_ptr = aIsThisInputBuffer ? in_ctrl_struct_ptr : out_ctrl_struct_ptr;

    // Now, go through all buffers and tell component to
    // either use a buffer, or to allocate its own buffer
    for (ii = 0; ii < aNumBuffers; ii++)
    {

        int32 errcode = 0;
        // get the address where the buf hdr ptr will be stored
        errcode = MemAllocate(ctrl_struct_ptr[ii], aMemPool, aAllocSize);
        if ((errcode != OsclErrNone) || (ctrl_struct_ptr[ii] == NULL))
        {
            if (errcode == OsclErrNoResources)
            {
                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                                (0, "PVMFOMXEncNode-%s::ProvideBuffersToComponent ->allocate() failed for no mempool chunk available", iNodeTypeId));
            }
            else
            {
                // General error
                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                                (0, "PVMFOMXEncNode-%s::ProvideBuffersToComponent ->allocate() failed due to some general error", iNodeTypeId));

                ReportErrorEvent(PVMFFailure);
                ChangeNodeState(EPVMFNodeError);
            }

            return false;
        }

        if (aUseBufferOK)
        {
            // Buffers are already allocated outside OMX component.
            // In case of output buffers, the buffer itself is located
            // just after the buffer header pointer.

            // In case of input buffers, the buffer header pointer is followed by a MediaDataSharedPtr
            //  which is used to ensure proper unbinding of the input messages. The buffer itself is either:
            //      a) allocated upstream (and the ptr to the buffer
            //          is a dummy pointer to which the component does not pay attention - PV OMX component)
            //      b) located just after the buffer header pointer and MediaDataSharedPtr

            uint8 *pB = ((uint8*) ctrl_struct_ptr[ii]);


            // in case of input buffers, initialize also MediaDataSharedPtr structure
            if (aIsThisInputBuffer)
            {

                InputBufCtrlStruct *temp = (InputBufCtrlStruct *) ctrl_struct_ptr[ii];
                oscl_memset(&(temp->pMediaData), 0, sizeof(PVMFSharedMediaDataPtr));
                temp->pMediaData = PVMFSharedMediaDataPtr(NULL, NULL);

                // advance ptr to skip the structure
                pB += oscl_mem_aligned_size(sizeof(InputBufCtrlStruct));

                err = OMX_UseBuffer(iOMXEncoder,    // hComponent
                                    &(temp->pBufHdr),       // address where ptr to buffer header will be stored
                                    aPortIndex,             // port index (for port for which buffer is provided)
                                    ctrl_struct_ptr[ii],    // App. private data = pointer to beginning of allocated data
                                    //              to have a context when component returns with a callback (i.e. to know
                                    //              what to free etc.
                                    (OMX_U32)aActualBufferSize,     // buffer size
                                    pB);                        // buffer data ptr

                in_buff_hdr_ptr[ii] = temp->pBufHdr;

            }
            else
            {
                OutputBufCtrlStruct *temp = (OutputBufCtrlStruct *) ctrl_struct_ptr[ii];
                // advance buffer ptr to skip the structure
                pB += oscl_mem_aligned_size(sizeof(OutputBufCtrlStruct));

                if ((iOutFormat == PVMF_MIME_H264_VIDEO_RAW) &&
                        !iOMXComponentUsesFullAVCFrames &&
                        !iOMXComponentUsesNALStartCodes)
                {
                    // write out NAL sync word at the beginning of the buffer
                    pB[0] = 0;
                    pB[1] = 0;
                    pB[2] = 0;
                    pB[3] = 1;
                    pB += 4;

                    // THe buffer that the component knows is always the same
                    // The node will move the ptr -4 when it needs teh sync word
                }

                err = OMX_UseBuffer(iOMXEncoder,    // hComponent
                                    &(temp->pBufHdr),       // address where ptr to buffer header will be stored
                                    aPortIndex,             // port index (for port for which buffer is provided)
                                    ctrl_struct_ptr[ii],    // App. private data = pointer to beginning of allocated data
                                    //              to have a context when component returns with a callback (i.e. to know
                                    //              what to free etc.
                                    (OMX_U32)aActualBufferSize,     // buffer size
                                    pB);                        // buffer data ptr

                out_buff_hdr_ptr[ii] = temp->pBufHdr;


            }


        }
        else
        {
            // the component must allocate its own buffers.
            if (aIsThisInputBuffer)
            {

                InputBufCtrlStruct *temp = (InputBufCtrlStruct *) ctrl_struct_ptr[ii];
                // initialize the media data field to 0 //TODO cleanup work started in another record. JJ 05/12/09
                oscl_memset(&(temp->pMediaData), 0, sizeof(PVMFSharedMediaDataPtr));
                temp->pMediaData = PVMFSharedMediaDataPtr(NULL, NULL);

                err = OMX_AllocateBuffer(iOMXEncoder,
                                         &(temp->pBufHdr),
                                         aPortIndex,
                                         ctrl_struct_ptr[ii],
                                         (OMX_U32)aActualBufferSize);

                in_buff_hdr_ptr[ii] = temp->pBufHdr;
            }
            else
            {
                OutputBufCtrlStruct *temp = (OutputBufCtrlStruct *) ctrl_struct_ptr[ii];
                err = OMX_AllocateBuffer(iOMXEncoder,
                                         &(temp->pBufHdr),
                                         aPortIndex,
                                         ctrl_struct_ptr[ii],
                                         (OMX_U32)aActualBufferSize);

                out_buff_hdr_ptr[ii] = temp->pBufHdr;
            }

        }

        if (err != OMX_ErrorNone)
        {
            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                            (0, "PVMFOMXEncNode-%s::ProvideBuffersToComponent() Problem using/allocating a buffer", iNodeTypeId));


            return false;
        }

    }

    for (ii = 0; ii < aNumBuffers; ii++)
    {
        // after initializing the buffer hdr ptrs, return them
        // to the mempool
        aMemPool->deallocate((OsclAny*) ctrl_struct_ptr[ii]);
    }

    // set the flags
    if (aIsThisInputBuffer)
    {
        iInputBuffersFreed = false;
    }
    else
    {
        iOutputBuffersFreed = false;
    }

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::ProvideBuffersToComponent() done", iNodeTypeId));
    return true;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool PVMFOMXEncNode::FreeBuffersFromComponent(OsclMemPoolFixedChunkAllocator *aMemPool, // allocator
        uint32 aAllocSize,     // size to allocate from pool (hdr only or hdr+ buffer)
        uint32 aNumBuffers,    // number of buffers
        uint32 aPortIndex,      // port idx
        bool  aIsThisInputBuffer      // is this input or output
                                             )
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::FreeBuffersToComponent() enter", iNodeTypeId));

    uint32 ii = 0;
    OMX_ERRORTYPE err = OMX_ErrorNone;
    OsclAny **ctrl_struct_ptr = aIsThisInputBuffer ? in_ctrl_struct_ptr : out_ctrl_struct_ptr;

    // Now, go through all buffers and tell component to free them
    for (ii = 0; ii < aNumBuffers; ii++)
    {

        int32 errcode = 0;
        // get the address where the buf hdr ptr will be stored

        errcode = MemAllocate(ctrl_struct_ptr[ii], aMemPool, aAllocSize);
        if ((errcode != OsclErrNone) || (ctrl_struct_ptr[ii] == NULL))
        {
            if (errcode == OsclErrNoResources)
            {
                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                                (0, "PVMFOMXEncNode-%s::FreeBuffersFromComponent ->allocate() failed for no mempool chunk available", iNodeTypeId));
            }
            else
            {
                // General error
                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                                (0, "PVMFOMXEncNode-%s::FreeBuffersFromComponent ->allocate() failed due to some general error", iNodeTypeId));

                ReportErrorEvent(PVMFFailure);
                ChangeNodeState(EPVMFNodeError);
            }

            return false;
        }
        // to maintain correct count
        aMemPool->notifyfreechunkavailable((*this), (OsclAny*) aMemPool);

        if (aIsThisInputBuffer)
        {

            iNumOutstandingInputBuffers++;
            // get the buf hdr pointer
            InputBufCtrlStruct *temp = (InputBufCtrlStruct *) ctrl_struct_ptr[ii];

            if(ipExternalInputBufferAllocatorInterface && ipFixedSizeBufferAlloc)
            {
                ipFixedSizeBufferAlloc->deallocate((OsclAny*) temp->pBufHdr->pBuffer);
            }
            err = OMX_FreeBuffer(iOMXEncoder,
                                 aPortIndex,
                                 temp->pBufHdr);

        }
        else
        {
            iNumOutstandingOutputBuffers++;
            OutputBufCtrlStruct *temp = (OutputBufCtrlStruct *) ctrl_struct_ptr[ii];
            err = OMX_FreeBuffer(iOMXEncoder,
                                 aPortIndex,
                                 temp->pBufHdr);

        }

        if (err != OMX_ErrorNone)
        {
            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                            (0, "PVMFOMXEncNode-%s::FreeBuffersFromComponent() Problem freeing a buffer", iNodeTypeId));

            return false;
        }

    }

    for (ii = 0; ii < aNumBuffers; ii++)
    {
        // after freeing the buffer hdr ptrs, return them
        // to the mempool (which will itself then be deleted promptly)
        aMemPool->deallocate((OsclAny*) ctrl_struct_ptr[ii]);
    }


    // mark buffers as freed (so as not to do it twice)
    if (aIsThisInputBuffer)
    {
        oscl_free(in_ctrl_struct_ptr);
        oscl_free(in_buff_hdr_ptr);

        in_ctrl_struct_ptr = NULL;
        in_buff_hdr_ptr = NULL;
        iInputBuffersFreed = true;

        if(ipExternalInputBufferAllocatorInterface)
        {
            ipExternalInputBufferAllocatorInterface->removeRef();
            ipExternalInputBufferAllocatorInterface = NULL;
        }
    }
    else
    {
        oscl_free(out_ctrl_struct_ptr);
        oscl_free(out_buff_hdr_ptr);

        out_ctrl_struct_ptr = NULL;
        out_buff_hdr_ptr = NULL;

        iOutputBuffersFreed = true;
    }
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::FreeBuffersFromComponent() done", iNodeTypeId));
    return true;
}



/////////////////////////////////////////////////////////////////////////////
////////////////////// CALLBACK PROCESSING FOR EVENT HANDLER
/////////////////////////////////////////////////////////////////////////////
OMX_ERRORTYPE PVMFOMXEncNode::EventHandlerProcessing(OMX_OUT OMX_HANDLETYPE aComponent,
        OMX_OUT OMX_PTR aAppData,
        OMX_OUT OMX_EVENTTYPE aEvent,
        OMX_OUT OMX_U32 aData1,
        OMX_OUT OMX_U32 aData2,
        OMX_OUT OMX_PTR aEventData)
{
    OSCL_UNUSED_ARG(aComponent);
    OSCL_UNUSED_ARG(aAppData);
    OSCL_UNUSED_ARG(aEventData);

    switch (aEvent)
    {
        case OMX_EventCmdComplete:
        {

            switch (aData1)
            {
                case OMX_CommandStateSet:
                {
                    HandleComponentStateChange(aData2);
                    break;
                }
                case OMX_CommandFlush:            //not supported
                    // nothing to do here yet
                    break;

                case OMX_CommandPortDisable:
                {
                    // if port disable command is done, we can re-allocate the buffers and re-enable the port

                    iProcessingState = EPVMFOMXEncNodeProcessingState_PortReEnable;
                    iPortIndexForDynamicReconfig =  aData2;

                    RunIfNotReady();
                    break;
                }
                case OMX_CommandPortEnable:
                    // port enable command is done. Check if the other port also reported change.
                    // If not, we can start data flow. Otherwise, must start dynamic reconfig procedure for
                    // the other port as well.
                {
                    if (iSecondPortReportedChange)
                    {
                        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
                                        (0, "PVMFOMXEncNode-%s::EventHandlerProcessing: OMX_CommandPortEnable - completed on port %d, dynamic reconfiguration needed on port %d", iNodeTypeId, aData2, iSecondPortToReconfig));

                        iProcessingState = EPVMFOMXEncNodeProcessingState_PortReconfig;
                        iPortIndexForDynamicReconfig = iSecondPortToReconfig;
                        iSecondPortReportedChange = false;
                    }
                    else
                    {
                        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
                                        (0, "PVMFOMXEncNode-%s::EventHandlerProcessing: OMX_CommandPortEnable - completed on port %d, resuming normal data flow", iNodeTypeId, aData2));
                        iProcessingState = EPVMFOMXEncNodeProcessingState_ReadyToEncode;
                        iDynamicReconfigInProgress = false;
                    }
                    RunIfNotReady();
                    break;
                }

                case OMX_CommandMarkBuffer:
                    // nothing to do here yet;
                    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
                                    (0, "PVMFOMXEncNode-%s::EventHandlerProcessing: OMX_CommandMarkBuffer - completed - no action taken", iNodeTypeId));

                    break;

                default:
                {
                    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
                                    (0, "PVMFOMXEncNode-%s::EventHandlerProcessing: Unsupported event", iNodeTypeId));
                    break;
                }
            }//end of switch (aData1)

            break;
        }//end of case OMX_EventCmdComplete

        case OMX_EventError:
        {
            LOGE("Ln %d OMX_EventError nData1 %d nData2 %d", __LINE__, aData1, aData2);

            if (aData1 == (OMX_U32) OMX_ErrorStreamCorrupt)
            {
                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
                                (0, "PVMFOMXEncNode-%s::EventHandlerProcessing: OMX_EventError - Bitstream corrupt error", iNodeTypeId));
                // Errors from corrupt bitstream are reported as info events
                ReportInfoEvent(PVMFInfoProcessingFailure, NULL);

            }
            else if (aData1 == (OMX_U32) OMX_ErrorInvalidState)
            {
                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
                                (0, "PVMFOMXEncNode-%s::EventHandlerProcessing: OMX_EventError - OMX_ErrorInvalidState", iNodeTypeId));
                HandleComponentStateChange(OMX_StateInvalid);
            }
            else
            {
                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
                                (0, "PVMFOMXEncNode-%s::EventHandlerProcessing: OMX_EventError", iNodeTypeId));
                // for now, any error from the component will be reported as error
                ReportErrorEvent(PVMFErrProcessing, NULL, NULL);
                SetState(EPVMFNodeError);
            }
            break;

        }

        case OMX_EventBufferFlag:
        {
            // the component is reporting it encountered end of stream flag
            // we'll send eos when we get the actual last buffer with marked eos

            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "PVMFOMXEncNode-%s::EventHandlerProcessing: OMX_EventBufferFlag (EOS) flag returned from OMX component", iNodeTypeId));

            RunIfNotReady();
            break;
        }//end of case OMX_EventBufferFlag

        case OMX_EventMark:
        {

            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "PVMFOMXEncNode-%s::EventHandlerProcessing: OMX_EventMark returned from OMX component - no action taken", iNodeTypeId));

            RunIfNotReady();
            break;
        }//end of case OMX_EventMark

        case OMX_EventPortSettingsChanged:
        {

            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "PVMFOMXEncNode-%s::EventHandlerProcessing: OMX_EventPortSettingsChanged returned from OMX component", iNodeTypeId));

            // first check if dynamic reconfiguration is already in progress,
            // if so, wait until this is completed, and then initiate the 2nd reconfiguration
            if (iDynamicReconfigInProgress)
            {
                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                                (0, "PVMFOMXEncNode-%s::EventHandlerProcessing: OMX_EventPortSettingsChanged returned for port %d, dynamic reconfig already in progress", iNodeTypeId, aData1));

                iSecondPortToReconfig = aData1;
                iSecondPortReportedChange = true;
            }
            else
            {
                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                                (0, "PVMFOMXEncNode-%s::EventHandlerProcessing: OMX_EventPortSettingsChanged returned for port %d", iNodeTypeId, aData1));

                iProcessingState = EPVMFOMXEncNodeProcessingState_PortReconfig;
                iPortIndexForDynamicReconfig = aData1;
                iDynamicReconfigInProgress = true;
            }

            RunIfNotReady();
            break;
        }//end of case OMX_PortSettingsChanged

        case OMX_EventResourcesAcquired:        //not supported
        {
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "PVMFOMXEncNode-%s::EventHandlerProcessing: OMX_EventResourcesAcquired returned from OMX component - no action taken", iNodeTypeId));

            RunIfNotReady();

            break;
        }

        default:
        {
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "PVMFOMXEncNode-%s::EventHandlerProcessing:  Unknown Event returned from OMX component - no action taken", iNodeTypeId));

            break;
        }

    }//end of switch (eEvent)



    return OMX_ErrorNone;
}




/////////////////////////////////////////////////////////////////////////////
// This function handles the event of OMX component state change
/////////////////////////////////////////////////////////////////////////////
void PVMFOMXEncNode::HandleComponentStateChange(OMX_U32 encoder_state)
{
    switch (encoder_state)
    {
        case OMX_StateIdle:
        {
            iCurrentEncoderState = OMX_StateIdle;

            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "PVMFOMXEncNode-%s::HandleComponentStateChange: OMX_StateIdle reached", iNodeTypeId));

            //  this state can be reached either going from OMX_Loaded->OMX_Idle (preparing)
            //  or going from OMX_Executing->OMX_Idle (stopping)


            if ((iCurrentCommand.size() > 0) &&
                    (iCurrentCommand.front().iCmd == PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_PREPARE))
            {
                iProcessingState = EPVMFOMXEncNodeProcessingState_ReadyToEncode;
                SetState(EPVMFNodePrepared);
                CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFSuccess);
                RunIfNotReady();
            }
            else if ((iCurrentCommand.size() > 0) &&
                     (iCurrentCommand.front().iCmd == PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_STOP))
            {
                // if we are stopped, we won't start until the node gets DoStart command.
                //  in this case, we are ready to start sending buffers
                if (iProcessingState == EPVMFOMXEncNodeProcessingState_Stopping)
                    iProcessingState = EPVMFOMXEncNodeProcessingState_ReadyToEncode;
                // if the processing state was not stopping, leave the state as it was (continue port reconfiguration)
                SetState(EPVMFNodePrepared);
                CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFSuccess);

                RunIfNotReady();
            }
            else if ((iCurrentCommand.size() > 0) &&
                     (iCurrentCommand.front().iCmd == PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_FLUSH))
            {
                // if there is a flush, similar to the case of stop, we won't start until the node gets
                // DoStart command. In this case, we'll be ready
                if (iProcessingState == EPVMFOMXEncNodeProcessingState_Stopping)
                    iProcessingState = EPVMFOMXEncNodeProcessingState_ReadyToEncode;



                //Flush is complete.  Go to prepared state.
                SetState(EPVMFNodePrepared);
                //resume port input (if possible) so the ports can be re-started.
                if (iInPort)
                {
                    iInPort->ResumeInput();
                }
                if (iOutPort)
                {
                    iOutPort->ResumeInput();
                }
                CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFSuccess);
                RunIfNotReady();

            }
            else if ((iCurrentCommand.size() > 0) &&
                     (iCurrentCommand.front().iCmd == PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_RESET))
            {
                // State change to Idle was initiated due to Reset. First need to reach idle, and then loaded
                // Once Idle is reached, we need to initiate idle->loaded transition
                iStopInResetMsgSent = false;
                RunIfNotReady();
            }
            break;
        }//end of case OMX_StateIdle

        case OMX_StateExecuting:
        {
            iCurrentEncoderState = OMX_StateExecuting;

            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "PVMFOMXEncNode-%s::HandleComponentStateChange: OMX_StateExecuting reached", iNodeTypeId));

            // this state can be reached going from OMX_Idle -> OMX_Executing (preparing)
            //  or going from OMX_Pause -> OMX_Executing (coming from pause)
            //  either way, this is a response to "DoStart" command

            if ((iCurrentCommand.size() > 0) &&
                    (iCurrentCommand.front().iCmd == PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_START))
            {
                SetState(EPVMFNodeStarted);
                CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFSuccess);

                RunIfNotReady();
            }

            break;
        }//end of case OMX_StateExecuting

        case OMX_StatePause:
        {
            iCurrentEncoderState = OMX_StatePause;

            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "PVMFOMXEncNode-%s::HandleComponentStateChange: OMX_StatePause reached", iNodeTypeId));


            //  This state can be reached going from OMX_Executing-> OMX_Pause
            if ((iCurrentCommand.size() > 0) &&
                    (iCurrentCommand.front().iCmd == PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_PAUSE))
            {
                SetState(EPVMFNodePaused);
                CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFSuccess);
                RunIfNotReady();
            }

            break;
        }//end of case OMX_StatePause

        case OMX_StateLoaded:
        {
            iCurrentEncoderState = OMX_StateLoaded;

            //  this state can be reached only going from OMX_Idle ->OMX_Loaded (stopped to reset)
            //

            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "PVMFOMXEncNode-%s::HandleComponentStateChange: OMX_StateLoaded reached", iNodeTypeId));
            //Check if command's responce is pending
            if ((iCurrentCommand.size() > 0) &&
                    (iCurrentCommand.front().iCmd == PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_RESET))
            {

                // move this here
                if (iInPort)
                {
                    OSCL_DELETE(((PVMFOMXEncPort*)iInPort));
                    iInPort = NULL;
                }

                if (iOutPort)
                {
                    OSCL_DELETE(((PVMFOMXEncPort*)iOutPort));
                    iOutPort = NULL;
                }

                iDataIn.Unbind();

                // Reset the metadata key list
                iAvailableMetadataKeys.clear();


                iProcessingState = EPVMFOMXEncNodeProcessingState_Idle;
                //logoff & go back to Created state.
                SetState(EPVMFNodeIdle);
                CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFSuccess);
                iResetInProgress = false;
                iResetMsgSent = false;
            }

            break;
        }//end of case OMX_StateLoaded

        case OMX_StateInvalid:
        default:
        {
            iCurrentEncoderState = OMX_StateInvalid;

            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
                            (0, "PVMFOMXEncNode-%s::HandleComponentStateChange: OMX_StateInvalid reached", iNodeTypeId));
            //Clearup encoder
            DeleteOMXEncoder();

            if (iCurrentCommand.size() > 0)
            {//can NOT be CANCEL or CANCEL_ALL. Just to cmd completion for the rest
                if (iCurrentCommand.front().iCmd == PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_RESET)
                {
                    //delete all ports and notify observer.
                    if (iInPort)
                    {
                        OSCL_DELETE(((PVMFOMXEncPort*)iInPort));
                        iInPort = NULL;
                    }

                    if (iOutPort)
                    {
                        OSCL_DELETE(((PVMFOMXEncPort*)iOutPort));
                        iOutPort = NULL;
                    }

                    iDataIn.Unbind();

                    // Reset the metadata key list
                    iAvailableMetadataKeys.clear();

                    iEndOfDataReached = false;
                    iIsEOSSentToComponent = false;
                    iIsEOSReceivedFromComponent = false;

                    iProcessingState = EPVMFOMXEncNodeProcessingState_Idle;
                    //logoff & go back to Created state.
                    SetState(EPVMFNodeIdle);
                    CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFSuccess);
                }
                else
                {
                    SetState(EPVMFNodeError);
                    CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFErrResource);
                }
            }

            break;
        }//end of case OMX_StateInvalid

    }//end of switch(encoder_state)

}






/////////////////////////////////////////////////////////////////////////////
////////////////////// CALLBACK PROCESSING FOR EMPTY BUFFER DONE - input buffer was consumed
/////////////////////////////////////////////////////////////////////////////
OMX_ERRORTYPE PVMFOMXEncNode::EmptyBufferDoneProcessing(OMX_OUT OMX_HANDLETYPE aComponent,
        OMX_OUT OMX_PTR aAppData,
        OMX_OUT OMX_BUFFERHEADERTYPE* aBuffer)
{

    OSCL_UNUSED_ARG(aComponent);
    OSCL_UNUSED_ARG(aAppData);
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFOMXEncNode-%s::EmptyBufferDoneProcessing: In", iNodeTypeId));

    OSCL_ASSERT((void*) aComponent == (void*) iOMXEncoder); // component should match the component
    OSCL_ASSERT(aAppData == (OMX_PTR)(this));       // AppData should represent this node ptr

    // first, get the buffer "context", i.e. pointer to application private data that contains the
    // address of the mempool buffer (so that it can be released)
    InputBufCtrlStruct *pContext = (InputBufCtrlStruct *)(aBuffer->pAppPrivate);



    // if a buffer is not empty, log a msg, but release anyway
    if ((aBuffer->nFilledLen > 0) && (iDoNotSaveInputBuffersFlag == false))
        // if dynamic port reconfig is in progress for input port, don't keep the buffer
    {

        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::EmptyBufferDoneProcessing: Input buffer returned non-empty with %d bytes still in it", iNodeTypeId, aBuffer->nFilledLen));


    }

    iInputBufferToResendToComponent = NULL;


    // input buffer is to be released,
    // refcount needs to be decremented (possibly - the input msg associated with the buffer will be unbound)
    // NOTE: in case of "moveable" input buffers (passed into component without copying), unbinding decrements a refcount which eventually results
    //          in input message being released back to upstream mempool once all its fragments are returned
    //      in case of input buffers passed into component by copying, unbinding has no effect
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFOMXEncNode-%s::EmptyBufferDoneProcessing: Release input buffer (with %d refcount remaining of input message)", iNodeTypeId, (pContext->pMediaData).get_count() - 1));


    (pContext->pMediaData).Unbind();


    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFOMXEncNode-%s::EmptyBufferDoneProcessing: Release input buffer %x back to mempool", iNodeTypeId, pContext));

    iInBufMemoryPool->deallocate((OsclAny *) pContext);


    // the OMX spec says that no error is to be returned
    return OMX_ErrorNone;

}



/////////////////////////////////////////////////////////////////////////////
////////////////////// CALLBACK PROCESSING FOR FILL BUFFER DONE - output buffer is ready
/////////////////////////////////////////////////////////////////////////////
OMX_ERRORTYPE PVMFOMXEncNode::FillBufferDoneProcessing(OMX_OUT OMX_HANDLETYPE aComponent,
        OMX_OUT OMX_PTR aAppData,
        OMX_OUT OMX_BUFFERHEADERTYPE* aBuffer)
{

    OSCL_UNUSED_ARG(aComponent);
    OSCL_UNUSED_ARG(aAppData);
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFOMXEncNode-%s::FillBufferDoneProcessing: In", iNodeTypeId));

    OSCL_ASSERT((void*) aComponent == (void*) iOMXEncoder); // component should match the component
    OSCL_ASSERT(aAppData == (OMX_PTR)(this));       // AppData should represent this node ptr

    // first, get the buffer "context", i.e. pointer to application private data that contains the
    // address of the mempool buffer (so that it can be released)
    OsclAny *pContext = (OsclAny*) aBuffer->pAppPrivate;


    // check for EOS flag
    if ((aBuffer->nFlags & OMX_BUFFERFLAG_EOS))
    {
        // EOS received - enable sending EOS msg
        iIsEOSReceivedFromComponent = true;

        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::FillBufferDoneProcessing: Output buffer has EOS set", iNodeTypeId));

    }

    if (((iOutFormat == PVMF_MIME_H264_VIDEO_MP4) || (iOutFormat == PVMF_MIME_H264_VIDEO_RAW))
            && (iOMXComponentUsesNALStartCodes))
    {
        // find size of first start code, since it can be either 3 or 4 bytes
        uint8* pData = (uint8*)aBuffer->pBuffer + aBuffer->nOffset;
        uint8* pTemp;
        uint32 size = aBuffer->nFilledLen;
        if (AVCAnnexBGetNALUnit(pData, &pTemp, (int32*)&size, true))
        {
            iFirstNALStartCodeSize = (uint32)pTemp - (uint32)pData;
        }
        else
        {
            iFirstNALStartCodeSize = 0;
        }
    }

    /* the case in which a buffer simply containing a start code is sent */
    if (aBuffer->nFilledLen <= iFirstNALStartCodeSize && iOMXComponentUsesNALStartCodes)
    {
        aBuffer->nFilledLen = 0;
    }

    // if a buffer is empty, or if it should not be sent downstream (say, due to state change)
    // release the buffer back to the pool
    if ((aBuffer->nFilledLen == 0) || (iDoNotSendOutputBuffersDownstreamFlag == true))
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::FillBufferDoneProcessing: Release output buffer %x back to mempool - buffer empty or not to be sent downstream", iNodeTypeId, pContext));

        iOutBufMemoryPool->deallocate(pContext);

    }
    else
    {

        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::FillBufferDoneProcessing: Output frame %d received", iNodeTypeId, iFrameCounter));

        iFrameCounter++;
        // get pointer to actual buffer data
        uint8 *pBufdata = ((uint8*) aBuffer->pBuffer);
        // move the data pointer based on offset info
        pBufdata += aBuffer->nOffset;

        uint32 bufLen = (uint32) aBuffer->nFilledLen;

        // in case of mp4 streaming and the very 1st buffer, save vol header separately
        if ((iOutFormat == PVMF_MIME_M4V) && (iFrameCounter == 1))
        {

            // save the first buffer since this is the VOL header
            uint refCounterSize = oscl_mem_aligned_size(sizeof(OsclRefCounterDA));
            OsclMemoryFragment volHeader;

            int vol_len = aBuffer->nFilledLen;
            bool frameInVolHdr = CheckM4vVopStartCode(pBufdata, &vol_len);

            volHeader.ptr = NULL;
            volHeader.len = vol_len;
            uint8* memBuffer = (uint8*)iAlloc.allocate(refCounterSize + volHeader.len);
            oscl_memset(memBuffer, 0, refCounterSize + volHeader.len);
            OsclRefCounter* refCounter = OSCL_PLACEMENT_NEW(memBuffer, OsclRefCounterDA(memBuffer, (OsclDestructDealloc*) & iAlloc));
            memBuffer += refCounterSize;
            volHeader.ptr = (OsclAny*)memBuffer;

            // copy the vol header from OMX buffer
            oscl_memcpy(volHeader.ptr, pBufdata, volHeader.len);

            // save in class variable
            iVolHeader = OsclRefCounterMemFrag(volHeader, refCounter, volHeader.len);

            if (frameInVolHdr == false)
            {
                // release the OMX buffer
                iOutBufMemoryPool->deallocate(pContext);
                return OMX_ErrorNone;
            }
            else  // there is a frame in this buffer, update the pointer and continue to process it.
            {
                pBufdata += vol_len;
                bufLen -= vol_len;
            }
        }

        if (iFrameCounter == 1)
        {
            if ((iOutFormat == PVMF_MIME_ADTS)
                    || (iOutFormat == PVMF_MIME_ADIF)
                    || (iOutFormat == PVMF_MIME_MPEG4_AUDIO)
                    || (iOutFormat == PVMF_MIME_WMA)
                    || (iOutFormat == PVMF_MIME_WMV)
               )
            {

                // save the first buffer since this is the config header and needs to be sent separately
                uint refCounterSize = oscl_mem_aligned_size(sizeof(OsclRefCounterDA));
                OsclMemoryFragment configHeader;
                configHeader.ptr = NULL;
                configHeader.len = aBuffer->nFilledLen;
                uint8* memBuffer = (uint8*)iAlloc.allocate(refCounterSize + configHeader.len);
                oscl_memset(memBuffer, 0, refCounterSize + configHeader.len);
                OsclRefCounter* refCounter = OSCL_PLACEMENT_NEW(memBuffer, OsclRefCounterDA(memBuffer, (OsclDestructDealloc*) & iAlloc));
                memBuffer += refCounterSize;
                configHeader.ptr = (OsclAny*)memBuffer;

                // copy the vol header from OMX buffer
                oscl_memcpy(configHeader.ptr, pBufdata, configHeader.len);

                // save in class variable
                iConfigHeader = OsclRefCounterMemFrag(configHeader, refCounter, configHeader.len);

                // release the OMX buffer
                iOutBufMemoryPool->deallocate(pContext);
                return OMX_ErrorNone;
            }
        }

        // in case of avc mp4, need to save sps/pps sequences
        if ((iOutFormat == PVMF_MIME_H264_VIDEO_MP4) && (!iSpsPpsSequenceOver))
        {

            if (iOMXComponentUsesNALStartCodes)
            {
                // remove the start code from these single NAL frames
                pBufdata += iFirstNALStartCodeSize;
                bufLen -= iFirstNALStartCodeSize;
            }
            // detect nal type
            uint8 *bitstream = pBufdata;
            int nal_type;

            // adjust the pointers in the iParamSet memfragment
            uint8 *destptr = (uint8*) iParamSet.getMemFragPtr();
            uint32 length = iParamSet.getMemFrag().len;
            uint32 capacity = iParamSet.getCapacity();

            destptr += length;


            nal_type = bitstream[0] & 0x1F;

            if (nal_type == 0x07) // SPS type NAL
            {
                int32 nal_size = aBuffer->nFilledLen;
                AVCAnnexBGetNALUnit(aBuffer->pBuffer, &bitstream, (int32*)&nal_size, false);
                // can the SPS fit into the buffer
                if (aBuffer->nFilledLen <= (capacity - length))
                {
                    iSPSs[iNumSPSs].ptr = destptr;
                    iSPSs[iNumSPSs++].len = nal_size;

                    oscl_memcpy(destptr, pBufdata, nal_size); // copy SPS into iParamSet memfragment
                    length += nal_size;
                    iParamSet.getMemFrag().len = length; // update length
                    destptr += nal_size;
                    if (nal_size < aBuffer->nFilledLen) {
                        LOGD("SPS and PPS are located within a single output buffer");
                        uint8* pData = (uint8*)aBuffer->pBuffer + nal_size +iFirstNALStartCodeSize;
                        uint32 size = aBuffer->nFilledLen -(nal_size +iFirstNALStartCodeSize);
                        AVCAnnexBGetNALUnit(pData, &bitstream, (int32*)&size, false);
                        nal_size = size;
                        nal_type = bitstream[0] & 0x1F;
                        if (nal_type == 0x08) // PPS type NAL
                        {
                            if (aBuffer->nFilledLen <= (capacity - length))
                            {
                                iPPSs[iNumPPSs].ptr = destptr;
                                iPPSs[iNumPPSs++].len = nal_size;
                                oscl_memcpy(destptr, bitstream, nal_size); // copy PPS into iParamSet memfragment$
                                length += nal_size;
                                iParamSet.getMemFrag().len = length; // update length
                            }
                        }
                    }
                }

                // release the OMX buffer
                iOutBufMemoryPool->deallocate(pContext);
                return OMX_ErrorNone;
            }
            else if (nal_type == 0x08) // PPS type NAL
            {
                LOGD("SPS and PPS are located in separate output buffers");
                // can the PPS fit into the buffer?
                if (aBuffer->nFilledLen <= (capacity - length))
                {

                    iPPSs[iNumPPSs].ptr = destptr;
                    iPPSs[iNumPPSs++].len = aBuffer->nFilledLen;

                    oscl_memcpy(destptr, pBufdata, aBuffer->nFilledLen); // copy PPS into iParamSet memfragment
                    length += aBuffer->nFilledLen;
                    iParamSet.getMemFrag().len = length; // update length


                }

                // release the OMX buffer
                iOutBufMemoryPool->deallocate(pContext);
                return OMX_ErrorNone;
            }
            else
            {
                if (iOMXComponentUsesNALStartCodes)
                {
                    // bring start code back since it's not a SPS or PPS
                    pBufdata -= iFirstNALStartCodeSize;
                    bufLen += iFirstNALStartCodeSize;
                }

                // this is neither SPS nor PPS
                // stop recording SPS/PPS
                iSpsPpsSequenceOver = true;
                iFirstNAL = true; // set indicator of first NAL
                // send out SPS/PPS recorded so far
                if (((PVMFOMXEncPort*)iOutPort))
                {
                    ((PVMFOMXEncPort*)iOutPort)->SendSPS_PPS(iSPSs, iNumSPSs, iPPSs, iNumPPSs);
                }
            }

        }

        if (iOMXComponentUsesFullAVCFrames && iOutFormat == PVMF_MIME_H264_VIDEO_MP4)
        {
            // do not parse fo PVMF_MIME_H264_VIDEO_RAW, since this data is just written raw, and knowing
            // the NAL boundaries isn't necessary

            if (!ParseFullAVCFramesIntoNALs(aBuffer))
            {
                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                                (0, "PVMFOMXEncNode-%s::FillBufferDoneProcessing: Problem parsing NALs in buffer %x of size %d - releasing the buffer", iNodeTypeId, pBufdata, aBuffer->nFilledLen));

                iOutBufMemoryPool->deallocate(pContext);
            }
        }

        // adjust ptr to data to expose the NAL sync word if necessary
        if ((iOutFormat == PVMF_MIME_H264_VIDEO_RAW) &&
                (iOMXComponentSupportsExternalOutputBufferAlloc) &&
                (!iOMXComponentUsesFullAVCFrames) &&
                (!iOMXComponentUsesNALStartCodes) &&
                ((iFirstNAL == true) || (iEndOfNALFlagPrevious != 0))
           )
        {
            pBufdata -= 4;
            bufLen += 4;
        }

        // otherwise, queue output buffer
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::FillBufferDoneProcessing: Wrapping buffer %x of size %d", iNodeTypeId, pBufdata, aBuffer->nFilledLen));
        // wrap the buffer into the MediaDataImpl wrapper, and queue it for sending downstream
        // wrapping will create a refcounter. When refcounter goes to 0 i.e. when media data
        // is released in downstream components, the custom deallocator will automatically release the buffer back to the
        //  mempool. To do that, the deallocator needs to have info about Context
        // NOTE: we had to wait until now to wrap the buffer data because we only know
        //          now where the actual data is located (based on buffer offset)
        OsclSharedPtr<PVMFMediaDataImpl> MediaDataCurr = WrapOutputBuffer(pBufdata, bufLen, pContext);

        // if you can't get the MediaDataCurr, release the buffer back to the pool
        if (MediaDataCurr.GetRep() == NULL)
        {
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "PVMFOMXEncNode-%s::FillBufferDoneProcessing: Problem wrapping buffer %x of size %d - releasing the buffer", iNodeTypeId, pBufdata, aBuffer->nFilledLen));

            iOutBufMemoryPool->deallocate(pContext);
        }
        else
        {
            OsclSharedPtr<PVMFMediaDataImpl> MediaDataOut;

            //DV - NOTE:
            //In case of AVC, OMX_EndOfFrameFlag is used to mark the end of NAL
            //                End of frame is determined by comparing timestamps
            //              As a consequence, there is a lag of one buffer
            //              i.e. we send/queue the previous buffer and keep the current one so that
            //              When the next buffer arrives, we can compare timestamps etc.

            // In case of MP4, OMX_EndOFFrameFlag is used to mark end of frame and there is no lag

            if ((iOutFormat == PVMF_MIME_H264_VIDEO_MP4) || (iOutFormat == PVMF_MIME_H264_VIDEO_RAW))
            {

                MediaDataOut = iPreviousMediaData; // send out previous media data

                // copy data to be attached with outgoing media data from previous buffer
                iTimeStampOut = iTimeStampPrevious;
                iKeyFrameFlagOut = iKeyFrameFlagPrevious;
                iEndOfNALFlagOut = iEndOfNALFlagPrevious;
                // figure out if we need to set end of frame based on TS
                if (aBuffer->nTimeStamp != iTimeStampPrevious)
                    iEndOfFrameFlagOut = 1;
                else
                    iEndOfFrameFlagOut = 0;
                iBufferLenOut = iBufferLenPrevious;

                // now read the info for the current data
                iPreviousMediaData = MediaDataCurr;
                // record timestamp, flags etc.
                iTimeStampPrevious = aBuffer->nTimeStamp;
                // check for Key Frame
                iKeyFrameFlagPrevious = (aBuffer->nFlags & OMX_BUFFERFLAG_SYNCFRAME);
                // for avc, ENDOFFRAMEFLAG is used to delimit NALs
                iEndOfNALFlagPrevious = (aBuffer->nFlags & OMX_BUFFERFLAG_ENDOFFRAME);
                iBufferLenPrevious = bufLen;


            }
            else // MP4 case
            {

                MediaDataOut = MediaDataCurr;
                // record timestamp, flags etc.
                iTimeStampOut = aBuffer->nTimeStamp;

                // check for Key Frame
                iKeyFrameFlagOut = (aBuffer->nFlags & OMX_BUFFERFLAG_SYNCFRAME);
                iEndOfNALFlagOut = 0; // set this to 0 for mp4
                //check for END OF FRAME FLAG
                iEndOfFrameFlagOut = (aBuffer->nFlags & OMX_BUFFERFLAG_ENDOFFRAME);
                iBufferLenOut = aBuffer->nFilledLen;


            }
            // if there's a problem queuing output buffer, MediaDataCurr will expire at end of scope and
            // release buffer back to the pool, (this should not be the case)

            // queue only if not the first NAL
            if (!iFirstNAL)
            {
                if (QueueOutputBuffer(MediaDataOut, iBufferLenOut))
                {
                    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                                    (0, "PVMFOMXEncNode-%s::FillBufferDoneProcessing: Buffer %x of size %d queued - reschedule the node to send out", iNodeTypeId, pBufdata, aBuffer->nFilledLen));

                    // if queing went OK,
                    // re-schedule the node so that outgoing queue can be emptied (unless the outgoing port is busy)
                    if ((iOutPort) && !(iOutPort->IsConnectedPortBusy()))
                        RunIfNotReady();
                }
                else
                {
                    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                                    (0, "PVMFOMXEncNode-%s::FillBufferDoneProcessing: Problem queing buffer %x of size %d - releasing the buffer", iNodeTypeId, pBufdata, aBuffer->nFilledLen));
                }
            }
            else
            {
                iFirstNAL = false;
            }

            // if EOS and AVC (with a lag), queue also the last buffer
            if ((aBuffer->nFlags & OMX_BUFFERFLAG_EOS) &&
                    ((iOutFormat == PVMF_MIME_H264_VIDEO_MP4) || (iOutFormat == PVMF_MIME_H264_VIDEO_RAW))
               )
            {

                MediaDataOut = iPreviousMediaData; // send out previous media data

                // copy data to be attached with outgoing media data from previous buffer
                iTimeStampOut = iTimeStampPrevious;
                iKeyFrameFlagOut = iKeyFrameFlagPrevious;
                iEndOfNALFlagOut =   1;
                iEndOfFrameFlagOut = 1;

                iBufferLenOut = iBufferLenPrevious;

                if (QueueOutputBuffer(MediaDataOut, iBufferLenOut))
                {
                    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                                    (0, "PVMFOMXEncNode-%s::FillBufferDoneProcessing: Buffer %x of size %d queued - reschedule the node to send out", iNodeTypeId, pBufdata, aBuffer->nFilledLen));

                    // if queing went OK,
                    // re-schedule the node so that outgoing queue can be emptied (unless the outgoing port is busy)
                    if ((iOutPort) && !(iOutPort->IsConnectedPortBusy()))
                        RunIfNotReady();
                }
                else
                {
                    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                                    (0, "PVMFOMXEncNode-%s::FillBufferDoneProcessing: Problem queing buffer %x of size %d - releasing the buffer", iNodeTypeId, pBufdata, aBuffer->nFilledLen));
                }

            }
        }

    }
    // the OMX spec says that no error is to be returned
    return OMX_ErrorNone;

}
////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////// Put output buffer in outgoing queue //////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////
bool PVMFOMXEncNode::QueueOutputBuffer(OsclSharedPtr<PVMFMediaDataImpl> &mediadataimplout, uint32 aDataLen)
{

    bool status = true;
    PVMFSharedMediaDataPtr mediaDataOut;
    int32 leavecode = 0;

    // NOTE: ASSUMPTION IS THAT OUTGOING QUEUE IS BIG ENOUGH TO QUEUE ALL THE OUTPUT BUFFERS
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFOMXEncNode-%s::QueueOutputFrame: In", iNodeTypeId));

    // Check if the port is still connected
    if (iOutPort == NULL)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
                        (0, "PVMFOMXEncNode-%s::QueueOutputFrame() OutgoingQueue Out Port is disconnected"));
        return false;
    }

    // First check if we can put outgoing msg. into the queue
    if (iOutPort->IsOutgoingQueueBusy())
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
                        (0, "PVMFOMXEncNode-%s::QueueOutputFrame() OutgoingQueue is busy", iNodeTypeId));
        return false;
    }

    OSCL_TRY(leavecode,
             mediaDataOut = PVMFMediaData::createMediaData(mediadataimplout, iMediaDataMemPool););
    if (leavecode == 0)
    {

        uint32 marker_bits = mediaDataOut->getMarkerInfo();

        if (iEndOfFrameFlagOut != 0)
        {
            marker_bits |= PVMF_MEDIA_DATA_MARKER_INFO_M_BIT;
        }

        if (iKeyFrameFlagOut != 0)
        {
            marker_bits |= PVMF_MEDIA_DATA_MARKER_INFO_RANDOM_ACCESS_POINT_BIT;
        }

        if (iEndOfNALFlagOut != 0)
        {
            marker_bits |= PVMF_MEDIA_DATA_MARKER_INFO_END_OF_NAL_BIT;
        }

        // attach marker bit
        mediaDataOut->setMarkerInfo(marker_bits);


        // Update the filled length of the fragment
        mediaDataOut->setMediaFragFilledLen(0, aDataLen);

        // Set timestamp
        // first convert OMX_TICKS into output timescale
        uint32 output_timestamp = ConvertOMXTicksIntoTimestamp(iTimeStampOut);

        mediaDataOut->setTimestamp(output_timestamp);

        // Set Streamid
        mediaDataOut->setStreamID(iStreamID);

        // Set sequence number
        mediaDataOut->setSeqNum(iSeqNum++);

        PVLOGGER_LOGMSG(PVLOGMSG_INST_REL, iDataPathLogger, PVLOGMSG_INFO, (0, ":PVMFOMXEncNode-%s::QueueOutputFrame(): - SeqNum=%d, Ticks=%l TS=%d", iNodeTypeId, iSeqNum, iTimeStampOut, output_timestamp));


        // Check if Fsi needs to be sent (VOL header)
        if (sendYuvFsi)
        {
            if (iOutFormat == PVMF_MIME_M4V)
            {
                mediaDataOut->setFormatSpecificInfo(iVolHeader);

            }
            else if ((iOutFormat == PVMF_MIME_ADTS)
                     || (iOutFormat == PVMF_MIME_ADIF)
                     || (iOutFormat == PVMF_MIME_MPEG4_AUDIO)
                     || (iOutFormat == PVMF_MIME_WMA)
                     || (iOutFormat == PVMF_MIME_WMV))
            {

                mediaDataOut->setFormatSpecificInfo(iConfigHeader);

            }

            sendYuvFsi = false;
        }

        // Send frame to downstream node
        PVMFSharedMediaMsgPtr mediaMsgOut;
        convertToPVMFMediaMsg(mediaMsgOut, mediaDataOut);

        if (iOutPort && (iOutPort->QueueOutgoingMsg(mediaMsgOut) == PVMFSuccess))
        {
            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO,
                            (0, "PVMFOMXEncNode-%s::QueueOutputFrame(): Queued frame OK ", iNodeTypeId));

        }
        else
        {
            // we should not get here because we always check for whether queue is busy or not
            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                            (0, "PVMFOMXEncNode-%s::QueueOutputFrame(): Send frame failed", iNodeTypeId));
            return false;
        }




    }//end of if (leavecode==0)
    else
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
                        (0, "PVMFOMXEncNode-%s::QueueOutputFrame() call PVMFMediaData::createMediaData is failed", iNodeTypeId));
        return false;
    }

    return status;

}

//////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////// Attach a MediaDataImpl wrapper (refcount, deallocator etc.)
/////////////////////////////// to the output buffer /////////////////////////////////////////
OsclSharedPtr<PVMFMediaDataImpl> PVMFOMXEncNode::WrapOutputBuffer(uint8 *pData, uint32 aDataLen, OsclAny *pContext)
{
    // wrap output buffer into a mediadataimpl
    uint32 aligned_cleanup_size = oscl_mem_aligned_size(sizeof(PVOMXEncBufferSharedPtrWrapperCombinedCleanupDA));
    uint32 aligned_refcnt_size = oscl_mem_aligned_size(sizeof(OsclRefCounterDA));
    uint8 *my_ptr = (uint8*) oscl_malloc(aligned_cleanup_size + aligned_refcnt_size);

    if (my_ptr == NULL)
    {
        OsclSharedPtr<PVMFMediaDataImpl> null_buff(NULL, NULL);
        return null_buff;
    }

    // create a deallocator and pass the buffer_allocator to it as well as pointer to data that needs to be returned to the mempool
    PVOMXEncBufferSharedPtrWrapperCombinedCleanupDA *cleanup_ptr =
        OSCL_PLACEMENT_NEW(my_ptr + aligned_refcnt_size, PVOMXEncBufferSharedPtrWrapperCombinedCleanupDA(iOutBufMemoryPool, pContext));

    // create the ref counter after the cleanup object (refcount is set to 1 at creation)
    OsclRefCounterDA *my_refcnt;
    PVMFMediaDataImpl* media_data_ptr;

    if (iOMXComponentUsesFullAVCFrames && iNumNALs > 0)
    {
        uint32 ii;
        media_data_ptr = OSCL_NEW(PVMFMediaFragGroup<OsclMemAllocator>, (iNumNALs));
        my_refcnt = OSCL_PLACEMENT_NEW(my_ptr, OsclRefCounterDA(media_data_ptr, cleanup_ptr));

        // loop through and assign a create a media fragment for each NAL
        for (ii = 0; ii < iNumNALs; ii++)
        {
            OsclMemoryFragment memFrag;

            if (iOMXComponentUsesNALStartCodes)
            {
                // need to get NAL ptr from stored array, since start codes can be 3 or 4 bytes,
                // and the only way to know is by parsing the buffer (which we should have done by now and stored in the array)
                memFrag.ptr = iNALPtrArray[ii];
            }
            else
            {
                memFrag.ptr = pData;
                pData += iNALSizeArray[ii];
            }

            memFrag.len = iNALSizeArray[ii];

            OsclRefCounterMemFrag refCountMemFragOut(memFrag, my_refcnt, memFrag.len);
            media_data_ptr->appendMediaFragment(refCountMemFragOut);
        }

        oscl_memset((void *) iNALSizeArray, 0, sizeof(uint32) * iNumNALs);
        iNumNALs = 0;
    }
    else
    {
        media_data_ptr = OSCL_NEW(PVMFMediaFragGroup<OsclMemAllocator>, (1));
        my_refcnt = OSCL_PLACEMENT_NEW(my_ptr, OsclRefCounterDA(media_data_ptr, cleanup_ptr));

        OsclMemoryFragment memFrag;

        if (iOMXComponentUsesNALStartCodes && (iOutFormat != PVMF_MIME_H264_VIDEO_RAW))
        {
            // skip start code
            pData += iFirstNALStartCodeSize;
            aDataLen -= iFirstNALStartCodeSize;
        }

        memFrag.ptr = pData;
        memFrag.len = aDataLen;

        OsclRefCounterMemFrag refCountMemFragOut(memFrag, my_refcnt, memFrag.len);
        media_data_ptr->appendMediaFragment(refCountMemFragOut);
    }

    OsclSharedPtr<PVMFMediaDataImpl> MediaDataImplOut(media_data_ptr, my_refcnt);

    return MediaDataImplOut;
}
//////////////////////////////////////////////////////////////////////////////
bool PVMFOMXEncNode::SendBeginOfMediaStreamCommand()
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFOMXEncNode-%s::SendBeginOfMediaStreamCommand() In", iNodeTypeId));

    PVMFSharedMediaCmdPtr sharedMediaCmdPtr = PVMFMediaCmd::createMediaCmd();
    // Set the formatID, timestamp, sequenceNumber and streamID for the media message
    sharedMediaCmdPtr->setFormatID(PVMF_MEDIA_CMD_BOS_FORMAT_ID);
    sharedMediaCmdPtr->setTimestamp(iBOSTimestamp);
    //reset the sequence number
    uint32 seqNum = 0;
    sharedMediaCmdPtr->setSeqNum(seqNum);
    sharedMediaCmdPtr->setStreamID(iStreamID);

    PVMFSharedMediaMsgPtr mediaMsgOut;
    convertToPVMFMediaCmdMsg(mediaMsgOut, sharedMediaCmdPtr);
    if (iOutPort->QueueOutgoingMsg(mediaMsgOut) != PVMFSuccess)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::SendBeginOfMediaStreamCommand() Outgoing queue busy", iNodeTypeId));
        return false;
    }

    iSendBOS = false;

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFOMXEncNode-%s::SendBeginOfMediaStreamCommand() BOS Sent StreamID %d", iNodeTypeId, iStreamID));
    return true;
}
////////////////////////////////////
bool PVMFOMXEncNode::SendEndOfTrackCommand(void)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFOMXEncNode-%s::SendEndOfTrackCommand() In", iNodeTypeId));

    PVMFSharedMediaCmdPtr sharedMediaCmdPtr = PVMFMediaCmd::createMediaCmd();

    sharedMediaCmdPtr->setFormatID(PVMF_MEDIA_CMD_EOS_FORMAT_ID);

    // Set the timestamp
    sharedMediaCmdPtr->setTimestamp(iEndOfDataTimestamp);

    // Set Streamid
    sharedMediaCmdPtr->setStreamID(iStreamID);

    // Set the sequence number
    sharedMediaCmdPtr->setSeqNum(iSeqNum++);

    PVMFSharedMediaMsgPtr mediaMsgOut;
    convertToPVMFMediaCmdMsg(mediaMsgOut, sharedMediaCmdPtr);
    if (iOutPort->QueueOutgoingMsg(mediaMsgOut) != PVMFSuccess)
    {
        // this should not happen because we check for queue busy before calling this function
        return false;
    }

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFOMXEncNode-%s::SendEndOfTrackCommand() Out", iNodeTypeId));
    return true;
}

/////////////////////////////////////////////////////////////////////////////
//The various command handlers call this routine when a command is complete.
/////////////////////////////////////////////////////////////////////////////
void PVMFOMXEncNode::CommandComplete(PVMFOMXEncNodeCmdQ& aCmdQ, PVMFOMXEncNodeCommand& aCmd, PVMFStatus aStatus, OsclAny* aEventData)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::CommandComplete Id %d Cmd %d Status %d Context %d Data %d", iNodeTypeId
                    , aCmd.iId, aCmd.iCmd, aStatus, aCmd.iContext, aEventData));

    //create response
    PVMFCmdResp resp(aCmd.iId, aCmd.iContext, aStatus, aEventData);
    PVMFSessionId session = aCmd.iSession;

    //Erase the command from the queue.
    aCmdQ.Erase(&aCmd);

    //Report completion to the session observer.
    ReportCmdCompleteEvent(session, resp);
}

/////////////////////////////////////////////////////////////////////////////
void PVMFOMXEncNode::DoInit(PVMFOMXEncNodeCommand& aCmd)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::DoInit() In", iNodeTypeId));
    switch (iInterfaceState)
    {
        case EPVMFNodeIdle:
        {
            SetState(EPVMFNodeInitialized);
            CommandComplete(iInputCommands, aCmd, PVMFSuccess);
            break;
        }

        default:
            CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
            break;
    }
}

/////////////////////////////////////////////////////////////////////////////
void PVMFOMXEncNode::DoPrepare(PVMFOMXEncNodeCommand& aCmd)
{
    OMX_ERRORTYPE err = OMX_ErrorNone;
    OMX_STRING Role = NULL;

    switch (iInterfaceState)
    {
        case EPVMFNodeInitialized:
        {
            if (NULL == iInPort)
            {
                CommandComplete(iInputCommands, aCmd, PVMFFailure);
            }


            // by now the encode parameters have been set

            if (iOutFormat == PVMF_MIME_H2631998 ||
                    iOutFormat == PVMF_MIME_H2632000)
            {
                Role = (OMX_STRING)"video_encoder.h263";
                iNodeTypeId = LOG_ID_VIDEO_H263;
            }
            else if (iOutFormat == PVMF_MIME_M4V)
            {
                Role = (OMX_STRING)"video_encoder.mpeg4";
                iNodeTypeId = LOG_ID_VIDEO_M4V;
            }
            else if (iOutFormat == PVMF_MIME_H264_VIDEO_RAW ||
                     iOutFormat == PVMF_MIME_H264_VIDEO_MP4)
            {
                Role = (OMX_STRING)"video_encoder.avc";
                iNodeTypeId = LOG_ID_VIDEO_AVC;
                iFirstNAL = true; // set this flag to prevent node from queueing the first
                // buffer
            }
            else if ((iOutFormat == PVMF_MIME_AMR_IETF) ||
                     (iOutFormat == PVMF_MIME_AMR_IF2))
            {
                Role = (OMX_STRING)"audio_encoder.amrnb";
                iNodeTypeId = LOG_ID_AUDIO_AMRNB;
            }
            else if (iOutFormat == PVMF_MIME_AMRWB_IETF)
            {
                Role = (OMX_STRING)"audio_encoder.amrwb";
                iNodeTypeId = LOG_ID_AUDIO_AMRWB;
            }
            else if (iOutFormat == PVMF_MIME_ADTS ||
                     iOutFormat == PVMF_MIME_ADIF ||
                     iOutFormat == PVMF_MIME_MPEG4_AUDIO)
            {
                Role = (OMX_STRING)"audio_encoder.aac";
                iNodeTypeId = LOG_ID_AUDIO_AAC;
            }
            else
            {
                // Illegal codec specified.
                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::DoPrepare() Input port format other then codec type", iNodeTypeId));
                CommandComplete(iInputCommands, aCmd, PVMFErrArgument);
                return;
            }


            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_DEBUG,
                            (0, "PVMFOMXEncNode-%s::Initializing OMX component and encoder for role %s", iNodeTypeId, Role));

            /* Set callback structure */
            iCallbacks.EventHandler    = CallbackEventHandlerEnc; //event_handler;
            iCallbacks.EmptyBufferDone = CallbackEmptyBufferDoneEnc; //empty_buffer_done;
            iCallbacks.FillBufferDone  = CallbackFillBufferDoneEnc; //fill_buffer_done;


            // determine components which can fit the role
            // then, create the component. If multiple components fit the role,
            // the first one registered will be selected. If that one fails to
            // be created, the second one in the list is selected etc.
            OMX_U32 num_comps = 0;
            OMX_STRING *CompOfRole;
            OMX_S8 CompName[PV_OMX_MAX_COMPONENT_NAME_LENGTH];
            // call once to find out the number of components that can fit the role
            OMX_MasterGetComponentsOfRole(Role, &num_comps, NULL);
            uint32 ii;

            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
                            (0, "PVMFOMXEncNode-%s::DoPrepare(): There are %d components of role %s ", iNodeTypeId, num_comps, Role));

            if (num_comps > 0)
            {
                CompOfRole = (OMX_STRING *)oscl_malloc(num_comps * sizeof(OMX_STRING));

                for (ii = 0; ii < num_comps; ii++)
                    CompOfRole[ii] = (OMX_STRING) oscl_malloc(PV_OMX_MAX_COMPONENT_NAME_LENGTH * sizeof(OMX_U8));

                // call 2nd time to get the component names
                OMX_MasterGetComponentsOfRole(Role, &num_comps, (OMX_U8 **)CompOfRole);

                for (ii = 0; ii < num_comps; ii++)
                {
                    // try to create component
                    err = OMX_MasterGetHandle(&iOMXEncoder, (OMX_STRING) CompOfRole[ii], (OMX_PTR) this, (OMX_CALLBACKTYPE *) & iCallbacks);

                    if ((err == OMX_ErrorNone) && (iOMXEncoder != NULL))
                    {
                        oscl_strncpy((OMX_STRING)CompName, (OMX_STRING) CompOfRole[ii], PV_OMX_MAX_COMPONENT_NAME_LENGTH);

                        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
                                        (0, "PVMFOMXEncNode-%s::DoPrepare(): Got Component %s handle ", iNodeTypeId, CompOfRole[ii]));
                        LOGE("PVMFOMXEncNode-%s::DoPrepare(): Got Component %s handle ", iNodeTypeId, CompOfRole[ii]);

                        if ((CheckComponentForMultRoles((OMX_STRING)CompName, (OMX_STRING)CompOfRole[ii])) &&
                            (CheckComponentCapabilities(&iOutFormat)))
                        {
                            // Found a component and it passed all tests.   Break out of the loop
                            break;
                        }
                    }

                    // Component failed negotiations
                    if (iOMXEncoder != NULL)
                    {
                        OMX_MasterFreeHandle(iOMXEncoder);
                        iOMXEncoder = NULL;
                    }
                }

                // whether successful or not, need to free CompOfRoles
                for (ii = 0; ii < num_comps; ii++)
                {
                    oscl_free(CompOfRole[ii]);
                    CompOfRole[ii] = NULL;
                }

                oscl_free(CompOfRole);
                // check if there was a problem
                if ((err != OMX_ErrorNone) || (iOMXEncoder == NULL))
                {
                    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                                    (0, "PVMFOMXEncNode-%s::Can't get handle for encoder!", iNodeTypeId));
                    iOMXEncoder = NULL;
                    CommandComplete(iInputCommands, aCmd, PVMFErrResource);
                    return;
                }
            }
            else
            {
                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                                (0, "PVMFOMXEncNode-%s::No component can handle role %s !", iNodeTypeId, Role));
                iOMXEncoder = NULL;
                CommandComplete(iInputCommands, aCmd, PVMFErrResource);
                return;
            }

            if (!iOMXEncoder)
            {
                CommandComplete(iInputCommands, aCmd, PVMFErrNoResources);
                return;
            }

            // create active objects to handle callbacks in case of multithreaded implementation

            // NOTE: CREATE THE THREADSAFE CALLBACK AOs REGARDLESS OF WHETHER MULTITHREADED COMPONENT OR NOT
            //      If it is not multithreaded, we won't use them
            //      The Flag iIsComponentMultiThreaded decides which mechanism is used for callbacks.
            //      This flag is set by looking at component capabilities (or to true by default)

            if (iThreadSafeHandlerEventHandler)
            {
                OSCL_DELETE(iThreadSafeHandlerEventHandler);
                iThreadSafeHandlerEventHandler = NULL;
            }
            // substitute default parameters: observer(this node),queuedepth(3),nameAO for logging
            // Get the priority of the encoder node, and set the threadsafe callback AO priority to 1 higher

            iThreadSafeHandlerEventHandler = OSCL_NEW(EventHandlerThreadSafeCallbackAOEnc, (this, 10, "EventHandlerAO", Priority() + 2));

            if (iThreadSafeHandlerEmptyBufferDone)
            {
                OSCL_DELETE(iThreadSafeHandlerEmptyBufferDone);
                iThreadSafeHandlerEmptyBufferDone = NULL;
            }
            // use queue depth of iNumInputBuffers to prevent deadlock
            iThreadSafeHandlerEmptyBufferDone = OSCL_NEW(EmptyBufferDoneThreadSafeCallbackAOEnc, (this, iNumInputBuffers, "EmptyBufferDoneAO", Priority() + 1));

            if (iThreadSafeHandlerFillBufferDone)
            {
                OSCL_DELETE(iThreadSafeHandlerFillBufferDone);
                iThreadSafeHandlerFillBufferDone = NULL;
            }
            // use queue depth of iNumOutputBuffers to prevent deadlock
            iThreadSafeHandlerFillBufferDone = OSCL_NEW(FillBufferDoneThreadSafeCallbackAOEnc, (this, iNumOutputBuffers, "FillBufferDoneAO", Priority() + 1));

            if ((iThreadSafeHandlerEventHandler == NULL) ||
                    (iThreadSafeHandlerEmptyBufferDone == NULL) ||
                    (iThreadSafeHandlerFillBufferDone == NULL)
               )
            {
                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                                (0, "PVMFOMXEncNode-%s::Can't get threadsafe callbacks for encoder!", iNodeTypeId));
                iOMXEncoder = NULL;
            }


            // Init Encoder
            iCurrentEncoderState = OMX_StateLoaded;

            /* Change state to OMX_StateIdle from OMX_StateLoaded. */
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
                            (0, "PVMFOMXEncNode-%s::DoPrepare(): Changing Component state Loaded -> Idle ", iNodeTypeId));

            err = OMX_SendCommand(iOMXEncoder, OMX_CommandStateSet, OMX_StateIdle, NULL);
            if (err != OMX_ErrorNone)
            {
                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                                (0, "PVMFOMXEncNode-%s::DoPrepare() Can't send StateSet command!", iNodeTypeId));

                CommandComplete(iInputCommands, aCmd, PVMFErrNoResources);
                return;
            }


            /* Allocate input buffers */
            if (!CreateInputMemPool(iNumInputBuffers))
            {
                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                                (0, "PVMFOMXEncNode-%s::DoPrepare() Can't allocate mempool for input buffers!", iNodeTypeId));

                CommandComplete(iInputCommands, aCmd, PVMFErrNoResources);
                return;
            }

            if (in_ctrl_struct_ptr)
            {
                oscl_free(in_ctrl_struct_ptr);
                in_ctrl_struct_ptr = NULL;
            }
            if (in_buff_hdr_ptr)
            {
                oscl_free(in_buff_hdr_ptr);
                in_buff_hdr_ptr = NULL;
            }

            in_ctrl_struct_ptr = (OsclAny **) oscl_malloc(iNumInputBuffers * sizeof(OsclAny *));

            if (in_ctrl_struct_ptr == NULL)
            {
                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                                (0, "PVMFOMXEncNode-%s::DoPreapare in_ctrl_struct_ptr == NULL", iNodeTypeId));

                CommandComplete(iInputCommands, aCmd, PVMFErrNoResources);
                return ;
            }

            in_buff_hdr_ptr = (OsclAny **) oscl_malloc(iNumInputBuffers * sizeof(OsclAny *));

            if (in_buff_hdr_ptr == NULL)
            {
                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                                (0, "PVMFOMXEncNode-%s::DoPreapare in_buff_hdr_ptr == NULL", iNodeTypeId));

                CommandComplete(iInputCommands, aCmd, PVMFErrNoResources);
                return ;
            }


            if (!ProvideBuffersToComponent(iInBufMemoryPool, // allocator
                                           iInputAllocSize,  // size to allocate from pool (hdr only or hdr+ buffer)
                                           iNumInputBuffers, // number of buffers
                                           iOMXComponentInputBufferSize, // actual buffer size
                                           iInputPortIndex, // port idx
                                           iOMXComponentSupportsExternalInputBufferAlloc, // can component use OMX_UseBuffer
                                           true // this is input
                                          ))
            {
                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                                (0, "PVMFOMXEncNode-%s::DoPrepare() Component can't use input buffers!", iNodeTypeId));

                CommandComplete(iInputCommands, aCmd, PVMFErrNoResources);
                return;
            }


            /* Allocate output buffers */
            if (!CreateOutMemPool(iNumOutputBuffers))
            {
                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                                (0, "PVMFOMXEncNode-%s::DoPrepare() Can't allocate mempool for output buffers!", iNodeTypeId));

                CommandComplete(iInputCommands, aCmd, PVMFErrNoResources);
                return;
            }

            if (out_ctrl_struct_ptr)
            {
                oscl_free(out_ctrl_struct_ptr);
                out_ctrl_struct_ptr = NULL;
            }
            if (out_buff_hdr_ptr)
            {
                oscl_free(out_buff_hdr_ptr);
                out_buff_hdr_ptr = NULL;
            }

            out_ctrl_struct_ptr = (OsclAny **) oscl_malloc(iNumOutputBuffers * sizeof(OsclAny *));

            if (out_ctrl_struct_ptr == NULL)
            {
                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                                (0, "PVMFOMXEncNode-%s::DoPreapare out_ctrl_struct_ptr == NULL", iNodeTypeId));

                CommandComplete(iInputCommands, aCmd, PVMFErrNoResources);
                return ;
            }

            out_buff_hdr_ptr = (OsclAny **) oscl_malloc(iNumOutputBuffers * sizeof(OsclAny *));

            if (out_buff_hdr_ptr == NULL)
            {
                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                                (0, "PVMFOMXEncNode-%s::DoPreapare out_buff_hdr_ptr == NULL", iNodeTypeId));

                CommandComplete(iInputCommands, aCmd, PVMFErrNoResources);
                return ;
            }


            if (!ProvideBuffersToComponent(iOutBufMemoryPool, // allocator
                                           iOutputAllocSize,     // size to allocate from pool (hdr only or hdr+ buffer)
                                           iNumOutputBuffers, // number of buffers
                                           iOMXComponentOutputBufferSize, // actual buffer size
                                           iOutputPortIndex, // port idx
                                           iOMXComponentSupportsExternalOutputBufferAlloc, // can component use OMX_UseBuffer
                                           false // this is not input
                                          ))
            {
                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                                (0, "PVMFOMXEncNode-%s::DoPrepare() Component can't use output buffers!", iNodeTypeId));

                CommandComplete(iInputCommands, aCmd, PVMFErrNoResources);
                return;
            }


            //this command is asynchronous.  move the command from
            //the input command queue to the current command, where
            //it will remain until it completes. We have to wait for
            // OMX component state transition to complete

            int32 err;
            OSCL_TRY(err, iCurrentCommand.StoreL(aCmd););
            if (err != OsclErrNone)
            {
                CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
                return;
            }
            iInputCommands.Erase(&aCmd);

        }
        break;
        case EPVMFNodePrepared:
            CommandComplete(iInputCommands, aCmd, PVMFSuccess);
            break;
        default:
            CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
            break;
    }

}

/////////////////////////////////////////////////////////////////////////////
void PVMFOMXEncNode::DoStart(PVMFOMXEncNodeCommand& aCmd)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::DoStart() In", iNodeTypeId));

    iDiagnosticsLogged = false;

    PVMFStatus status = PVMFSuccess;

    OMX_ERRORTYPE  err;
    OMX_STATETYPE sState;

#ifdef _TEST_AE_ERROR_HANDLING
    if (FAIL_NODE_CMD_START == iErrorNodeCmd)
    {
        iInterfaceState = EPVMFNodeError;
    }
#endif



    switch (iInterfaceState)
    {
        case EPVMFNodePrepared:
        case EPVMFNodePaused:
        {
            //Get state of OpenMAX encoder
            err = OMX_GetState(iOMXEncoder, &sState);
            if (err != OMX_ErrorNone)
            {
                //Error condition report
                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                                (0, "PVMFOMXEncNode-%s::DoStart(): Can't get State of encoder!", iNodeTypeId));

                sState = OMX_StateInvalid;
            }
#ifdef _TEST_AE_ERROR_HANDLING
            if (iErrorHandlingInit)
            {
                //some random state ,we want Init to fail

                sState = OMX_StateInvalid;
            }
#endif
            if ((sState == OMX_StateIdle) || (sState == OMX_StatePause))
            {
                /* Change state to OMX_StateExecuting form OMX_StateIdle. */
                // init the flag
                iDoNotSendOutputBuffersDownstreamFlag = false; // or if output was not being sent downstream due to state changes
                // re-anable sending output

                iDoNotSaveInputBuffersFlag = false;


                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                                (0, "PVMFOMXEncNode-%s::DoStart() Changing Component state Idle->Executing", iNodeTypeId));

                err = OMX_SendCommand(iOMXEncoder, OMX_CommandStateSet, OMX_StateExecuting, NULL);
                if (err != OMX_ErrorNone)
                {
                    //Error condition report
                    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                                    (0, "PVMFOMXEncNode-%s::DoStart(): Can't send StateSet command to encoder!", iNodeTypeId));

                    status = PVMFErrInvalidState;
                }

            }
            else
            {
                //Error condition report
                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                                (0, "PVMFOMXEncNode-%s::DoStart(): Encoder is not in the Idle or Pause state!", iNodeTypeId));

                status = PVMFErrInvalidState;
            }


        }
        break;

        default:
            status = PVMFErrInvalidState;
            break;
    }

    if (status == PVMFErrInvalidState)
    {
        CommandComplete(iInputCommands, aCmd, status);
    }
    else
    {
        //this command is asynchronous.  move the command from
        //the input command queue to the current command, where
        //it will remain until it completes.
        int32 err;
        OSCL_TRY(err, iCurrentCommand.StoreL(aCmd););
        if (err != OsclErrNone)
        {
            CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
        }
        iInputCommands.Erase(&aCmd);
    }
}

/////////////////////////////////////////////////////////////////////////////
void PVMFOMXEncNode::DoStop(PVMFOMXEncNodeCommand& aCmd)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::DoStop() In", iNodeTypeId));

    LogDiagnostics();

    OMX_ERRORTYPE  err;
    OMX_STATETYPE sState;
#ifdef _TEST_AE_ERROR_HANDLING
    if (FAIL_NODE_CMD_STOP == iErrorNodeCmd)
    {
        iInterfaceState = EPVMFNodeError;
    }
#endif
    switch (iInterfaceState)
    {
        case EPVMFNodeStarted:
        case EPVMFNodePaused:
        case EPVMFNodePrepared:
            // Stop data source
            // This will also prevent execution of HandleProcessingState

            iDataIn.Unbind();
            iPreviousMediaData.Unbind();
            if ((iOutFormat == PVMF_MIME_H264_VIDEO_MP4) || (iOutFormat == PVMF_MIME_H264_VIDEO_RAW))
            {
                // prepare for next start (if it comes)
                iFirstNAL = true;
            }
            // Clear queued messages in ports
            if (iInPort)
            {
                iInPort->ClearMsgQueues();
            }

            if (iOutPort)
            {
                iOutPort->ClearMsgQueues();
            }

            // Clear the data flags

            iEndOfDataReached = false;
            iIsEOSSentToComponent = false;
            iIsEOSReceivedFromComponent = false;


            iDoNotSendOutputBuffersDownstreamFlag = true; // stop sending output buffers downstream
            iDoNotSaveInputBuffersFlag = true;


            //Get state of OpenMAX encoder
            err = OMX_GetState(iOMXEncoder, &sState);
            if (err != OMX_ErrorNone)
            {
                //Error condition report
                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                                (0, "PVMFOMXEncNode-%s::DoStop(): Can't get State of encoder!", iNodeTypeId));

                sState = OMX_StateInvalid;
            }

            if ((sState == OMX_StateExecuting) || (sState == OMX_StatePause))
            {
                /* Change state to OMX_StateIdle from OMX_StateExecuting or OMX_StatePause. */

                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                                (0, "PVMFOMXEncNode-%s::DoStop() Changing Component State Executing->Idle or Pause->Idle", iNodeTypeId));

                err = OMX_SendCommand(iOMXEncoder, OMX_CommandStateSet, OMX_StateIdle, NULL);
                if (err != OMX_ErrorNone)
                {
                    //Error condition report
                    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                                    (0, "PVMFOMXEncNode-%s::DoStop(): Can't send StateSet command to encoder!", iNodeTypeId));

                    CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
                    break;
                }

                // prevent the node from sending more buffers etc.
                // if port reconfiguration is in process, let the state remain one of the port config states
                //  if there is a start command, we can do it seemlessly (by continuing the port reconfig)
                if (iProcessingState == EPVMFOMXEncNodeProcessingState_ReadyToEncode)
                    iProcessingState = EPVMFOMXEncNodeProcessingState_Stopping;

            }
            else
            {
                //Error condition report
                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                                (0, "PVMFOMXEncNode-%s::DoStop(): Encoder is not in the Executing or Pause state!", iNodeTypeId));

                CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
                break;
            }

            //this command is asynchronous.  move the command from
            //the input command queue to the current command, where
            //it will remain until it completes.
            int32 err;
            OSCL_TRY(err, iCurrentCommand.StoreL(aCmd););
            if (err != OsclErrNone)
            {
                CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
                return;
            }
            iInputCommands.Erase(&aCmd);

            break;

        default:
            CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
            break;
    }
}

/////////////////////////////////////////////////////////////////////////////
void PVMFOMXEncNode::DoFlush(PVMFOMXEncNodeCommand& aCmd)
{
#ifdef _TEST_AE_ERROR_HANDLING
    if (FAIL_NODE_CMD_FLUSH == iErrorNodeCmd)
    {
        iInterfaceState = EPVMFNodeError;
    }
#endif
    switch (iInterfaceState)
    {
        case EPVMFNodeStarted:
        case EPVMFNodePaused:
            //the flush is asynchronous.  move the command from
            //the input command queue to the current command, where
            //it will remain until the flush completes.
            int32 err;
            OSCL_TRY(err, iCurrentCommand.StoreL(aCmd););
            if (err != OsclErrNone)
            {
                CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
                return;
            }
            iInputCommands.Erase(&aCmd);

            //Notify all ports to suspend their input
            if (iInPort)
            {
                iInPort->SuspendInput();
            }
            RunIfNotReady();
            if (iOutPort)
            {
                iOutPort->SuspendInput();
            }
            // Stop data source

            // DV: Sending "OMX_CommandFlush" to the encoder;
            // Not used because PV Flush command expects data to be processed before getting out
            iDoNotSendOutputBuffersDownstreamFlag = true; // collect output buffers

            break;

        default:
            CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
            break;
    }
}

/////////////////////////////////////////////////////////////////////////////
void PVMFOMXEncNode::DoPause(PVMFOMXEncNodeCommand& aCmd)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::DoPause() In", iNodeTypeId));

    OMX_ERRORTYPE  err;
    OMX_STATETYPE sState;
#ifdef _TEST_AE_ERROR_HANDLING
    if (FAIL_NODE_CMD_PAUSE == iErrorNodeCmd)
    {
        iInterfaceState = EPVMFNodeError;
    }
#endif

    switch (iInterfaceState)
    {
        case EPVMFNodeStarted:


            //Get state of OpenMAX encoder
            err = OMX_GetState(iOMXEncoder, &sState);
            if (err != OMX_ErrorNone)
            {
                //Error condition report
                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                                (0, "PVMFOMXEncNode-%s::DoPause(): Can't get State of encoder!", iNodeTypeId));

                sState = OMX_StateInvalid;
            }

            if (sState == OMX_StateExecuting)
            {
                /* Change state to OMX_StatePause from OMX_StateExecuting. */
                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                                (0, "PVMFOMXEncNode-%s::DoPause() Changing Component State Executing->Idle", iNodeTypeId));

                err = OMX_SendCommand(iOMXEncoder, OMX_CommandStateSet, OMX_StatePause, NULL);
                if (err != OMX_ErrorNone)
                {
                    //Error condition report
                    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                                    (0, "PVMFOMXEncNode-%s::DoPause(): Can't send StateSet command to encoder!", iNodeTypeId));

                    CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
                    break;
                }

            }
            else
            {
                //Error condition report
                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                                (0, "PVMFOMXEncNode-%s::DoPause(): Encoder is not in the Executing state!", iNodeTypeId));
                CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
                break;
            }

            //this command is asynchronous.  move the command from
            //the input command queue to the current command, where
            //it will remain until it completes.
            int32 err;
            OSCL_TRY(err, iCurrentCommand.StoreL(aCmd););
            if (err != OsclErrNone)
            {
                CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
                return;
            }
            iInputCommands.Erase(&aCmd);

            break;
        default:
            CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
            break;
    }
}

/////////////////////////////////////////////////////////////////////////////
void PVMFOMXEncNode::DoReset(PVMFOMXEncNodeCommand& aCmd)
{

    OMX_ERRORTYPE  err;
    OMX_STATETYPE sState;

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFOMXEncNode-%s::DoReset() In", iNodeTypeId));

    LogDiagnostics();

    switch (iInterfaceState)
    {
        case EPVMFNodeIdle:
        case EPVMFNodeInitialized:
        case EPVMFNodePrepared:
        case EPVMFNodeStarted:
        case EPVMFNodePaused:
        case EPVMFNodeError:
        {
            //Check if encoder is initilized
            if (iOMXEncoder != NULL)
            {
                //Get state of OpenMAX encoder
                err = OMX_GetState(iOMXEncoder, &sState);
                if (err != OMX_ErrorNone)
                {
                    sState = OMX_StateInvalid;
                }

                if (sState == OMX_StateLoaded)
                {
                    // this is a value obtained by synchronous call to component. Either the component was
                    // already in this state without node issuing any commands,
                    // or perhaps we started the Reset, but the callback notification has not yet arrived.
                    if (iResetInProgress)
                    {
                        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                                        (0, "PVMFOMXEncNode-%s::DoReset() OMX comp is in loaded state. Wait for official callback to change variables etc.", iNodeTypeId));
                        return;
                    }
                }
                else if (sState == OMX_StateIdle)
                {
                    //this command is asynchronous.  move the command from
                    //the input command queue to the current command, where
                    //it will remain until it is completed.
                    if (!iResetInProgress)
                    {
                        int32 err;
                        OSCL_TRY(err, iCurrentCommand.StoreL(aCmd););
                        if (err != OsclErrNone)
                        {
                            CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
                            return;
                        }
                        iInputCommands.Erase(&aCmd);

                        iResetInProgress = true;
                    }

                    // if buffers aren't all back (due to timing issues with different callback AOs
                    //      state change can be reported before all buffers are returned)
                    if (iNumOutstandingInputBuffers > 0 || iNumOutstandingOutputBuffers > 0)
                    {
                        LOGE("PVMFOMXEncNode-%s::DoReset() Waiting for %d input and-or %d output buffers", iNodeTypeId, iNumOutstandingInputBuffers, iNumOutstandingOutputBuffers);

                        return;
                    }

                    if (!iResetMsgSent)
                    {
                        // We can come here only if all buffers are already back
                        // Don't repeat any of this twice.
                        /* Change state to OMX_StateLoaded form OMX_StateIdle. */
                        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                                        (0, "PVMFOMXEncNode-%s::DoReset() Changing Component State Idle->Loaded", iNodeTypeId));

                        err = OMX_SendCommand(iOMXEncoder, OMX_CommandStateSet, OMX_StateLoaded, NULL);
                        if (err != OMX_ErrorNone)
                        {
                            //Error condition report
                            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                                            (0, "PVMFOMXEncNode-%s::DoReset(): Can't send StateSet command to encoder!", iNodeTypeId));
                        }

                        iResetMsgSent = true;


                        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                                        (0, "PVMFOMXEncNode-%s::DoReset() freeing output buffers", iNodeTypeId));

                        if (false == iOutputBuffersFreed)
                        {
                            if (!FreeBuffersFromComponent(iOutBufMemoryPool, // allocator
                                                          iOutputAllocSize,  // size to allocate from pool (hdr only or hdr+ buffer)
                                                          iNumOutputBuffers, // number of buffers
                                                          iOutputPortIndex, // port idx
                                                          false // this is not input
                                                         ))
                            {
                                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                                                (0, "PVMFOMXEncNode-%s::DoReset() Cannot free output buffers ", iNodeTypeId));

                                if (iResetInProgress)
                                {
                                    iResetInProgress = false;
                                    if ((iCurrentCommand.size() > 0) &&
                                            (iCurrentCommand.front().iCmd == PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_RESET)
                                       )
                                    {
                                        CommandComplete(iCurrentCommand, iCurrentCommand.front() , PVMFErrResource);
                                    }
                                }

                            }

                        }
                        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                                        (0, "PVMFOMXEncNode-%s::DoReset() freeing input buffers ", iNodeTypeId));
                        if (false == iInputBuffersFreed)
                        {
                            if (!FreeBuffersFromComponent(iInBufMemoryPool, // allocator
                                                          iInputAllocSize,   // size to allocate from pool (hdr only or hdr+ buffer)
                                                          iNumInputBuffers, // number of buffers
                                                          iInputPortIndex, // port idx
                                                          true // this is input
                                                         ))
                            {
                                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                                                (0, "PVMFOMXEncNode-%s::DoReset() Cannot free input buffers ", iNodeTypeId));

                                if (iResetInProgress)
                                {
                                    iResetInProgress = false;
                                    if ((iCurrentCommand.size() > 0) &&
                                            (iCurrentCommand.front().iCmd == PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_RESET)
                                       )
                                    {
                                        CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFErrResource);
                                    }
                                }


                            }
                        }



                        iEndOfDataReached = false;
                        iIsEOSSentToComponent = false;
                        iIsEOSReceivedFromComponent = false;



                        // also, perform Port deletion when the component replies with the command
                        // complete, not right here
                    } // end of if(iResetMsgSent)


                    return;

                }
                else if ((sState == OMX_StateExecuting) || (sState == OMX_StatePause))
                {
                    //this command is asynchronous.  move the command from
                    //the input command queue to the current command, where
                    //it will remain until it is completed.
                    if (!iResetInProgress)
                    {
                        int32 err;
                        OSCL_TRY(err, iCurrentCommand.StoreL(aCmd););
                        if (err != OsclErrNone)
                        {
                            CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
                            return;
                        }
                        iInputCommands.Erase(&aCmd);

                        iResetInProgress = true;
                    }

                    /* Change state to OMX_StateIdle from OMX_StateExecuting or OMX_StatePause. */

                    if (!iStopInResetMsgSent)
                    {

                        // don't send twice in a row

                        iDataIn.Unbind();
                        iPreviousMediaData.Unbind();
                        if ((iOutFormat == PVMF_MIME_H264_VIDEO_MP4) || (iOutFormat == PVMF_MIME_H264_VIDEO_RAW))
                        {
                            // prepare for next start (if it comes)
                            iFirstNAL = true;
                        }
                        // Clear queued messages in ports
                        if (iInPort)
                        {
                            iInPort->ClearMsgQueues();
                        }

                        if (iOutPort)
                        {
                            iOutPort->ClearMsgQueues();
                        }

                        // Clear the data flags

                        iEndOfDataReached = false;
                        iIsEOSSentToComponent = false;
                        iIsEOSReceivedFromComponent = false;


                        iDoNotSendOutputBuffersDownstreamFlag = true; // stop sending output buffers downstream
                        iDoNotSaveInputBuffersFlag = true;

                        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                                        (0, "PVMFOMXEncNode-%s::DoReset() Changing Component State Executing->Idle or Pause->Idle", iNodeTypeId));

                        err = OMX_SendCommand(iOMXEncoder, OMX_CommandStateSet, OMX_StateIdle, NULL);
                        if (err != OMX_ErrorNone)
                        {
                            //Error condition report
                            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                                            (0, "PVMFOMXEncNode-%s::DoReset(): Can't send StateSet command to Encoder!", iNodeTypeId));

                            CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
                            break;
                        }

                        iStopInResetMsgSent = true;

                        // prevent the node from sending more buffers etc.
                        // if port reconfiguration is in process, let the state remain one of the port config states
                        //  if there is a start command, we can do it seemlessly (by continuing the port reconfig)
                        if (iProcessingState == EPVMFOMXEncNodeProcessingState_ReadyToEncode)
                            iProcessingState = EPVMFOMXEncNodeProcessingState_Stopping;
                    }
                    return;
                }
                else
                {
                    //Error condition report
                    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                                    (0, "PVMFOMXEncNode-%s::DoReset(): Encoder is not in the Idle state! %d", iNodeTypeId, sState ));
                    //do it here rather than relying on DTOR to avoid node reinit problems.
                    DeleteOMXEncoder();
                    //still return success.
                }//end of if (sState == OMX_StateLoaded)
            }//end of if (iOMXEncoder != NULL)

            //delete all ports and notify observer.
            if (iInPort)
            {
                OSCL_DELETE(((PVMFOMXEncPort*)iInPort));
                iInPort = NULL;
            }

            if (iOutPort)
            {
                OSCL_DELETE(((PVMFOMXEncPort*)iOutPort));
                iOutPort = NULL;
            }

            iDataIn.Unbind();


            // Reset the metadata key list
            iAvailableMetadataKeys.clear();

            iEndOfDataReached = false;
            iIsEOSSentToComponent = false;
            iIsEOSReceivedFromComponent = false;


            iProcessingState = EPVMFOMXEncNodeProcessingState_Idle;
            //logoff & go back to Created state.
            SetState(EPVMFNodeIdle);


            if (iResetInProgress)
            {
                iResetInProgress = false;
                if ((iCurrentCommand.size() > 0) &&
                        (iCurrentCommand.front().iCmd == PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_RESET)
                   )
                {
                    CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFSuccess);
                }
            }
            else
            {
                CommandComplete(iInputCommands, aCmd, PVMFSuccess);
            }

        }
        break;

        default:
            CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
            break;
    }
}

/////////////////////////////////////////////////////////////////////////////
void PVMFOMXEncNode::DoRequestPort(PVMFOMXEncNodeCommand& aCmd)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFOMXEncNode-%s::DoRequestPort() In", iNodeTypeId));
    //This node supports port request from any state

    //retrieve port tag.
    int32 tag;
    OSCL_String* portconfig;

    aCmd.PVMFOMXEncNodeCommandBase::Parse(tag, portconfig);

    PVMFPortInterface* port = NULL;


    int32 leavecode = 0;
    //validate the tag...

    switch (tag)
    {
        case PVMF_OMX_ENC_NODE_PORT_TYPE_INPUT:
            if (iInPort)
            {
                CommandComplete(iInputCommands, aCmd, PVMFFailure);
                break;
            }
            OSCL_TRY(leavecode, iInPort = OSCL_NEW(PVMFOMXEncPort, ((int32)tag, this, "OMXEncIn")););
            if (leavecode || iInPort == NULL)
            {
                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
                                (0, "PVMFOMXEncNode-%s::DoRequestPort: Error - Input port instantiation failed", iNodeTypeId));
                CommandComplete(iInputCommands, aCmd, PVMFErrArgument);
                return;
            }

            // if format was provided in mimestring, set it now.
            if (portconfig)
            {
                PVMFFormatType format = portconfig->get_str();
                if (((PVMFOMXEncPort*)iInPort)->IsFormatSupported(format))
                {
                    ((PVMFOMXEncPort*)iInPort)->iFormat = format;
                }
                else
                {

                    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
                                    (0, "PVMFOMXEncNode-%s::DoRequestPort: Error - Input port does not support format %s", iNodeTypeId, format.getMIMEStrPtr()));
                    OSCL_DELETE(((PVMFOMXEncPort*)iInPort));
                    iInPort = NULL;
                    CommandComplete(iInputCommands, aCmd, PVMFErrArgument);
                    return;
                }

            }


            port = iInPort;
            break;

        case PVMF_OMX_ENC_NODE_PORT_TYPE_OUTPUT:
            if (iOutPort)
            {
                CommandComplete(iInputCommands, aCmd, PVMFFailure);
                break;
            }
            OSCL_TRY(leavecode, iOutPort = OSCL_NEW(PVMFOMXEncPort, ((int32)tag, this, "OMXEncOut")));
            if (leavecode || iOutPort == NULL)
            {
                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
                                (0, "PVMFOMXEncNode-%s::DoRequestPort: Error - Output port instantiation failed", iNodeTypeId));
                CommandComplete(iInputCommands, aCmd, PVMFErrArgument);
                return;
            }

            // if format was provided in mimestring, set it now.
            if (portconfig)
            {
                PVMFFormatType format = portconfig->get_str();
                if (((PVMFOMXEncPort*)iOutPort)->IsFormatSupported(format) && (SetCodecType(format) == PVMFSuccess))
                {
                    ((PVMFOMXEncPort*)iOutPort)->iFormat = format;
                }
                else
                {

                    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
                                    (0, "PVMFOMXEncNode-%s::DoRequestPort: Error - Output port does not support format %s", iNodeTypeId, format.getMIMEStrPtr()));
                    OSCL_DELETE(((PVMFOMXEncPort*)iOutPort));
                    iOutPort = NULL;
                    CommandComplete(iInputCommands, aCmd, PVMFErrArgument);
                    return;
                }


            }

            port = iOutPort;
            break;

        default:
            //bad port tag
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
                            (0, "PVMFOMXEncNode-%s::DoRequestPort: Error - Invalid port tag", iNodeTypeId));
            CommandComplete(iInputCommands, aCmd, PVMFErrArgument);
            return;
    }

    //Return the port pointer to the caller.
    CommandComplete(iInputCommands, aCmd, PVMFSuccess, (OsclAny*)port);
}

/////////////////////////////////////////////////////////////////////////////
void PVMFOMXEncNode::DoReleasePort(PVMFOMXEncNodeCommand& aCmd)
{
    PVMFPortInterface* temp;
    aCmd.PVMFOMXEncNodeCommandBase::Parse(temp);
    PVMFOMXEncPort* port = (PVMFOMXEncPort*) temp;
#ifdef _TEST_AE_ERROR_HANDLING
    if (FAIL_NODE_CMD_RELEASE_PORT == iErrorNodeCmd)
    {
        port = NULL;
    }
#endif

    if (port != NULL && (port == iInPort || port == iOutPort))
    {
        if (port == iInPort)
        {
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "PVMFOMXEncNode-%s::DoReleasePort Input port released", iNodeTypeId));

            OSCL_DELETE(((PVMFOMXEncPort*)iInPort));
            iInPort = NULL;
        }
        else
        {
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "PVMFOMXEncNode-%s::DoReleasePort Output port released", iNodeTypeId));

            OSCL_DELETE(((PVMFOMXEncPort*)iOutPort));
            iOutPort = NULL;
        }
        //delete the port.
        CommandComplete(iInputCommands, aCmd, PVMFSuccess);
    }
    else
    {
        //port not found.
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
                        (0, "PVMFOMXEncNode-%s::DoReleasePort ERROR unknown port cannot be released", iNodeTypeId));

        CommandComplete(iInputCommands, aCmd, PVMFFailure);
    }
}

/////////////////////////////////////////////////////////////////////////////
PVMFStatus PVMFOMXEncNode::DoGetNodeMetadataKey(PVMFOMXEncNodeCommand& aCmd)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFOMXEncNode-%s::DoGetNodeMetadataKey() In", iNodeTypeId));

    PVMFMetadataList* keylistptr = NULL;
    uint32 starting_index;
    int32 max_entries;
    char* query_key;

    aCmd.PVMFOMXEncNodeCommand::Parse(keylistptr, starting_index, max_entries, query_key);

    // Check parameters
    if (keylistptr == NULL)
    {
        // The list pointer is invalid
        return PVMFErrArgument;
    }

    // Update the available metadata keys
    iAvailableMetadataKeys.clear();
    int32 leavecode = 0;
    leavecode = Push_Back_MetadataKeys(PVOMXENCMETADATA_CODECINFO_VIDEO_FORMAT_KEY);

    if (iYUVWidth > 0 && iYUVHeight > 0)
    {
        leavecode = 0;
        leavecode = Push_Back_MetadataKeys(PVOMXENCMETADATA_CODECINFO_VIDEO_WIDTH_KEY);
        if (0 == leavecode)
            leavecode = Push_Back_MetadataKeys(PVOMXENCMETADATA_CODECINFO_VIDEO_HEIGHT_KEY);
    }
    // add the profile, level and avgbitrate
    PVMF_MPEGVideoProfileType aProfile;
    PVMF_MPEGVideoLevelType aLevel;
    if (GetProfileAndLevel(aProfile, aLevel) == PVMFSuccess)
    {
        // For H263 this metadata will be available only after first frame decoding
        leavecode = 0;
        leavecode = Push_Back_MetadataKeys(PVOMXENCMETADATA_CODECINFO_VIDEO_PROFILE_KEY);
        if (0 == leavecode)
            leavecode = Push_Back_MetadataKeys(PVOMXENCMETADATA_CODECINFO_VIDEO_LEVEL_KEY);
    }
    if (0 == leavecode)
        leavecode = Push_Back_MetadataKeys(PVOMXENCMETADATA_CODECINFO_VIDEO_AVGBITRATE_KEY);

    if ((starting_index > (iAvailableMetadataKeys.size() - 1)) || max_entries == 0)
    {
        // Invalid starting index and/or max entries
        return PVMFErrArgument;
    }

    // Copy the requested keys
    uint32 num_entries = 0;
    int32 num_added = 0;
    for (uint32 lcv = 0; lcv < iAvailableMetadataKeys.size(); lcv++)
    {
        if (query_key == NULL)
        {
            // No query key so this key is counted
            ++num_entries;
            if (num_entries > starting_index)
            {
                // Past the starting index so copy the key
                leavecode = 0;
                leavecode = Push_Back_MetadataKeys(keylistptr, lcv);
                OSCL_FIRST_CATCH_ANY(leavecode,
                                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                                                     (0, "PVMFOMXEncNode-%s::DoGetNodeMetadataKey() Memory allocation failure when copying metadata key", iNodeTypeId));
                                     return PVMFErrNoMemory);
                num_added++;
            }
        }
        else
        {
            // Check if the key matche the query key
            if (pv_mime_strcmp(iAvailableMetadataKeys[lcv].get_cstr(), query_key) >= 0)
            {
                // This key is counted
                ++num_entries;
                if (num_entries > starting_index)
                {
                    // Past the starting index so copy the key
                    leavecode = 0;
                    leavecode = Push_Back_MetadataKeys(keylistptr, lcv);
                    OSCL_FIRST_CATCH_ANY(leavecode,
                                         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::DoGetNodeMetadataKey() Memory allocation failure when copying metadata key", iNodeTypeId));
                                         return PVMFErrNoMemory);
                    num_added++;
                }
            }
        }

        // Check if max number of entries have been copied
        if (max_entries > 0 && num_added >= max_entries)
        {
            break;
        }
    }

    return PVMFSuccess;
}

/////////////////////////////////////////////////////////////////////////////
PVMFStatus PVMFOMXEncNode::DoGetNodeMetadataValue(PVMFOMXEncNodeCommand& aCmd)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::DoGetNodeMetadataValue() In", iNodeTypeId));

    PVMFMetadataList* keylistptr = NULL;
    Oscl_Vector<PvmiKvp, OsclMemAllocator>* valuelistptr = NULL;
    uint32 starting_index;
    int32 max_entries;

    aCmd.PVMFOMXEncNodeCommand::Parse(keylistptr, valuelistptr, starting_index, max_entries);

    // Check the parameters
    if (keylistptr == NULL || valuelistptr == NULL)
    {
        return PVMFErrArgument;
    }

    uint32 numkeys = keylistptr->size();

    if (starting_index > (numkeys - 1) || numkeys <= 0 || max_entries == 0)
    {
        // Don't do anything
        return PVMFErrArgument;
    }

    uint32 numvalentries = 0;
    int32 numentriesadded = 0;
    for (uint32 lcv = 0; lcv < numkeys; lcv++)
    {
        int32 leavecode = 0;
        PvmiKvp KeyVal;
        KeyVal.key = NULL;
        uint32 KeyLen = 0;

        if ((oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVOMXENCMETADATA_CODECINFO_VIDEO_WIDTH_KEY) == 0) &&
                iYUVWidth > 0)
        {
            // Video width
            // Increment the counter for the number of values found so far
            ++numvalentries;

            // Create a value entry if past the starting index
            if (numvalentries > starting_index)
            {
                KeyLen = oscl_strlen(PVOMXENCMETADATA_CODECINFO_VIDEO_WIDTH_KEY) + 1; // for "codec-info/video/width;"
                KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
                KeyLen += oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR) + 1; // for "uint32" and NULL terminator

                // Allocate memory for the string
                leavecode = 0;
                leavecode = CreateNewArray(KeyVal.key, KeyLen);



                if (leavecode == 0)
                {
                    // Copy the key string
                    oscl_strncpy(KeyVal.key, PVOMXENCMETADATA_CODECINFO_VIDEO_WIDTH_KEY, oscl_strlen(PVOMXENCMETADATA_CODECINFO_VIDEO_WIDTH_KEY) + 1);
                    oscl_strncat(KeyVal.key, PVOMXENCMETADATA_SEMICOLON, oscl_strlen(PVOMXENCMETADATA_SEMICOLON));
                    oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
                    oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR));
                    KeyVal.key[KeyLen-1] = NULL_TERM_CHAR;
                    // Copy the value
                    KeyVal.value.uint32_value = iYUVWidth;
                    // Set the length and capacity
                    KeyVal.length = 1;
                    KeyVal.capacity = 1;
                }
                else
                {
                    // Memory allocation failed
                    KeyVal.key = NULL;
                    break;
                }
            }
        }
        else if ((oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVOMXENCMETADATA_CODECINFO_VIDEO_HEIGHT_KEY) == 0) &&
                 iYUVHeight > 0)
        {
            // Video height
            // Increment the counter for the number of values found so far
            ++numvalentries;

            // Create a value entry if past the starting index
            if (numvalentries > starting_index)
            {
                KeyLen = oscl_strlen(PVOMXENCMETADATA_CODECINFO_VIDEO_HEIGHT_KEY) + 1; // for "codec-info/video/height;"
                KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
                KeyLen += oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR) + 1; // for "uint32" and NULL terminator

                // Allocate memory for the string
                leavecode = 0;
                leavecode = CreateNewArray(KeyVal.key, KeyLen);



                if (leavecode == 0)
                {
                    // Copy the key string
                    oscl_strncpy(KeyVal.key, PVOMXENCMETADATA_CODECINFO_VIDEO_HEIGHT_KEY, oscl_strlen(PVOMXENCMETADATA_CODECINFO_VIDEO_HEIGHT_KEY) + 1);
                    oscl_strncat(KeyVal.key, PVOMXENCMETADATA_SEMICOLON, oscl_strlen(PVOMXENCMETADATA_SEMICOLON));
                    oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
                    oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR));
                    KeyVal.key[KeyLen-1] = NULL_TERM_CHAR;
                    // Copy the value
                    KeyVal.value.uint32_value = iYUVHeight;
                    // Set the length and capacity
                    KeyVal.length = 1;
                    KeyVal.capacity = 1;
                }
                else
                {
                    // Memory allocation failed
                    KeyVal.key = NULL;
                    break;
                }
            }
        }
        else if ((oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVOMXENCMETADATA_CODECINFO_VIDEO_PROFILE_KEY) == 0))
        {
            // Video profile
            // Increment the counter for the number of values found so far
            ++numvalentries;

            // Create a value entry if past the starting index
            if (numvalentries > starting_index)
            {
                KeyLen = oscl_strlen(PVOMXENCMETADATA_CODECINFO_VIDEO_PROFILE_KEY) + 1; // for "codec-info/video/profile;"
                KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
                KeyLen += oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR) + 1; // for "uint32" and NULL terminator

                // Allocate memory for the string
                leavecode = 0;
                leavecode = CreateNewArray(KeyVal.key, KeyLen);



                if (leavecode == 0)
                {
                    PVMF_MPEGVideoProfileType aProfile;
                    PVMF_MPEGVideoLevelType aLevel;
                    if (GetProfileAndLevel(aProfile, aLevel) == PVMFSuccess)
                    {
                        // Copy the key string
                        oscl_strncpy(KeyVal.key, PVOMXENCMETADATA_CODECINFO_VIDEO_PROFILE_KEY, oscl_strlen(PVOMXENCMETADATA_CODECINFO_VIDEO_PROFILE_KEY) + 1);
                        oscl_strncat(KeyVal.key, PVOMXENCMETADATA_SEMICOLON, oscl_strlen(PVOMXENCMETADATA_SEMICOLON));
                        oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
                        oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR));
                        KeyVal.key[KeyLen-1] = NULL_TERM_CHAR;
                        // Copy the value
                        KeyVal.value.uint32_value = (uint32)aProfile; // This is to be decided, who will interpret these value
                        // Set the length and capacity
                        KeyVal.length = 1;
                        KeyVal.capacity = 1;
                    }
                    else
                    {
                        // Memory allocation failed
                        KeyVal.key = NULL;
                        break;
                    }
                }
                else
                {
                    // Memory allocation failed
                    KeyVal.key = NULL;
                    break;
                }
            }
        }
        else if ((oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVOMXENCMETADATA_CODECINFO_VIDEO_LEVEL_KEY) == 0))
        {
            // Video level
            // Increment the counter for the number of values found so far
            ++numvalentries;

            // Create a value entry if past the starting index
            if (numvalentries > starting_index)
            {
                KeyLen = oscl_strlen(PVOMXENCMETADATA_CODECINFO_VIDEO_LEVEL_KEY) + 1; // for "codec-info/video/level;"
                KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
                KeyLen += oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR) + 1; // for "uint32" and NULL terminator

                // Allocate memory for the string
                leavecode = 0;
                leavecode = CreateNewArray(KeyVal.key, KeyLen);



                if (leavecode == 0)
                {
                    PVMF_MPEGVideoProfileType aProfile;
                    PVMF_MPEGVideoLevelType aLevel;
                    if (GetProfileAndLevel(aProfile, aLevel) == PVMFSuccess)
                    {
                        // Copy the key string
                        oscl_strncpy(KeyVal.key, PVOMXENCMETADATA_CODECINFO_VIDEO_LEVEL_KEY, oscl_strlen(PVOMXENCMETADATA_CODECINFO_VIDEO_LEVEL_KEY) + 1);
                        oscl_strncat(KeyVal.key, PVOMXENCMETADATA_SEMICOLON, oscl_strlen(PVOMXENCMETADATA_SEMICOLON));
                        oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
                        oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR));
                        KeyVal.key[KeyLen-1] = NULL_TERM_CHAR;
                        // Copy the value
                        KeyVal.value.uint32_value = (uint32)aLevel; // This is to be decided, who will interpret these value
                        // Set the length and capacity
                        KeyVal.length = 1;
                        KeyVal.capacity = 1;
                    }
                    else
                    {
                        // Memory allocation failed
                        KeyVal.key = NULL;
                        break;
                    }
                }
                else
                {
                    // Memory allocation failed
                    KeyVal.key = NULL;
                    break;
                }
            }
        }
        else if ((oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVOMXENCMETADATA_CODECINFO_VIDEO_AVGBITRATE_KEY) == 0) &&
                 (iAvgBitrateValue > 0))
        {
            // Video average bitrate
            // Increment the counter for the number of values found so far
            ++numvalentries;

            // Create a value entry if past the starting index
            if (numvalentries > starting_index)
            {
                KeyLen = oscl_strlen(PVOMXENCMETADATA_CODECINFO_VIDEO_AVGBITRATE_KEY) + 1; // for "codec-info/video/avgbitrate;"
                KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
                KeyLen += oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR) + 1; // for "uint32" and NULL terminator

                // Allocate memory for the string
                leavecode = 0;
                leavecode = CreateNewArray(KeyVal.key, KeyLen);



                if (leavecode == 0)
                {
                    // Copy the key string
                    oscl_strncpy(KeyVal.key, PVOMXENCMETADATA_CODECINFO_VIDEO_AVGBITRATE_KEY, oscl_strlen(PVOMXENCMETADATA_CODECINFO_VIDEO_AVGBITRATE_KEY) + 1);
                    oscl_strncat(KeyVal.key, PVOMXENCMETADATA_SEMICOLON, oscl_strlen(PVOMXENCMETADATA_SEMICOLON));
                    oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
                    oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR));
                    KeyVal.key[KeyLen-1] = NULL_TERM_CHAR;
                    // Copy the value
                    KeyVal.value.uint32_value = iAvgBitrateValue;
                    // Set the length and capacity
                    KeyVal.length = 1;
                    KeyVal.capacity = 1;

                }
                else
                {
                    // Memory allocation failed
                    KeyVal.key = NULL;
                    break;
                }
            }
        }
        else if ((oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVOMXENCMETADATA_CODECINFO_VIDEO_FORMAT_KEY) == 0) &&
                 (((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_H2631998 || ((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_H2632000 || ((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_M4V ||
                  ((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO || ((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO_MP4 ||
                  ((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO_RAW  || ((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_WMV))
        {
            // Format
            // Increment the counter for the number of values found so far
            ++numvalentries;

            // Create a value entry if past the starting index
            if (numvalentries > starting_index)
            {
                KeyLen = oscl_strlen(PVOMXENCMETADATA_CODECINFO_VIDEO_FORMAT_KEY) + 1; // for "codec-info/video/format;"
                KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
                KeyLen += oscl_strlen(PVMI_KVPVALTYPE_CHARPTR_STRING_CONSTCHAR) + 1; // for "char*" and NULL terminator

                uint32 valuelen = 0;
                if (((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO)
                {
                    valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_H264_VIDEO)) + 1; // Value string plus one for NULL terminator
                }
                else if (((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO_MP4)
                {
                    valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_H264_VIDEO_MP4)) + 1; // Value string plus one for NULL terminator
                }
                else if (((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO_RAW)
                {
                    valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_H264_VIDEO_RAW)) + 1; // Value string plus one for NULL terminator
                }
                else if (((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_M4V)
                {
                    valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_M4V)) + 1; // Value string plus one for NULL terminator
                }
                else if (((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_H2631998)
                {
                    valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_H2631998)) + 1; // Value string plus one for NULL terminator
                }
                else if (((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_H2632000)
                {
                    oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_H2632000), valuelen);
                }
                else if (((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_WMV)
                {
                    valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_WMV)) + 1; // Value string plus one for NULL terminator
                }
                else
                {
                    // Should not enter here
                    OSCL_ASSERT(false);
                    valuelen = 1;
                }

                // Allocate memory for the strings
                leavecode = 0;
                leavecode = CreateNewArray(KeyVal.key, KeyLen);
                if (0 == leavecode)
                {
                    leavecode = CreateNewArray(KeyVal.value.pChar_value , valuelen);
                }

                if (leavecode == 0)
                {
                    // Copy the key string
                    oscl_strncpy(KeyVal.key, PVOMXENCMETADATA_CODECINFO_VIDEO_FORMAT_KEY, oscl_strlen(PVOMXENCMETADATA_CODECINFO_VIDEO_FORMAT_KEY) + 1);
                    oscl_strncat(KeyVal.key, PVOMXENCMETADATA_SEMICOLON, oscl_strlen(PVOMXENCMETADATA_SEMICOLON));
                    oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
                    oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_CHARPTR_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_CHARPTR_STRING_CONSTCHAR));
                    KeyVal.key[KeyLen-1] = NULL_TERM_CHAR;
                    // Copy the value
                    if (((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO)
                    {
                        oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_H264_VIDEO), valuelen);
                    }
                    else if (((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO_MP4)
                    {
                        oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_H264_VIDEO_MP4), valuelen);
                    }
                    else if (((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO_RAW)
                    {
                        oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_H264_VIDEO_RAW), valuelen);
                    }
                    else if (((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_M4V)
                    {
                        oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_M4V), valuelen);
                    }
                    else if (((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_H2631998)
                    {
                        oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_H2631998), valuelen);
                    }
                    else if (((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_H2632000)
                    {
                        oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_H2632000), valuelen);
                    }
                    else if (((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_WMV)
                    {
                        oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_WMV), valuelen);
                    }
                    else
                    {
                        // Should not enter here
                        OSCL_ASSERT(false);
                        valuelen = 1;
                    }

                    KeyVal.value.pChar_value[valuelen-1] = NULL_TERM_CHAR;
                    // Set the length and capacity
                    KeyVal.length = valuelen;
                    KeyVal.capacity = valuelen;
                }
                else
                {
                    // Memory allocation failed so clean up
                    if (KeyVal.key)
                    {
                        OSCL_ARRAY_DELETE(KeyVal.key);
                        KeyVal.key = NULL;
                    }
                    if (KeyVal.value.pChar_value)
                    {
                        OSCL_ARRAY_DELETE(KeyVal.value.pChar_value);
                    }
                    break;
                }
            }
        }

        if (KeyVal.key != NULL)
        {
            leavecode = 0;
            leavecode = PushBackKeyVal(valuelistptr, KeyVal);
            if (leavecode != 0)
            {
                switch (GetValTypeFromKeyString(KeyVal.key))
                {
                    case PVMI_KVPVALTYPE_CHARPTR:
                        if (KeyVal.value.pChar_value != NULL)
                        {
                            OSCL_ARRAY_DELETE(KeyVal.value.pChar_value);
                            KeyVal.value.pChar_value = NULL;
                        }
                        break;

                    default:
                        // Add more case statements if other value types are returned
                        break;
                }

                OSCL_ARRAY_DELETE(KeyVal.key);
                KeyVal.key = NULL;
            }
            else
            {
                // Increment the counter for number of value entries added to the list
                ++numentriesadded;
            }

            // Check if the max number of value entries were added
            if (max_entries > 0 && numentriesadded >= max_entries)
            {
                break;
            }
        }
    }

    return PVMFSuccess;
}

/////////////////////////////////////////////////////////////////////////////
bool PVMFOMXEncNode::ReleaseAllPorts()
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::ReleaseAllPorts() In", iNodeTypeId));

    if (iInPort)
    {
        iInPort->ClearMsgQueues();
        iInPort->Disconnect();
        OSCL_DELETE(((PVMFOMXEncPort*)iInPort));
        iInPort = NULL;
    }

    if (iOutPort)
    {
        iOutPort->ClearMsgQueues();
        iOutPort->Disconnect();
        OSCL_DELETE(((PVMFOMXEncPort*)iOutPort));
        iOutPort = NULL;
    }

    return true;
}

/////////////////////////////////////////////////////////////////////////////
// Clean Up Encoder
/////////////////////////////////////////////////////////////////////////////
bool PVMFOMXEncNode::DeleteOMXEncoder()
{
    OMX_ERRORTYPE  err;

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFOMXEncNode-%s::DeleteOMXEncoder() In", iNodeTypeId));

    if (iOMXEncoder != NULL)
    {
        /* Free Component handle. */
        err = OMX_MasterFreeHandle(iOMXEncoder);
        if (err != OMX_ErrorNone)
        {
            //Error condition report
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
                            (0, "PVMFOMXEncNode-%s::DeleteOMXEncoder(): Can't free encoder's handle!", iNodeTypeId));
        }
        iOMXEncoder = NULL;

    }//end of if (iOMXEncoder != NULL)


    return true;
}

/////////////////////////////////////////////////////////////////////////////
void PVMFOMXEncNode::ChangeNodeState(TPVMFNodeInterfaceState aNewState)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::ChangeNodeState() Changing state from %d to %d", iNodeTypeId, iInterfaceState, aNewState));
    iInterfaceState = aNewState;
}

/////////////////////////////////////////////////////////////////////////////
void PVMFOMXEncNode::freechunkavailable(OsclAny *aContext)
{

    // check context to see whether input or output buffer was returned to the mempool
    if (aContext == (OsclAny *) iInBufMemoryPool)
    {

        iNumOutstandingInputBuffers--;

        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::freechunkavailable() Memory chunk in INPUT mempool was deallocated, %d out of %d now available", iNodeTypeId, iNumInputBuffers - iNumOutstandingInputBuffers, iNumInputBuffers));

        // notification only works once.
        // If there are multiple buffers coming back in a row, make sure to set the notification
        // flag in the mempool again, so that next buffer also causes notification
        iInBufMemoryPool->notifyfreechunkavailable(*this, aContext);

    }
    else if (aContext == (OsclAny *) iOutBufMemoryPool)
    {

        iNumOutstandingOutputBuffers--;
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::freechunkavailable() Memory chunk in OUTPUT mempool was deallocated, %d out of %d now available", iNodeTypeId, iNumOutputBuffers - iNumOutstandingOutputBuffers, iNumOutputBuffers));

        // notification only works once.
        // If there are multiple buffers coming back in a row, make sure to set the notification
        // flag in the mempool again, so that next buffer also causes notification
        iOutBufMemoryPool->notifyfreechunkavailable(*this, aContext);

    }
    else
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::freechunkavailable() UNKNOWN mempool ", iNodeTypeId));

    }

    // reschedule
    if (IsAdded())
        RunIfNotReady();


}

/////////////////////////////////////////////////////////////////////////////
void PVMFOMXEncNode::HandlePortActivity(const PVMFPortActivity &aActivity)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "0x%x PVMFOMXEncNode-%s::PortActivity: port=0x%x, type=%d",
                     this, iNodeTypeId, aActivity.iPort, aActivity.iType));

    switch (aActivity.iType)
    {
        case PVMF_PORT_ACTIVITY_OUTGOING_MSG:
            //An outgoing message was queued on this port.
            //We only need to queue a port activity event on the
            //first message.  Additional events will be queued during
            //the port processing as needed.
            if (aActivity.iPort->OutgoingMsgQueueSize() == 1)
            {
                //wake up the AO to process the port activity event.
                RunIfNotReady();
            }
            break;

        case PVMF_PORT_ACTIVITY_INCOMING_MSG:
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
                            (0, "PVMFOMXEncNode-%s::PortActivity: IncomingMsgQueueSize=%d", iNodeTypeId, aActivity.iPort->IncomingMsgQueueSize()));
            if (aActivity.iPort->IncomingMsgQueueSize() == 1)
            {
                //wake up the AO to process the port activity event.
                RunIfNotReady();
            }
            break;

        case PVMF_PORT_ACTIVITY_OUTGOING_QUEUE_READY:
            if (iProcessingState == EPVMFOMXEncNodeProcessingState_WaitForOutgoingQueue)
            {
                iProcessingState = EPVMFOMXEncNodeProcessingState_ReadyToEncode;
                RunIfNotReady();
            }
            break;

        case PVMF_PORT_ACTIVITY_CONNECT:
            //nothing needed.
            break;

        case PVMF_PORT_ACTIVITY_DISCONNECT:
            //clear the node input data when either port is disconnected.

            iDataIn.Unbind();
            break;

        case PVMF_PORT_ACTIVITY_CONNECTED_PORT_BUSY:
            // The connected port has become busy (its incoming queue is
            // busy).
            // No action is needed here-- the port processing code
            // checks for connected port busy during data processing.
            break;

        case PVMF_PORT_ACTIVITY_CONNECTED_PORT_READY:
            // The connected port has transitioned from Busy to Ready to Receive.
            // It's time to start processing outgoing messages again.

            //iProcessingState should transition from WaitForOutputPort to ReadyToEncode
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
                            (0, "0x%x PVMFOMXEncNode-%s::PortActivity: Connected port is now ready", this, iNodeTypeId));
            RunIfNotReady();
            break;

        default:
            break;
    }
}

/////////////////////////////////////////////////////////////////////////////
void PVMFOMXEncNode::DoCancelAllCommands(PVMFOMXEncNodeCommand& aCmd)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFOMXEncNode-%s::DoCancelAllCommands", iNodeTypeId));

    //first cancel the current command if any
    {
        while (!iCurrentCommand.empty())
        {
            CommandComplete(iCurrentCommand, iCurrentCommand[0], PVMFErrCancelled);
        }

    }

    //next cancel all queued commands
    {
        //start at element 1 since this cancel command is element 0.
        while (iInputCommands.size() > 1)
        {
            CommandComplete(iInputCommands, iInputCommands[1], PVMFErrCancelled);
        }
    }

    if (iResetInProgress && !iResetMsgSent)
    {
        // if reset is started but reset msg has not been sent, we can cancel reset
        // as if nothing happened. Otherwise, the callback will set the flag back to false
        iResetInProgress = false;
    }
    //finally, report cancel complete.
    CommandComplete(iInputCommands, aCmd, PVMFSuccess);
}

/////////////////////////////////////////////////////////////////////////////
void PVMFOMXEncNode::DoCancelCommand(PVMFOMXEncNodeCommand& aCmd)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFOMXEncNode-%s::DoCancelCommand", iNodeTypeId));

    //extract the command ID from the parameters.
    PVMFCommandId id;
    aCmd.PVMFOMXEncNodeCommandBase::Parse(id);

    //first check "current" command if any
    {
        PVMFOMXEncNodeCommand* cmd = iCurrentCommand.FindById(id);
        if (cmd)
        {

            // if reset is being canceled:
            if (cmd->iCmd == PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_RESET)
            {
                if (iResetInProgress && !iResetMsgSent)
                {
                    // if reset is started but reset msg has not been sent, we can cancel reset
                    // as if nothing happened. Otherwise, the callback will set the flag back to false
                    iResetInProgress = false;
                }
            }
            //cancel the queued command
            CommandComplete(iCurrentCommand, *cmd, PVMFErrCancelled);
            //report cancel success
            CommandComplete(iInputCommands, aCmd, PVMFSuccess);
            return;
        }
    }

    //next check input queue.
    {
        //start at element 1 since this cancel command is element 0.
        PVMFOMXEncNodeCommand* cmd = iInputCommands.FindById(id, 1);
        if (cmd)
        {
            //cancel the queued command
            CommandComplete(iInputCommands, *cmd, PVMFErrCancelled);
            //report cancel success
            CommandComplete(iInputCommands, aCmd, PVMFSuccess);
            return;
        }
    }
    //if we get here the command isn't queued so the cancel fails.
    CommandComplete(iInputCommands, aCmd, PVMFErrArgument);
}

/////////////////////////////////////////////////////////////////////////////
void PVMFOMXEncNode::DoQueryUuid(PVMFOMXEncNodeCommand& aCmd)
{
    //This node supports Query UUID from any state

    OSCL_String* mimetype;
    Oscl_Vector<PVUuid, OsclMemAllocator> *uuidvec;
    bool exactmatch;
    aCmd.PVMFOMXEncNodeCommandBase::Parse(mimetype, uuidvec, exactmatch);

    //Try to match the input mimetype against any of
    //the custom interfaces for this node

    //Match against custom interface1...
    if (*mimetype == PVMF_OMX_ENC_NODE_CUSTOM1_MIMETYPE
            //also match against base mimetypes for custom interface1,
            //unless exactmatch is set.
            || (!exactmatch && *mimetype == PVMF_OMX_ENC_NODE_MIMETYPE)
            || (!exactmatch && *mimetype == PVMF_BASEMIMETYPE))
    {

        PVUuid uuid(PVMF_OMX_ENC_NODE_CUSTOM1_UUID);
        uuidvec->push_back(uuid);
    }
    CommandComplete(iInputCommands, aCmd, PVMFSuccess);
}

/////////////////////////////////////////////////////////////////////////////
void PVMFOMXEncNode::DoQueryInterface(PVMFOMXEncNodeCommand&  aCmd)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFOMXEncNode-%s::DoQueryInterface", iNodeTypeId));
    PVUuid* uuid;
    PVInterface** ptr;
    aCmd.PVMFOMXEncNodeCommandBase::Parse(uuid, ptr);

    if (*uuid == PVUuid(PVMF_OMX_ENC_NODE_CUSTOM1_UUID))
    {
        addRef();
        *ptr = (PVMFOMXEncNodeExtensionInterface*)this;
        CommandComplete(iInputCommands, aCmd, PVMFSuccess);
    }
    else if (*uuid == PVUuid(KPVMFMetadataExtensionUuid))
    {
        addRef();
        *ptr = (PVMFMetadataExtensionInterface*)this;
        CommandComplete(iInputCommands, aCmd, PVMFSuccess);
    }
    else if (*uuid == PVUuid(PVMI_CAPABILITY_AND_CONFIG_PVUUID))
    {
        addRef();
        *ptr = (PvmiCapabilityAndConfig*)this;
        CommandComplete(iInputCommands, aCmd, PVMFSuccess);
    }
    else if (*uuid == PVMp4H263EncExtensionUUID)
    {
        addRef();
        *ptr = OSCL_STATIC_CAST(PVMp4H263EncExtensionInterface*, this);
        CommandComplete(iInputCommands, aCmd, PVMFSuccess);
        //iface = OSCL_STATIC_CAST(PVInterface*, myInterface);

    }
    else if (*uuid == PVAudioEncExtensionUUID)
    {
        addRef();
        *ptr = OSCL_STATIC_CAST(PVAudioEncExtensionInterface*, this);
        //iface = OSCL_STATIC_CAST(PVInterface*, myInterface);
        CommandComplete(iInputCommands, aCmd, PVMFSuccess);

    }
    else
    {
        //not supported
        *ptr = NULL;
        CommandComplete(iInputCommands, aCmd, PVMFFailure);
    }
}

/////////////////////////////////////////////////////////////////////////////
void PVMFOMXEncNode::addRef()
{
    ++iExtensionRefCount;
}

/////////////////////////////////////////////////////////////////////////////
void PVMFOMXEncNode::removeRef()
{
    --iExtensionRefCount;
}

/////////////////////////////////////////////////////////////////////////////
bool PVMFOMXEncNode::queryInterface(const PVUuid& uuid, PVInterface*& iface)
{
    PVUuid my_uuid(PVMF_OMX_ENC_NODE_CUSTOM1_UUID);
    if (uuid == my_uuid)
    {
        PVMFOMXEncNodeExtensionInterface* myInterface = OSCL_STATIC_CAST(PVMFOMXEncNodeExtensionInterface*, this);
        iface = OSCL_STATIC_CAST(PVInterface*, myInterface);
        ++iExtensionRefCount;
        return true;
    }
    else if (uuid == KPVMFMetadataExtensionUuid)
    {
        PVMFMetadataExtensionInterface* myInterface = OSCL_STATIC_CAST(PVMFMetadataExtensionInterface*, this);
        iface = OSCL_STATIC_CAST(PVInterface*, myInterface);
        ++iExtensionRefCount;
        return true;
    }
    return false;
}

/////////////////////////////////////////////////////////////////////////////
uint32 PVMFOMXEncNode::GetNumMetadataKeys(char* aQueryKeyString)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::GetNumMetadataKeys() called", iNodeTypeId));

    // Update the available metadata keys
    iAvailableMetadataKeys.clear();
    int32 errcode = 0;
    OSCL_TRY(errcode, iAvailableMetadataKeys.push_back(PVOMXENCMETADATA_CODECINFO_VIDEO_FORMAT_KEY));

    if (iYUVWidth > 0 && iYUVHeight > 0)
    {
        errcode = 0;
        OSCL_TRY(errcode,
                 iAvailableMetadataKeys.push_back(PVOMXENCMETADATA_CODECINFO_VIDEO_WIDTH_KEY);
                 iAvailableMetadataKeys.push_back(PVOMXENCMETADATA_CODECINFO_VIDEO_HEIGHT_KEY));
    }
    // add the profile, level and avgbitrate
    PVMF_MPEGVideoProfileType aProfile;
    PVMF_MPEGVideoLevelType aLevel;
    if (GetProfileAndLevel(aProfile, aLevel) == PVMFSuccess)
    {
        // For H263 this metadata will be available only after first frame decoding
        errcode = 0;
        OSCL_TRY(errcode, iAvailableMetadataKeys.push_back(PVOMXENCMETADATA_CODECINFO_VIDEO_PROFILE_KEY));
        errcode = 0;
        OSCL_TRY(errcode, iAvailableMetadataKeys.push_back(PVOMXENCMETADATA_CODECINFO_VIDEO_LEVEL_KEY));
    }
    errcode = 0;
    OSCL_TRY(errcode, iAvailableMetadataKeys.push_back(PVOMXENCMETADATA_CODECINFO_VIDEO_AVGBITRATE_KEY));



    uint32 num_entries = 0;

    if (aQueryKeyString == NULL)
    {
        num_entries = iAvailableMetadataKeys.size();
    }
    else
    {
        for (uint32 i = 0; i < iAvailableMetadataKeys.size(); i++)
        {
            if (pv_mime_strcmp(iAvailableMetadataKeys[i].get_cstr(), aQueryKeyString) >= 0)
            {
                num_entries++;
            }
        }
    }
    return num_entries; // Number of elements
}

///////////////////////////////////////////////////////////////////////////////////////
void PVMFOMXEncNode::setObserver(PvmiConfigAndCapabilityCmdObserver* aObserver)
{
    OSCL_UNUSED_ARG(aObserver);
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::setObserver()", iNodeTypeId));
    // This method is not supported so leave
    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::setObserver() is not supported!", iNodeTypeId));
    OSCL_LEAVE(PVMFErrNotSupported);
}


PVMFStatus PVMFOMXEncNode::getParametersSync(PvmiMIOSession aSession, PvmiKeyType aIdentifier, PvmiKvp*& aParameters, int& aNumParamElements, PvmiCapabilityContext aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::getParametersSync()", iNodeTypeId));
    OSCL_UNUSED_ARG(aSession);

    return DoCapConfigGetParametersSync(aIdentifier, aParameters, aNumParamElements, aContext);
}


PVMFStatus PVMFOMXEncNode::releaseParameters(PvmiMIOSession aSession, PvmiKvp* aParameters, int aNumElements)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::releaseParameters()", iNodeTypeId));
    OSCL_UNUSED_ARG(aSession);

    return DoCapConfigReleaseParameters(aParameters, aNumElements);
}


void PVMFOMXEncNode::createContext(PvmiMIOSession aSession, PvmiCapabilityContext& aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::createContext()", iNodeTypeId));
    OSCL_UNUSED_ARG(aSession);
    OSCL_UNUSED_ARG(aContext);
    // This method is not supported so leave
    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::createContext() is not supported!", iNodeTypeId));
    OSCL_LEAVE(PVMFErrNotSupported);
}


void PVMFOMXEncNode::setContextParameters(PvmiMIOSession aSession, PvmiCapabilityContext& aContext, PvmiKvp* aParameters, int aNumParamElements)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::setContextParameters()", iNodeTypeId));
    OSCL_UNUSED_ARG(aSession);
    OSCL_UNUSED_ARG(aContext);
    OSCL_UNUSED_ARG(aParameters);
    OSCL_UNUSED_ARG(aNumParamElements);
    // This method is not supported so leave
    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::setContextParameters() is not supported!", iNodeTypeId));
    OSCL_LEAVE(PVMFErrNotSupported);
}


void PVMFOMXEncNode::DeleteContext(PvmiMIOSession aSession, PvmiCapabilityContext& aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::DeleteContext()", iNodeTypeId));
    OSCL_UNUSED_ARG(aSession);
    OSCL_UNUSED_ARG(aContext);
    // This method is not supported so leave
    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::DeleteContext() is not supported!", iNodeTypeId));
    OSCL_LEAVE(PVMFErrNotSupported);
}


void PVMFOMXEncNode::setParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters, int aNumElements, PvmiKvp* &aRetKVP)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::setParametersSync()", iNodeTypeId));
    OSCL_UNUSED_ARG(aSession);

    // Complete the request synchronously
    DoCapConfigSetParameters(aParameters, aNumElements, aRetKVP);
}


PVMFCommandId PVMFOMXEncNode::setParametersAsync(PvmiMIOSession aSession, PvmiKvp* aParameters, int aNumElements, PvmiKvp*& aRetKVP, OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::setParametersAsync()", iNodeTypeId));
    OSCL_UNUSED_ARG(aSession);
    OSCL_UNUSED_ARG(aParameters);
    OSCL_UNUSED_ARG(aNumElements);
    OSCL_UNUSED_ARG(aRetKVP);
    OSCL_UNUSED_ARG(aContext);

    // This method is not supported so leave
    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::setParametersAsync() is not supported!", iNodeTypeId));
    OSCL_LEAVE(PVMFErrNotSupported);
    return 0;
}


uint32 PVMFOMXEncNode::getCapabilityMetric(PvmiMIOSession aSession)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::getCapabilityMetric()", iNodeTypeId));
    OSCL_UNUSED_ARG(aSession);
    // Not supported so return 0
    return 0;
}


PVMFStatus PVMFOMXEncNode::verifyParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters, int aNumElements)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::verifyParametersSync()", iNodeTypeId));
    OSCL_UNUSED_ARG(aSession);

    return DoCapConfigVerifyParameters(aParameters, aNumElements);
}


/////////////////////////////////////////////////////////////////////////////
uint32 PVMFOMXEncNode::GetNumMetadataValues(PVMFMetadataList& aKeyList)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::GetNumMetadataValues() called", iNodeTypeId));

    uint32 numkeys = aKeyList.size();

    if (numkeys <= 0)
    {
        // Don't do anything
        return 0;
    }

    // Count the number of value entries for the provided key list
    uint32 numvalentries = 0;
    PVMF_MPEGVideoProfileType aProfile;
    PVMF_MPEGVideoLevelType aLevel;
    for (uint32 lcv = 0; lcv < numkeys; lcv++)
    {
        if ((oscl_strcmp(aKeyList[lcv].get_cstr(), PVOMXENCMETADATA_CODECINFO_VIDEO_WIDTH_KEY) == 0) &&
                iYUVWidth > 0)
        {
            // Video width
            ++numvalentries;
        }
        else if ((oscl_strcmp(aKeyList[lcv].get_cstr(), PVOMXENCMETADATA_CODECINFO_VIDEO_HEIGHT_KEY) == 0) &&
                 iYUVHeight > 0)
        {
            // Video height
            ++numvalentries;
        }
        else if ((oscl_strcmp(aKeyList[lcv].get_cstr(), PVOMXENCMETADATA_CODECINFO_VIDEO_PROFILE_KEY) == 0) &&
                 (GetProfileAndLevel(aProfile, aLevel) == PVMFSuccess))

        {
            // Video profile
            ++numvalentries;
        }
        else if ((oscl_strcmp(aKeyList[lcv].get_cstr(), PVOMXENCMETADATA_CODECINFO_VIDEO_LEVEL_KEY) == 0) &&
                 (GetProfileAndLevel(aProfile, aLevel) == PVMFSuccess))
        {
            // Video level
            ++numvalentries;
        }
        else if ((oscl_strcmp(aKeyList[lcv].get_cstr(), PVOMXENCMETADATA_CODECINFO_VIDEO_AVGBITRATE_KEY) == 0) &&
                 (iAvgBitrateValue > 0))

        {
            // Video average bitrate
            if (iAvgBitrateValue > 0)
                ++numvalentries;
        }
        else if ((oscl_strcmp(aKeyList[lcv].get_cstr(), PVOMXENCMETADATA_CODECINFO_VIDEO_FORMAT_KEY) == 0) &&
                 (((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_WMV || ((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_M4V || ((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_H2631998 || ((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_H2632000 || ((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO || ((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO_MP4 || ((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO_RAW))
        {
            // Format
            ++numvalentries;
        }
    }

    return numvalentries;
}

/////////////////////////////////////////////////////////////////////////////
PVMFCommandId PVMFOMXEncNode::GetNodeMetadataKeys(PVMFSessionId aSessionId, PVMFMetadataList& aKeyList, uint32 starting_index, int32 max_entries, char* query_key, const OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNodeCommand::GetNodeMetadataKeys() called", iNodeTypeId));

    PVMFOMXEncNodeCommand cmd;
    cmd.PVMFOMXEncNodeCommand::Construct(aSessionId, PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_GETNODEMETADATAKEY, &aKeyList, starting_index, max_entries, query_key, aContext);
    return QueueCommandL(cmd);
}

/////////////////////////////////////////////////////////////////////////////
PVMFCommandId PVMFOMXEncNode::GetNodeMetadataValues(PVMFSessionId aSessionId, PVMFMetadataList& aKeyList, Oscl_Vector<PvmiKvp, OsclMemAllocator>& aValueList, uint32 starting_index, int32 max_entries, const OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNodeCommand::GetNodeMetadataValue() called", iNodeTypeId));

    PVMFOMXEncNodeCommand cmd;
    cmd.PVMFOMXEncNodeCommand::Construct(aSessionId, PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_GETNODEMETADATAVALUE, &aKeyList, &aValueList, starting_index, max_entries, aContext);
    return QueueCommandL(cmd);
}

// From PVMFMetadataExtensionInterface
/////////////////////////////////////////////////////////////////////////////
PVMFStatus PVMFOMXEncNode::ReleaseNodeMetadataKeys(PVMFMetadataList& , uint32 , uint32)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::ReleaseNodeMetadataKeys() called", iNodeTypeId));
    //nothing needed-- there's no dynamic allocation in this node's key list
    return PVMFSuccess;
}

// From PVMFMetadataExtensionInterface
/////////////////////////////////////////////////////////////////////////////
PVMFStatus PVMFOMXEncNode::ReleaseNodeMetadataValues(Oscl_Vector<PvmiKvp, OsclMemAllocator>& aValueList, uint32 start, uint32 end)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::ReleaseNodeMetadataValues() called", iNodeTypeId));

    if (aValueList.size() == 0 || start > end)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::ReleaseNodeMetadataValues() Invalid start/end index", iNodeTypeId));
        return PVMFErrArgument;
    }

    if (end >= aValueList.size())
    {
        end = aValueList.size() - 1;
    }

    for (uint32 i = start; i <= end; i++)
    {
        if (aValueList[i].key != NULL)
        {
            switch (GetValTypeFromKeyString(aValueList[i].key))
            {
                case PVMI_KVPVALTYPE_CHARPTR:
                    if (aValueList[i].value.pChar_value != NULL)
                    {
                        OSCL_ARRAY_DELETE(aValueList[i].value.pChar_value);
                        aValueList[i].value.pChar_value = NULL;
                    }
                    break;

                case PVMI_KVPVALTYPE_UINT32:
                case PVMI_KVPVALTYPE_UINT8:
                    // No memory to free for these valtypes
                    break;

                default:
                    // Should not get a value that wasn't created from here
                    break;
            }

            OSCL_ARRAY_DELETE(aValueList[i].key);
            aValueList[i].key = NULL;
        }
    }

    return PVMFSuccess;
}






PVMFStatus PVMFOMXEncNode::GetProfileAndLevel(PVMF_MPEGVideoProfileType& aProfile, PVMF_MPEGVideoLevelType& aLevel)
{

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::GetProfileAndLevel() In", iNodeTypeId));

    if (NULL == iOMXEncoder)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::GetProfileAndLevel() iEncoder is Null", iNodeTypeId));
        aProfile = PV_MPEG_VIDEO_RESERVED_PROFILE;
        aLevel  = PV_MPEG_VIDEO_LEVEL_UNKNOWN;
        return PVMFFailure;
    }

    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::GetProfileAndLevel() iEncoder is Null", iNodeTypeId));
    aProfile = PV_MPEG_VIDEO_RESERVED_PROFILE;
    aLevel  = PV_MPEG_VIDEO_LEVEL_UNKNOWN;
    // DV: FOR NOW, JUST RETURN FAILURE, WE DON'T SUPPORT THIS FEATURE YET
    return PVMFFailure;


}


/////////////////////////////////////////////////////////////////////////////
void PVMFOMXEncNode::LogDiagnostics()
{
    if (iDiagnosticsLogged == false)
    {
        iDiagnosticsLogged = true;
        PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iDiagnosticsLogger, PVLOGMSG_INFO, (0, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"));
        PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iDiagnosticsLogger, PVLOGMSG_INFO, (0, "PVMFOMXEncNode-%s - Number of Media Msgs Sent = %d", iNodeTypeId, iSeqNum));
        PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iDiagnosticsLogger, PVLOGMSG_INFO, (0, "PVMFOMXEncNode-%s - TS of last encoded msg = %d", iNodeTypeId, ConvertOMXTicksIntoTimestamp(iTimeStampOut)));
    }
}



//////////////////////////////////
/////EXTENSION INTERFACE
////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF bool PVMFOMXEncNode::SetNumLayers(uint32 aNumLayers)
{
    switch (iInterfaceState)
    {
        case EPVMFNodeStarted:
        case EPVMFNodePaused:
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
                            (0, "PVMFOMXEncNode-%s::SetNumLayers: Error iInterfaceState=%d", iNodeTypeId, iInterfaceState));
            return false;

        default:
            break;
    }

    if (aNumLayers > MAX_LAYER)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
                        (0, "PVMFOMXEncNode-%s::SetNumLayers: Error Max num layers is %d", iNodeTypeId, MAX_LAYER));
        return false;
    }

    iVideoEncodeParam.iNumLayer = aNumLayers;
    return true;
}

////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF bool PVMFOMXEncNode::SetOutputBitRate(uint32 aLayer, uint32 aBitRate)
{
    switch (iInterfaceState)
    {
        case EPVMFNodeStarted:
        case EPVMFNodePaused:
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::SetOutputBitRate: Error iInterfaceState=%d", iInterfaceState));
            return false;

        default:
            break;
    }

    if ((int32)aLayer >= iVideoEncodeParam.iNumLayer)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
                        (0, "PVMFOMXEncNode-%s::SetOutputBitRate: Error Invalid layer number", iNodeTypeId));
        return false;
    }

    iVideoEncodeParam.iBitRate[aLayer] = aBitRate;
    return true;
}

////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF bool PVMFOMXEncNode::SetOutputFrameSize(uint32 aLayer, uint32 aWidth, uint32 aHeight)
{
    switch (iInterfaceState)
    {
        case EPVMFNodeStarted:
        case EPVMFNodePaused:
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
                            (0, "PVMFOMXEncNode-%s::SetOutputFrameSize: Error iInterfaceState=%d", iNodeTypeId, iInterfaceState));
            return false;

        default:
            break;
    }

    if ((int32)aLayer >= iVideoEncodeParam.iNumLayer)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
                        (0, "PVMFOMXEncNode-%s::SetOutputFrameSize: Error Invalid layer number", iNodeTypeId));
        return false;
    }

    iVideoEncodeParam.iFrameWidth[aLayer] = aWidth;
    iVideoEncodeParam.iFrameHeight[aLayer] = aHeight;
    return true;
}

////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF bool PVMFOMXEncNode::SetOutputFrameRate(uint32 aLayer, OsclFloat aFrameRate)
{
    switch (iInterfaceState)
    {
        case EPVMFNodeStarted:
        case EPVMFNodePaused:
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
                            (0, "PVMFOMXEncNode-%s::SetOutputFrameRate: Error iInterfaceState=%d", iInterfaceState));
            return false;

        default:
            break;
    }

    if ((int32)aLayer >= iVideoEncodeParam.iNumLayer)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
                        (0, "PVMFOMXEncNode-%s::SetOutputFrameRate: Error Invalid layer number", iNodeTypeId));
        return false;
    }

    iVideoEncodeParam.iFrameRate[aLayer] = OSCL_STATIC_CAST(float, aFrameRate);
    return true;
}

////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF bool PVMFOMXEncNode::SetSegmentTargetSize(uint32 aLayer, uint32 aSizeBytes)
{
    OSCL_UNUSED_ARG(aLayer);

    switch (iInterfaceState)
    {
        case EPVMFNodeStarted:
        case EPVMFNodePaused:
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
                            (0, "PVMFOMXEncNode-%s::SetSegmentTargetSize: Error iInterfaceState=%d", iNodeTypeId, iInterfaceState));
            return false;

        default:
            break;
    }

    iVideoEncodeParam.iPacketSize = aSizeBytes;
    return true;
}

////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF bool PVMFOMXEncNode::SetRateControlType(uint32 aLayer, PVMFVENRateControlType aRateControl)
{
    OSCL_UNUSED_ARG(aLayer);

    switch (iInterfaceState)
    {
        case EPVMFNodeStarted:
        case EPVMFNodePaused:
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
                            (0, "PVMFOMXEncNode-%s::SetRateControlType: Error iInterfaceState=%d", iNodeTypeId, iInterfaceState));
            return false;

        default:
            break;
    }

    iVideoEncodeParam.iRateControlType = aRateControl;
    return true;
}

////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF bool PVMFOMXEncNode::SetDataPartitioning(bool aDataPartitioning)
{
    switch (iInterfaceState)
    {
        case EPVMFNodeStarted:
        case EPVMFNodePaused:
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
                            (0, "PVMFOMXEncNode-%s::SetDataPartitioning: Error iInterfaceState=%d", iNodeTypeId, iInterfaceState));
            return false;

        default:
            break;
    }

    iVideoEncodeParam.iDataPartitioning = aDataPartitioning;

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
                    (0, "PVMFOMXEncNode-%s::SetDataPartitioning Called", iNodeTypeId));

    return true;
}

////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF bool PVMFOMXEncNode::SetIFrameInterval(uint32 aIFrameInterval)
{
    switch (iInterfaceState)
    {
        case EPVMFNodeStarted:
        case EPVMFNodePaused:
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
                            (0, "PVMFOMXEncNode-%s::SetIFrameInterval: Error iInterfaceState=%d", iNodeTypeId, iInterfaceState));
            return false;

        default:
            break;
    }

    iVideoEncodeParam.iIFrameInterval = aIFrameInterval;
    return true;
}
////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF bool PVMFOMXEncNode::SetSceneDetection(bool aSCD)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFOMXEncNode-%s::SetSceneDetection to %d", iNodeTypeId, aSCD));


    switch (iInterfaceState)
    {
        case EPVMFNodeStarted:
        case EPVMFNodePaused:
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
                            (0, "PVMFOMXEncEncNode-%s::SetIFrameInterval: Error iInterfaceState=%d", iNodeTypeId, iInterfaceState));
            return false;

        default:
            break;
    }

    iVideoEncodeParam.iSceneDetection = aSCD;

    return true;
}
////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF bool PVMFOMXEncNode::SetRVLC(bool aRVLC)
{

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFOMXEncNode-%s::SetRVLC", iNodeTypeId));

    switch (iInterfaceState)
    {
        case EPVMFNodeStarted:
        case EPVMFNodePaused:
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
                            (0, "PVMFOMXEncEncNode-%s::SetRVLC: Error iInterfaceState=%d", iNodeTypeId, iInterfaceState));
            return false;

        default:
            break;
    }

    iVideoEncodeParam.iRVLCEnable = aRVLC;

    return true;
}

////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF bool PVMFOMXEncNode::GetVolHeader(OsclRefCounterMemFrag& aVolHeader)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFOMXEncNode-%s::GetVolHeader", iNodeTypeId));

#ifdef _TEST_AE_ERROR_HANDLING
    if (iErrorConfigHeader)
    {
        iInterfaceState = EPVMFNodeError;
    }
#endif
    switch (iInterfaceState)
    {
        case EPVMFNodeInitialized:
        case EPVMFNodePrepared:
        case EPVMFNodeStarted:
        case EPVMFNodePaused:
            break;

        default:
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
                            (0, "PVMFOMXEncNode-%s::GetVolHeader: Error - Wrong state", iNodeTypeId));
            return false;
    }

    if (iOutFormat != PVMF_MIME_M4V)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
                        (0, "PVMFOMXEncNode-%s::GetVolHeader: Error - VOL header only for M4V encode", iNodeTypeId));
        return false;
    }

    uint8 *ptr = (uint8 *) iVolHeader.getMemFragPtr();
    //If data partioning mode
    if (iVideoEncodeParam.iDataPartitioning == true)
    {
        ptr[iVolHeader.getMemFragSize() - 1] = 0x8F;
    }
    //else combined mode
    else
    {
        ptr[iVolHeader.getMemFragSize() - 1] = 0x1F;
    }

    aVolHeader = iVolHeader;

    return true;
}

////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF bool PVMFOMXEncNode::RequestIFrame()
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFOMXEncNode-%s::RequestIFrame", iNodeTypeId));

    switch (iInterfaceState)
    {
        case EPVMFNodeStarted:
        case EPVMFNodePaused:
            break;
        default:
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
                            (0, "PVMFOMXEncNode-%s::RequestIFrame: Error - Wrong state", iNodeTypeId));
            return false;
    }

    return true;
}

////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF bool PVMFOMXEncNode::SetCodec(PVMFFormatType aCodec)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFOMXEncNode-%s::SetCodec %s", iNodeTypeId, aCodec.getMIMEStrPtr()));

    if (SetCodecType(aCodec) == PVMFSuccess)
    {
        return true;
    }
    else
    {
        return false;
    }

}



PVMFStatus PVMFOMXEncNode::SetCodecType(PVMFFormatType aCodec)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFOMXEncNode-%s::SetCodecType: aCodec=%s", iNodeTypeId, aCodec.getMIMEStrPtr()));

    switch (iInterfaceState)
    {
        case EPVMFNodeStarted:
        case EPVMFNodePaused:
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
                            (0, "PVMFOMXEncNode-%s::SetCodecType: Error iInterfaceState=%d", iNodeTypeId, iInterfaceState));

            return PVMFErrInvalidState;
        default:
            break;
    }

    if (aCodec == PVMF_MIME_H2631998)
    {
        iOutFormat = PVMF_MIME_H2631998;
    }
    else if (aCodec == PVMF_MIME_H2632000)
    {
        iOutFormat = PVMF_MIME_H2632000;
    }
    else if (aCodec == PVMF_MIME_M4V)
    {
        iOutFormat = PVMF_MIME_M4V;
    }
    else if (aCodec == PVMF_MIME_H264_VIDEO_RAW ||
             aCodec == PVMF_MIME_H264_VIDEO_MP4)
    {
        iOutFormat = aCodec;
    }
    else if (aCodec == PVMF_MIME_AMR_IETF ||
             aCodec == PVMF_MIME_AMR_IF2 ||
             aCodec == PVMF_MIME_AMRWB_IETF)
    {
        iOutFormat = aCodec;
    }
    else if (aCodec == PVMF_MIME_ADTS ||
             aCodec == PVMF_MIME_ADIF ||
             aCodec == PVMF_MIME_MPEG4_AUDIO)
    {
        iOutFormat = aCodec;
    }
    else
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "PVMFOMXEncNode-%s::SetCodecType: ERROR Unsupported format aCodec=%s", iNodeTypeId, aCodec.getMIMEStrPtr()));

        return PVMFErrNotSupported;
    }

    return PVMFSuccess;
}

////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF bool PVMFOMXEncNode::SetFSIParam(uint8* aFSIBuff, int aFSIBuffLength)
{


    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
                    (0, "PVMFOMXEncNode-%s::SetFSIParam: Error- NOT IMPLEMENTED", iNodeTypeId));
    OSCL_UNUSED_ARG(aFSIBuff);
    OSCL_UNUSED_ARG(aFSIBuffLength);

    return true;
}



// The input format methods are called from the port
////////////////////////////////////////////////////////////////////////////
PVMFStatus PVMFOMXEncNode::SetInputFormat(PVMFFormatType aFormat)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFOMXEncNode-%s::SetInputFormat: aFormat=%s", iNodeTypeId, aFormat.getMIMEStrPtr()));

    switch (iInterfaceState)
    {
        case EPVMFNodeStarted:
        case EPVMFNodePaused:
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
                            (0, "PVMFOMXEncNode-%s::SetInputFormat: Error - iInterfaceState=%d", iNodeTypeId, iInterfaceState));
            return PVMFErrInvalidState;
        default:
            break;
    }

    iInFormat = aFormat;
    return PVMFSuccess;
}

////////////////////////////////////////////////////////////////////////////
PVMFStatus PVMFOMXEncNode::SetInputFrameSize(uint32 aWidth, uint32 aHeight, uint8 aFrmOrient)
{
    switch (iInterfaceState)
    {
        case EPVMFNodeStarted:
        case EPVMFNodePaused:
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
                            (0, "PVMFOMXEncNode-%s::SetInputFrameSize: Error iInterfaceState=%d", iNodeTypeId, iInterfaceState));
            return false;
        default:
            break;
    }

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFOMXEncNode-%s::SetInputFrameSize: aWidth=%d, aHeight=%d, aFrmOrient=%d", iNodeTypeId, aWidth, aHeight, aFrmOrient));

    iVideoInputFormat.iFrameWidth = aWidth;
    iVideoInputFormat.iFrameHeight = aHeight;
    iVideoInputFormat.iFrameOrientation = aFrmOrient;
    return true;
}

////////////////////////////////////////////////////////////////////////////
PVMFStatus PVMFOMXEncNode::SetInputFrameRate(OsclFloat aFrameRate)
{
    switch (iInterfaceState)
    {
        case EPVMFNodeStarted:
        case EPVMFNodePaused:
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
                            (0, "PVMFOMXEncNode-%s::SetInputFrameRate: Error iInterfaceState=%d", iNodeTypeId, iInterfaceState));
            return false;
        default:
            break;
    }

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFOMXEncNode-%s::SetInputFrameRate: aFrameRate=%d", iNodeTypeId, aFrameRate));

    iVideoInputFormat.iFrameRate = OSCL_STATIC_CAST(float, aFrameRate);
    iVideoEncodeParam.iNoFrameSkip = iVideoEncodeParam.iNoCurrentSkip = false;
    return true;
}

////////////////////////////////////////////////////////////////////////////
PVMFFormatType PVMFOMXEncNode::GetCodecType()
{
    return iOutFormat;
}

////////////////////////////////////////////////////////////////////////////
// DV: Note - for video - there is an uint32 arg
uint32 PVMFOMXEncNode::GetOutputBitRate(uint32 aLayer)
{
    if ((int32)aLayer >= iVideoEncodeParam.iNumLayer)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
                        (0, "PVMFOMXEncNode-%s::GetOutputBitRate: Error - Invalid layer number", iNodeTypeId));
        return 0;
    }

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFOMXEncNode-%s::GetOutputBitRate: =%d", iNodeTypeId, iVideoEncodeParam.iBitRate[aLayer]));

    return iVideoEncodeParam.iBitRate[aLayer];
}

////////////////////////////////////////////////////////////////////////////
OsclFloat PVMFOMXEncNode::GetOutputFrameRate(uint32 aLayer)
{
    if ((int32)aLayer >= iVideoEncodeParam.iNumLayer)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
                        (0, "PVMFOMXEncNode-%s::GetOutputFrameRate: Error Invalid layer number", iNodeTypeId));
        return 0;
    }

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFOMXEncNode-%s::GetOutputFrameRate: =%f", iNodeTypeId, (OsclFloat) iVideoEncodeParam.iFrameRate[aLayer]));

    return (OsclFloat)iVideoEncodeParam.iFrameRate[aLayer];
}

////////////////////////////////////////////////////////////////////////////
PVMFStatus PVMFOMXEncNode::GetOutputFrameSize(uint32 aLayer, uint32& aWidth, uint32& aHeight)
{
    if ((int32)aLayer >= iVideoEncodeParam.iNumLayer)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
                        (0, "PVMFOMXEncNode-%s::GetOutputFrameSize: Error Invalid layer number", iNodeTypeId));
        return PVMFFailure;
    }

    aWidth = iVideoEncodeParam.iFrameWidth[aLayer];
    aHeight = iVideoEncodeParam.iFrameHeight[aLayer];
    return PVMFSuccess;
}

////////////////////////////////////////////////////////////////////////////
uint32 PVMFOMXEncNode::GetIFrameInterval()
{
    return iVideoEncodeParam.iIFrameInterval;
}
/////////////////////////////////////////////////////////////////////////////

uint32 PVMFOMXEncNode::GetOutputSamplingRate()
{


    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFOMXEncNode-%s::GetOutputSamplingRate: =%d", iNodeTypeId, iAudioEncodeParam.iOutputSamplingRate));

    return (uint32) iAudioEncodeParam.iOutputSamplingRate;
}
/////////////////////////////////////////////////////////////////////////////

uint32 PVMFOMXEncNode::GetOutputNumChannels()
{


    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFOMXEncNode-%s::GetOutputNumChannels: =%d", iNodeTypeId, iAudioEncodeParam.iOutputNumChannels));

    return (uint32) iAudioEncodeParam.iOutputNumChannels;
}

/////////////////////////AMRENCInterfaceExtension //////////////////////////
OSCL_EXPORT_REF PVMFStatus PVMFOMXEncNode::SetOutputBitRate(PVMF_GSMAMR_Rate aBitRate)
{
    // this particular API is used only for AMR (NB or WB)
    // do some error checking - make sure that NB (i.e. WB) bitrates correspond to NB (i.e. WB) codec
    if ((iOutFormat == PVMF_MIME_AMR_IF2) ||
            (iOutFormat == PVMF_MIME_AMR_IETF)
       )
    {

        switch (aBitRate)
        {
            case GSM_AMR_4_75:
            case GSM_AMR_5_15:
            case GSM_AMR_5_90:
            case GSM_AMR_6_70:
            case GSM_AMR_7_40:
            case GSM_AMR_7_95:
            case GSM_AMR_10_2:
            case GSM_AMR_12_2:

                iAudioEncodeParam.iAMRBitrate = aBitRate;

                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                                (0, "PVMFOMXEncNode-%s::SetOutputBitRate() OK - %d", iNodeTypeId, aBitRate));

                return PVMFSuccess;

            case GSM_AMR_6_60: // AMR WB bitrates start here
            case GSM_AMR_8_85:
            case GSM_AMR_12_65:
            case GSM_AMR_14_25:
            case GSM_AMR_15_85:
            case GSM_AMR_18_25:
            case GSM_AMR_19_85:
            case GSM_AMR_23_05:
            case GSM_AMR_23_85:

                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                                (0, "PVMFOMXEncNode-%s::SetOutputBitRate() failed - %d", iNodeTypeId, aBitRate));

                return PVMFFailure;

            default:

                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                                (0, "PVMFOMXEncNode-%s::SetOutputBitRate() failed - %d", iNodeTypeId, aBitRate));

                return PVMFFailure;
        }
    }

    if (iOutFormat == PVMF_MIME_AMRWB_IETF)
    {
        switch (aBitRate)
        {
            case GSM_AMR_4_75:
            case GSM_AMR_5_15:
            case GSM_AMR_5_90:
            case GSM_AMR_6_70:
            case GSM_AMR_7_40:
            case GSM_AMR_7_95:
            case GSM_AMR_10_2:
            case GSM_AMR_12_2:

                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                                (0, "PVMFOMXEncNode-%s::SetOutputBitRate() failed - %d", iNodeTypeId, aBitRate));

                return PVMFFailure;

            case GSM_AMR_6_60: // AMR WB bitrates start here
            case GSM_AMR_8_85:
            case GSM_AMR_12_65:
            case GSM_AMR_14_25:
            case GSM_AMR_15_85:
            case GSM_AMR_18_25:
            case GSM_AMR_19_85:
            case GSM_AMR_23_05:
            case GSM_AMR_23_85:

                iAudioEncodeParam.iAMRBitrate = aBitRate;
                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                                (0, "PVMFOMXEncNode-%s::SetOutputBitRate() OK - %d", iNodeTypeId, aBitRate));

                return PVMFSuccess;

            default:

                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                                (0, "PVMFOMXEncNode-%s::SetOutputBitRate() failed - %d", iNodeTypeId, aBitRate));

                return PVMFFailure;
        }
    }

    return PVMFSuccess;
}

////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF PVMFStatus PVMFOMXEncNode::SetMaxNumOutputFramesPerBuffer(uint32 aNumOutputFrames)
{
    iAudioEncodeParam.iMaxNumOutputFramesPerBuffer = aNumOutputFrames;
    return PVMFSuccess;
}

////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF PVMFStatus PVMFOMXEncNode::SetOutputBitRate(uint32 aBitRate)
{
    // this API is used for Non-AMR codecs
    iAudioEncodeParam.iOutputBitrate = aBitRate;
    return PVMFSuccess;
}

////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF PVMFStatus PVMFOMXEncNode::SetOutputNumChannel(uint32 aNumChannels)
{

    iAudioEncodeParam.iOutputNumChannels = aNumChannels;
    return PVMFSuccess;
}

////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF PVMFStatus PVMFOMXEncNode::SetOutputSamplingRate(uint32 aSamplingRate)
{
    iAudioEncodeParam.iOutputSamplingRate = aSamplingRate;
    return PVMFSuccess;
}


////////////////////////////////////////////////////////////////////////////
PVMFStatus PVMFOMXEncNode::SetInputSamplingRate(uint32 aSamplingRate)
{
    // do some error checking - make sure the input sampling rate is 8khz (i.e. 16khz) for AMRNB (i.e. WB)
    if (((iOutFormat == PVMF_MIME_AMR_IF2) ||
            (iOutFormat == PVMF_MIME_AMR_IETF)) &&
            (aSamplingRate != 8000)
       )
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                        (0, "PVMFOMXEncNode-%s::SetInputBitsSamplingRate() failed - %d", iNodeTypeId, aSamplingRate));

        return PVMFFailure;
    }

    if ((iOutFormat == PVMF_MIME_AMRWB_IETF) && (aSamplingRate != 16000))
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                        (0, "PVMFOMXEncNode-%s::SetInputBitsSamplingRate() failed - %d", iNodeTypeId, aSamplingRate));

        return PVMFFailure;
    }

    iAudioInputFormat.iInputSamplingRate = aSamplingRate;

    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFOMXEncNode-%s::SetInputBitsSamplingRate() OK setting OutputSamplingRate as well - %d", iNodeTypeId, aSamplingRate));

    // set output as well
    iAudioEncodeParam.iOutputSamplingRate = aSamplingRate;
    return PVMFSuccess;
}

////////////////////////////////////////////////////////////////////////////
PVMFStatus PVMFOMXEncNode::SetInputBitsPerSample(uint32 aBitsPerSample)
{
    if (aBitsPerSample != 16)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                        (0, "PVMFOMXEncNode-%s::SetInputBitsPerSample() failed - %d", iNodeTypeId, aBitsPerSample));

        return PVMFErrNotSupported;
    }

    iAudioInputFormat.iInputBitsPerSample = aBitsPerSample;

    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFOMXEncNode-%s::SetInputBitsPerSample() OK - %d", iNodeTypeId, aBitsPerSample));

    return PVMFSuccess;
}


////////////////////////////////////////////////////////////////////////////
PVMFStatus PVMFOMXEncNode::SetInputNumChannels(uint32 aNumChannels)
{
    // do some error checking - make sure the number of INPUT channels is 1 for AMR (NB or WB)

    if (((iOutFormat == PVMF_MIME_AMR_IF2) ||
            (iOutFormat == PVMF_MIME_AMR_IETF) ||
            (iOutFormat == PVMF_MIME_AMRWB_IETF)) &&
            (aNumChannels > 1)
       )
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                        (0, "PVMFOMXEncNode-%s::SetInputNumChannels() failed - %d", iNodeTypeId, aNumChannels));
        return PVMFFailure;
    }

    iAudioInputFormat.iInputNumChannels = aNumChannels;

    //set output as well
    iAudioEncodeParam.iOutputNumChannels = aNumChannels;
    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFOMXEncNode-%s::SetInputNumChannels() OK - %d", iNodeTypeId, aNumChannels));

    return PVMFSuccess;
}

////////////////////////////////////////////////////////////////////////////
uint32 PVMFOMXEncNode::GetOutputBitRate()
{
    if ((iOutFormat == PVMF_MIME_AMR_IF2) ||
            (iOutFormat == PVMF_MIME_AMR_IETF) ||
            (iOutFormat == PVMF_MIME_AMRWB_IETF)
       )
    {

        switch (iAudioEncodeParam.iAMRBitrate)
        {
            case GSM_AMR_4_75:
                return 4750;
            case GSM_AMR_5_15:
                return 5150;
            case GSM_AMR_5_90:
                return 5900;
            case GSM_AMR_6_70:
                return 6700;
            case GSM_AMR_7_40:
                return 7400;
            case GSM_AMR_7_95:
                return 7950;
            case GSM_AMR_10_2:
                return 10200;
            case GSM_AMR_12_2:
                return 12200;
            case GSM_AMR_6_60: // AMR WB bitrates start here
                return 6600;
            case GSM_AMR_8_85:
                return 8850;
            case GSM_AMR_12_65:
                return 12650;
            case GSM_AMR_14_25:
                return 14250;
            case GSM_AMR_15_85:
                return 15850;
            case GSM_AMR_18_25:
                return 18250;
            case GSM_AMR_19_85:
                return 19850;
            case GSM_AMR_23_05:
                return 23050;
            case GSM_AMR_23_85:
                return 23850;
            default:
                return 0;
        }
    }
    else
    {
        return iAudioEncodeParam.iOutputBitrate;
    }
}


///////////////////////// FROM CAP CONFIG IN VIDEO ENC NODE ////////////////////
PVMFStatus PVMFOMXEncNode::GetConfigParameter(PvmiKvp*& aParameters, int& aNumParamElements, int32 aIndex, PvmiKvpAttr aReqattr)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::GetConfigParameter() In", iNodeTypeId));

    aNumParamElements = 0;

    // Allocate memory for the KVP
    aParameters = (PvmiKvp*)oscl_malloc(sizeof(PvmiKvp));
    if (NULL == aParameters)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::GetConfigParameter() Memory allocation for KVP failed", iNodeTypeId));
        return PVMFErrNoMemory;
    }
    oscl_memset(aParameters, 0, sizeof(PvmiKvp));
    // Allocate memory for the key string in KVP
    PvmiKeyType memblock = (PvmiKeyType)oscl_malloc(PVOMXENCNODECONFIG_KEYSTRING_SIZE * sizeof(char));
    if (NULL == memblock)
    {
        oscl_free(aParameters);
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::GetConfigParameter() Memory allocation for key string failed", iNodeTypeId));
        return PVMFErrNoMemory;
    }
    oscl_strset(memblock, 0, PVOMXENCNODECONFIG_KEYSTRING_SIZE * sizeof(char));
    // Assign the key string buffer to KVP
    aParameters[0].key = memblock;

    // Copy the key string
    if (iInFormat == PVMF_MIME_PCM16)
    {
        // Copy the key string
        oscl_strncat(aParameters[0].key, _STRLIT_CHAR("x-pvmf/encoder/audio/"), 21);
        oscl_strncat(aParameters[0].key, PVOMXEncNodeConfigBaseKeys[aIndex].iString, oscl_strlen(PVOMXEncNodeConfigBaseKeys[aIndex].iString));
        oscl_strncat(aParameters[0].key, _STRLIT_CHAR(";type=value;valtype="), 20);
    }
    else
    {
        oscl_strncat(aParameters[0].key, _STRLIT_CHAR("x-pvmf/encoder/video/"), 21);
        oscl_strncat(aParameters[0].key, PVOMXEncNodeConfigBaseKeys[aIndex].iString, oscl_strlen(PVOMXEncNodeConfigBaseKeys[aIndex].iString));
        oscl_strncat(aParameters[0].key, _STRLIT_CHAR(";type=value;valtype="), 20);
    }
    switch (PVOMXEncNodeConfigBaseKeys[aIndex].iValueType)
    {
        case PVMI_KVPVALTYPE_BITARRAY32:
            oscl_strncat(aParameters[0].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_BITARRAY32_STRING), oscl_strlen(PVMI_KVPVALTYPE_BITARRAY32_STRING));
            break;

        case PVMI_KVPVALTYPE_KSV:
            oscl_strncat(aParameters[0].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_KSV_STRING), oscl_strlen(PVMI_KVPVALTYPE_KSV_STRING));
            break;

        case PVMI_KVPVALTYPE_BOOL:
            oscl_strncat(aParameters[0].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_BOOL_STRING), oscl_strlen(PVMI_KVPVALTYPE_BOOL_STRING));
            break;

        case PVMI_KVPVALTYPE_INT32:
            if (PVMI_KVPATTR_CUR == aReqattr)
            {
                oscl_strncat(aParameters[0].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_INT32_STRING), oscl_strlen(PVMI_KVPVALTYPE_RANGE_UINT32_STRING));
            }
            break;
        case PVMI_KVPVALTYPE_UINT32:
        default:
            if (PVMI_KVPATTR_CAP == aReqattr)
            {
                oscl_strncat(aParameters[0].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_RANGE_UINT32_STRING), oscl_strlen(PVMI_KVPVALTYPE_RANGE_UINT32_STRING));
            }
            else
            {
                oscl_strncat(aParameters[0].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_UINT32_STRING), oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING));
            }
            break;
    }
    aParameters[0].key[PVOMXENCNODECONFIG_KEYSTRING_SIZE-1] = 0;

    // Copy the requested info
    switch (aIndex)
    {

        case SAMPLING_RATE: // "sampling_rate"
            if (PVMI_KVPATTR_CUR == aReqattr)
            {
                // get the parameter here
                aParameters[0].value.uint32_value = iAudioInputFormat.iInputSamplingRate;

            }
            else if (PVMI_KVPATTR_DEF == aReqattr)
            {
                // Return default
                aParameters[0].value.uint32_value = PVMF_AMRENC_DEFAULT_SAMPLING_RATE;

            }
            else
            {
                // Return capability
            }
            break;

        case CHANNELS:  // "channels"

            if (PVMI_KVPATTR_CUR == aReqattr)
            {
                // get the par
                aParameters[0].value.uint32_value = iAudioInputFormat.iInputNumChannels;
            }
            else if (PVMI_KVPATTR_DEF == aReqattr)
            {
                // Return default
                aParameters[0].value.uint32_value = PVMF_AMRENC_DEFAULT_NUM_CHANNELS;
            }
            else
            {
                // Return capability
            }
            break;

        case ENCODING_MODE: // "encoding_mode"
            if (PVMI_KVPATTR_CUR == aReqattr)
            {
                // Return current value
                aParameters[0].value.uint32_value = iVideoEncodeParam.iEncMode;
            }
            else if (PVMI_KVPATTR_DEF == aReqattr)
            {
                // Return default
                aParameters[0].value.uint32_value = EI_ENCMODE_RECORDER;//default setting
            }
            else
            {
                // Return capability
            }
            break;

#ifdef _TEST_AE_ERROR_HANDLING
        case ERROR_START_INIT://error_start_init
            if (PVMI_KVPATTR_CUR == aReqattr)
            {
                // Return current value
                aParameters[0].value.bool_value = iErrorHandlingInit;
            }
            else if (PVMI_KVPATTR_DEF == aReqattr)
            {
                // Return default
                aParameters[0].value.bool_value = true;
            }
            else
            {
                // Return capability
            }
            break;
        case ERROR_ENCODE://error_encode
            if (PVMI_KVPATTR_CUR == aReqattr)
            {
                // Return current value
                aParameters[0].value.uint32_value = iErrorHandlingEncodeCount;
            }
            else if (PVMI_KVPATTR_DEF == aReqattr)
            {
                // Return default
                aParameters[0].value.uint32_value = 1;
            }
            else
            {
                // Return capability
            }
            break;

#endif

        default:
            // Invalid index
            oscl_free(aParameters[0].key);
            oscl_free(aParameters);
            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::GetConfigParameter() Invalid index to video enc node parameter", iNodeTypeId));
            return PVMFErrNotSupported;
    }

    aNumParamElements = 1;

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::GetConfigParameter() Out", iNodeTypeId));
    return PVMFSuccess;
}

PVMFStatus PVMFOMXEncNode::VerifyAndSetConfigParameter(PvmiKvp& aParameter, bool aSetParam)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::VerifyAndSetConfigParameter() In", iNodeTypeId));

    // Determine the valtype
    PvmiKvpValueType keyvaltype = GetValTypeFromKeyString(aParameter.key);
    if (PVMI_KVPVALTYPE_UNKNOWN == keyvaltype)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::VerifyAndSetConfigParameter() Valtype in key string unknown", iNodeTypeId));
        return PVMFErrNotSupported;
    }
    // Retrieve the fourth component from the key string
    char* compstr = NULL;
    pv_mime_string_extract_type(3, aParameter.key, compstr);

    int32 enccomp4ind;
    for (enccomp4ind = 0; enccomp4ind < PVOMXENCNODECONFIG_BASE_NUMKEYS; ++enccomp4ind)
    {
        // Go through each component string at 4th level
        if (pv_mime_strcmp(compstr, (char*)(PVOMXEncNodeConfigBaseKeys[enccomp4ind].iString)) >= 0)
        {
            // Break out of the for loop
            break;
        }
    }

    if (PVOMXENCNODECONFIG_BASE_NUMKEYS <= enccomp4ind)
    {
        // Match couldn't be found or non-leaf node specified
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::VerifyAndSetConfigParameter() Unsupported key or non-leaf node", iNodeTypeId));
        return PVMFErrNotSupported;
    }

    // Verify the valtype
    if (keyvaltype != PVOMXEncNodeConfigBaseKeys[enccomp4ind].iValueType)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::VerifyAndSetConfigParameter() Valtype does not match for key", iNodeTypeId));
        return PVMFErrNotSupported;
    }

    switch (enccomp4ind)
    {


        case SAMPLING_RATE: // "sampling_rate"
            // Change the parameter
            if (aSetParam)
            {
                // set the parameter here
                iAudioInputFormat.iInputSamplingRate = aParameter.value.uint32_value;
                iAudioEncodeParam.iOutputSamplingRate = aParameter.value.uint32_value;
            }
            break;

        case CHANNELS:  // "channels"
            // change the parameter
            if (aSetParam)
            {
                // set the parameter here
                iAudioInputFormat.iInputNumChannels = aParameter.value.uint32_value;
                iAudioEncodeParam.iOutputNumChannels = aParameter.value.uint32_value;
            }
            break;
        case ENCODING_MODE: // "encoding_mode"
            // change the parameter
            if (aSetParam)
            {
                iVideoEncodeParam.iEncMode = (EncEncodingMode)aParameter.value.uint32_value;
            }
            break;



#ifdef _TEST_AE_ERROR_HANDLING
        case ERROR_START_INIT: // "error_start_init"
            // change the parameter
            if (aSetParam)
            {
                iErrorHandlingInit = aParameter.value.bool_value;
            }
            break;
        case ERROR_ENCODE: // "error_avcencode"
            // change the parameter
            if (aSetParam)
            {

                char* paramstr = NULL;
                OSCL_HeapString<OsclMemAllocator> mode1 = "mode=duration";
                OSCL_HeapString<OsclMemAllocator> mode2 = "mode=frames";

                if (pv_mime_string_parse_param(aParameter.key, mode1.get_str(), paramstr) > 0)
                {
                    iErrorEncodeFlag = 1;
                    iErrorHandlingEncodeCount = aParameter.value.uint32_value;

                }

                else if (pv_mime_string_parse_param(aParameter.key, mode2.get_str(), paramstr) > 0)
                {
                    iErrorEncodeFlag = 2;
                    iErrorHandlingEncodeCount = aParameter.value.uint32_value;

                }
            }
            break;
        case ERROR_NODE_CMD: //"error-node-cmd"
            if (aSetParam)
            {
                iErrorNodeCmd = aParameter.value.uint32_value;
            }
            break;
        case ERROR_CONFIG_HEADER:
            if (aSetParam)
            {
                iErrorConfigHeader = aParameter.value.bool_value;
            }
            break;
        case ERROR_DATAPATH_STALL:
            if (aSetParam)
            {
                iErrorDataPathStall = aParameter.value.uint32_value;
            }
            break;
#endif

        default:
            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::VerifyAndSetConfigParameter() Invalid index for video enc node parameter", iNodeTypeId));
            return PVMFErrNotSupported;
    }

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::VerifyAndSetConfigParameter() Out", iNodeTypeId));
    return PVMFSuccess;
}

//void PVMFOMXEncNode::setParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters, int aNumElements, PvmiKvp*& aRetKVP)
void PVMFOMXEncNode::DoCapConfigSetParameters(PvmiKvp* aParameters, int aNumElements, PvmiKvp*& aRetKVP)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::DoCapConfigSetParameters()", iNodeTypeId));
    //OSCL_UNUSED_ARG(aSession);

    if (NULL == aParameters || aNumElements < 1)
    {
        if (aParameters)
        {
            aRetKVP = aParameters;
        }
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::DoCapConfigSetParameters() Passed in parameter invalid", iNodeTypeId));
        return;
    }

    // Go through each parameter
    for (int32 paramind = 0; paramind < aNumElements; ++paramind)
    {
        // Count the number of components and parameters in the key
        int compcount = pv_mime_string_compcnt(aParameters[paramind].key);
        // Retrieve the first component from the key string
        char* compstr = NULL;
        pv_mime_string_extract_type(0, aParameters[paramind].key, compstr);


        if ((
                    (pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/encoder/video")) < 0) &&
                    (pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/encoder/audio")) < 0)
                ) || (compcount < 4))
        {
            // First 3 components should be "x-pvmf/encoder/video" or "x-pvmf/encoder/audio" and there must
            // be at least 4 components
            aRetKVP = &aParameters[paramind];
            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::DoCapConfigSetParameters() Unsupported key", iNodeTypeId));
            return;
        }

        // check if audio parameters are asked from video enc instance or vice versa
        if (((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/encoder/video")) > 0) && (iInFormat == PVMF_MIME_PCM16)) ||
                ((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/encoder/audio")) > 0) && (iInFormat != PVMF_MIME_PCM16))
           )
        {

            aRetKVP = &aParameters[paramind];
            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::DoCapConfigSetParameters() Unsupported key", iNodeTypeId));
            return;
        }

        if (4 == compcount)
        {
            // Verify and set the passed-in video enc node setting
            PVMFStatus retval = VerifyAndSetConfigParameter(aParameters[paramind], true);
            if (PVMFSuccess != retval)
            {
                aRetKVP = &aParameters[paramind];
                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::DoCapConfigSetParameters() Setting parameter %d failed", iNodeTypeId, paramind));
                return;
            }
        }

        else
        {
            // Do not support more than 4 components right now
            aRetKVP = &aParameters[paramind];
            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::DoCapConfigSetParameters() Unsupported key", iNodeTypeId));
            return;
        }
    }
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::DoCapConfigSetParameters() Out", iNodeTypeId));
}


//PVMFStatus PVMFOMXEncNode::getParametersSync(PvmiMIOSession aSession, PvmiKeyType aIdentifier, PvmiKvp*& aParameters, int& aNumParamElements, PvmiCapabilityContext aContext)
PVMFStatus PVMFOMXEncNode::DoCapConfigGetParametersSync(PvmiKeyType aIdentifier, PvmiKvp*& aParameters, int& aNumParamElements, PvmiCapabilityContext aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::DoCapConfigGetParametersSync()", iNodeTypeId));
    //OSCL_UNUSED_ARG(aSession);
    OSCL_UNUSED_ARG(aContext);

    // Initialize the output parameters
    aNumParamElements = 0;
    aParameters = NULL;

    // Count the number of components and parameters in the key
    int compcount = pv_mime_string_compcnt(aIdentifier);
    // Retrieve the first component from the key string
    char* compstr = NULL;
    pv_mime_string_extract_type(0, aIdentifier, compstr);

    if ((
                (pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/encoder/video")) < 0) &&
                (pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/encoder/audio")) < 0)
            ) || (compcount < 4))
    {
        // First 3 components should be "x-pvmf/encoder/video" or  "x-pvmf/encoder/audio" and there must
        // be at least 4 components
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::DoCapConfigGetParametersSync() Invalid key string", iNodeTypeId));
        return PVMFErrNotSupported;
    }

    // check if audio parameters are asked from video enc instance or vice versa
    if (((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/encoder/video")) > 0) && (iInFormat == PVMF_MIME_PCM16)) ||
            ((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/encoder/audio")) > 0) && (iInFormat != PVMF_MIME_PCM16))
       )
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::DoCapConfigGetParameters() Unsupported key", iNodeTypeId));
        return PVMFErrNotSupported;
    }

    // Retrieve the fourth component from the key string
    pv_mime_string_extract_type(3, aIdentifier, compstr);

    for (int32 enccomp4ind = 0; enccomp4ind < PVOMXENCNODECONFIG_BASE_NUMKEYS; ++enccomp4ind)
    {
        // Go through each video enc component string at 4th level
        if (pv_mime_strcmp(compstr, (char*)(PVOMXEncNodeConfigBaseKeys[enccomp4ind].iString)) >= 0)
        {
            if (4 == compcount)
            {
                // Determine what is requested
                PvmiKvpAttr reqattr = GetAttrTypeFromKeyString(aIdentifier);
                if (PVMI_KVPATTR_UNKNOWN == reqattr)
                {
                    reqattr = PVMI_KVPATTR_CUR;
                }

                // Return the requested info
                PVMFStatus retval = GetConfigParameter(aParameters, aNumParamElements, enccomp4ind, reqattr);
                if (PVMFSuccess != retval)
                {
                    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::DoCapConfigGetParametersSync() Retrieving video enc node parameter failed", iNodeTypeId));
                    return retval;
                }
            }
            else
            {
                // Right now videoenc node doesn't support more than 4 components
                // for this sub-key string so error out
                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::DoCapConfigGetParametersSync() Unsupported key", iNodeTypeId));
                return PVMFErrNotSupported;
            }
        }
    }

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::DoCapConfigGetParametersSync() Out", iNodeTypeId));
    if (aNumParamElements == 0)
    {
        // If no one could get the parameter, return error
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::DoCapConfigGetParametersSync() Unsupported key", iNodeTypeId));
        return PVMFFailure;
    }
    else
    {
        return PVMFSuccess;
    }
}

//PVMFStatus PVMFOMXEncNode::releaseParameters(PvmiMIOSession aSession, PvmiKvp* aParameters, int aNumElements)
PVMFStatus PVMFOMXEncNode::DoCapConfigReleaseParameters(PvmiKvp* aParameters, int aNumElements)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::releaseParameters()", iNodeTypeId));
    //OSCL_UNUSED_ARG(aSession);

    if (aParameters == NULL || aNumElements < 1)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::DoCapConfigReleaseParameters() KVP list is NULL or number of elements is 0", iNodeTypeId));
        return PVMFErrArgument;
    }

    // Count the number of components and parameters in the key
    int compcount = pv_mime_string_compcnt(aParameters[0].key);
    // Retrieve the first component from the key string
    char* compstr = NULL;
    pv_mime_string_extract_type(0, aParameters[0].key, compstr);

    if ((
                (pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/encoder/video")) < 0) &&
                (pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/encoder/audio")) < 0)
            ) || (compcount < 3))
    {
        // First 3 component should be "x-pvmf/encoder/video" or "x-pvmf/encoder/audio" and there must
        // be at least three components
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::DoCapConfigReleaseParameters() Unsupported key", iNodeTypeId));
        return PVMFErrNotSupported;
    }

    // check if audio parameters are asked from video enc instance or vice versa
    if (((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/encoder/video")) > 0) && (iInFormat == PVMF_MIME_PCM16)) ||
            ((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/encoder/audio")) > 0) && (iInFormat != PVMF_MIME_PCM16))
       )
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::DoCapConfigReleaseParameters() Unsupported key", iNodeTypeId));
        return PVMFErrNotSupported;
    }

    // Retrieve the third component from the key string
    pv_mime_string_extract_type(2, aParameters[0].key, compstr);

    // Go through each KVP and release memory for value if allocated from heap
    for (int32 ii = 0; ii < aNumElements; ++ii)
    {
        // Next check if it is a value type that allocated memory
        PvmiKvpType kvptype = GetTypeFromKeyString(aParameters[ii].key);
        if (PVMI_KVPTYPE_VALUE == kvptype || PVMI_KVPTYPE_UNKNOWN == kvptype)
        {
            PvmiKvpValueType keyvaltype = GetValTypeFromKeyString(aParameters[ii].key);
            if (PVMI_KVPVALTYPE_UNKNOWN == keyvaltype)
            {
                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::DoCapConfigReleaseParameters() Valtype not specified in key string", iNodeTypeId));
                return PVMFErrNotSupported;
            }

            if (PVMI_KVPVALTYPE_CHARPTR == keyvaltype && NULL != aParameters[ii].value.pChar_value)
            {
                oscl_free(aParameters[ii].value.pChar_value);
                aParameters[ii].value.pChar_value = NULL;
            }
            else if (keyvaltype == PVMI_KVPVALTYPE_KSV && NULL != aParameters[ii].value.key_specific_value)
            {
                oscl_free(aParameters[ii].value.key_specific_value);
                aParameters[ii].value.key_specific_value = NULL;
            }
            else if (PVMI_KVPVALTYPE_RANGE_UINT32 == keyvaltype && NULL != aParameters[ii].value.key_specific_value)
            {
                range_uint32* rui32 = (range_uint32*)aParameters[ii].value.key_specific_value;
                aParameters[ii].value.key_specific_value = NULL;
                oscl_free(rui32);
            }
            // @TODO Add more types if video enc node starts returning more types
        }
    }

    // Video enc node allocated its key strings in one chunk so just free the first key string ptr
    oscl_free(aParameters[0].key);

    // Free memory for the parameter list
    oscl_free(aParameters);
    aParameters = NULL;

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::DoCapConfigReleaseParameters() Out", iNodeTypeId));
    return PVMFSuccess;
}


//PVMFStatus PVMFOMXEncNode::verifyParametersSync (PvmiMIOSession aSession, PvmiKvp* aParameters, int aNumElements)
PVMFStatus PVMFOMXEncNode::DoCapConfigVerifyParameters(PvmiKvp* aParameters, int aNumElements)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::DoCapConfigVerifyParameters()", iNodeTypeId));
    //OSCL_UNUSED_ARG(aSession);

    if (NULL == aParameters || aNumElements < 1)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::DoCapConfigVerifyParameters() Passed in parameter invalid", iNodeTypeId));
        return PVMFErrArgument;
    }

    // Go through each parameter
    for (int32 paramind = 0; paramind < aNumElements; ++paramind)
    {
        // Count the number of components and parameters in the key
        int compcount = pv_mime_string_compcnt(aParameters[paramind].key);
        // Retrieve the first component from the key string
        char* compstr = NULL;
        pv_mime_string_extract_type(0, aParameters[paramind].key, compstr);

        if (
            ((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/encoder/video")) < 0) &&
             (pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/encoder/audio")) < 0)
            ) || compcount < 3)
        {
            // First 3 components should be "x-pvmf/encoder/video" or
            // "x-pvmf/enoder/audio" and there must
            // be at least 3 components

            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::DoCapConfigVerifyParameters() Unsupported key", iNodeTypeId));
            return PVMFErrNotSupported;
        }

        // check if audio parameters are asked from video enc instance or vice versa
        if (((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/encoder/video")) > 0) && (iInFormat == PVMF_MIME_PCM16)) ||
                ((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/encoder/audio")) > 0) && (iInFormat != PVMF_MIME_PCM16))
           )
        {
            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::DoCapConfigVerifyParameters() Unsupported key", iNodeTypeId));
            return PVMFErrNotSupported;
        }

        if (4 == compcount)
        {
            // Verify and set the passed-in video enc node setting
            PVMFStatus retval = VerifyAndSetConfigParameter(aParameters[paramind], false);
            if (retval != PVMFSuccess)
            {
                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::DoCapConfigVerifyParameters() Setting parameter %d failed", iNodeTypeId, paramind));
                return retval;
            }
        }
        else
        {
            // Do not support more than 4 components right now
            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::DoCapConfigVerifyParameters() Unsupported key", iNodeTypeId));
            return PVMFErrNotSupported;
        }
    }

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::DoCapConfigVerifyParameters() Out", iNodeTypeId));
    return PVMFSuccess;

}

int32 PVMFOMXEncNode::PushBackKeyVal(Oscl_Vector<PvmiKvp, OsclMemAllocator>*& aValueListPtr, PvmiKvp &aKeyVal)
{
    int32 leavecode = 0;
    OSCL_TRY(leavecode, (*aValueListPtr).push_back(aKeyVal));
    return leavecode;
}

int32 PVMFOMXEncNode::Push_Back_MetadataKeys(const char* aMetadataKey)
{
    int32 leavecode = 0;
    OSCL_TRY(leavecode, iAvailableMetadataKeys.push_back(aMetadataKey));
    return leavecode;
}

int32 PVMFOMXEncNode::Push_Back_MetadataKeys(PVMFMetadataList *&aKeylistptr, uint32 aLcv)
{
    int32 leavecode = 0;
    OSCL_TRY(leavecode, aKeylistptr->push_back(iAvailableMetadataKeys[aLcv]));
    return leavecode;
}

int32 PVMFOMXEncNode::CreateNewArray(char*& aPtr, int32 aLen)
{
    int32 leavecode = 0;
    OSCL_TRY(leavecode,
             aPtr = OSCL_ARRAY_NEW(char, aLen););
    return leavecode;
}

int32 PVMFOMXEncNode::MemAllocate(OsclAny *&aPtr, OsclMemPoolFixedChunkAllocator *aMemPool, uint32 aAllocSize)
{
    uint32 errcode = 0;
    OSCL_TRY(errcode, aPtr = (OsclAny *) aMemPool->allocate(aAllocSize));
    return errcode;
}

bool PVMFOMXEncNode::ParseFullAVCFramesIntoNALs(OMX_BUFFERHEADERTYPE* aOutputBuffer)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVMFOMXEncNode-%s : ParseFullAVCFramesIntoNALs IN", iNodeTypeId));

    if (iOMXComponentUsesNALStartCodes && !(aOutputBuffer->nFlags & OMX_BUFFERFLAG_EXTRADATA))
    {
        OMX_U32 offset = aOutputBuffer->nOffset;
        OMX_U32 length = aOutputBuffer->nFilledLen;
        OMX_U8* pBuffer = aOutputBuffer->pBuffer + offset;
        OMX_U8* pCurrNAL;
        OMX_U32 bytesConsumed;
        int32 nalSize;

        iNumNALs = 0;

        while (length > 0)
        {
            nalSize = length;

            if (false == AVCAnnexBGetNALUnit(pBuffer, &pCurrNAL, &nalSize, false))
            {
                break;
            }

            bytesConsumed = nalSize + (int32)(pCurrNAL - pBuffer);
            length -= bytesConsumed;
            pBuffer += bytesConsumed;

            if ((iNALSizeArrayMaxElems > iNumNALs) && (iNALSizeArray != NULL))
            {
                iNALSizeArray[iNumNALs] = nalSize;
                iNALPtrArray[iNumNALs] = (uint8*)pCurrNAL; /* need store NAL ptrs since start code can be either 4 bytes or 3 bytes */
                iNumNALs++;
            }
            else
            {
                iNumNALs++;

                // count the number of NALs in the buffer
                while (length > 0)
                {
                    nalSize = length;

                    if (false == AVCAnnexBGetNALUnit(pBuffer, &pCurrNAL, &nalSize, false))
                    {
                        break;
                    }

                    bytesConsumed = nalSize + (int32)(pCurrNAL - pBuffer);
                    length -= bytesConsumed;
                    pBuffer += bytesConsumed;

                    iNumNALs++;
                }

                // reassign alloc size to new max.
                iNALSizeArrayMaxElems = iNumNALs;

                // free memory and then reallocate
                if (iNALSizeArray != NULL)
                {
                    oscl_free(iNALSizeArray);
                }
                iNALSizeArray = (uint32*) oscl_malloc(sizeof(uint32) * iNALSizeArrayMaxElems);

                if (iNALPtrArray != NULL)
                {
                    oscl_free(iNALPtrArray);
                }
                iNALPtrArray = (uint8**) oscl_malloc(sizeof(uint8*) * iNALSizeArrayMaxElems);

                // reset parameters and start over
                iNumNALs = 0;
                length = aOutputBuffer->nFilledLen;
                pBuffer = aOutputBuffer->pBuffer + offset;

                if (iNALSizeArray == NULL || iNALPtrArray == NULL)
                {
                    iNALSizeArrayMaxElems = 0;

                    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVMFOMXEncNode-%s : ParseFullAVCFramesIntoNALs ERROR - Out of Memory", iNodeTypeId));
                    return false;
                }
            }
        }

        if (iNumNALs <= 0)
        {
            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVMFOMXEncNode-%s : ParseFullAVCFramesIntoNALs ERROR", iNodeTypeId));
            return false;
        }
    }
    else if (aOutputBuffer->nFlags & OMX_BUFFERFLAG_EXTRADATA)
    {
        // get extra data from end of buffer
        OMX_OTHER_EXTRADATATYPE *pExtra;
        OMX_U32 offset = aOutputBuffer->nOffset + aOutputBuffer->nFilledLen;
        OMX_U32 allocLen = aOutputBuffer->nAllocLen;
        OMX_U8* pTemp = aOutputBuffer->pBuffer + offset;

        // align
        pExtra = (OMX_OTHER_EXTRADATATYPE *)(((OMX_U32) pTemp + 3) & ~3);
        offset += (OMX_U32) pExtra - (OMX_U32) pTemp;

        while (pExtra->eType != OMX_ExtraDataNone)
        {
            if (pExtra->eType == OMX_ExtraDataNALSizeArray)
            {
                iNumNALs = pExtra->nDataSize >> 2;
                if ((iNALSizeArrayMaxElems > iNumNALs) && (iNALSizeArray != NULL))
                {
                    oscl_memcpy(iNALSizeArray, ((OMX_U8*)pExtra + 20), pExtra->nDataSize); // 20 is the size of the extra data struct (minus data hint)
                }
                else
                {
                    // reassign alloc size to new max.
                    iNALSizeArrayMaxElems = iNumNALs;

                    // free memory and then reallocate
                    if (iNALSizeArray != NULL)
                    {
                        oscl_free(iNALSizeArray);
                    }

                    iNALSizeArray = (uint32*) oscl_malloc(sizeof(uint32) * iNALSizeArrayMaxElems);
                    if (iNALSizeArray == NULL)
                    {
                        iNALSizeArrayMaxElems = 0;

                        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVMFOMXEncNode-%s : ParseFullAVCFramesIntoNALs ERROR - Out of Memory", iNodeTypeId));
                        return false;
                    }

                    oscl_memcpy(iNALSizeArray, ((OMX_U8*)pExtra + 20), pExtra->nDataSize); // 20 is the size of the extra data struct (minus data hint)
                }

                break;
            }

            offset += pExtra->nSize;
            /* 20 is size of extra data struct (minus data hint),
             * so if there isn't enough room for there to be a full struct, and we haven't reached an OMX_ExtraDataNone
             * the data is corrupt
             */
            if (offset > (allocLen - 20))
            {
                // corrupt data
                break;
            }
            else
            {
                pExtra = (OMX_OTHER_EXTRADATATYPE *)((OMX_U8*)pExtra + pExtra->nSize);
            }
        }

        if (pExtra->eType != OMX_ExtraDataNALSizeArray)
        {
            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVMFOMXEncNode-%s : ParseFullAVCFramesIntoNALs ERROR", iNodeTypeId));
            return false;
        }
    }
    else
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVMFOMXEncNode-%s : ParseFullAVCFramesIntoNALs ERROR", iNodeTypeId));
        return false;
    }

    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVMFOMXEncNode-%s : ParseFullAVCFramesIntoNALs OUT", iNodeTypeId));
    return true;
}

/* utility function copied from the AVC Decoder interface */
bool PVMFOMXEncNode::AVCAnnexBGetNALUnit(uint8 *bitstream, uint8 **nal_unit, int32 *size, bool getPtrOnly)
{
    int32 i, j, FoundStartCode = 0;
    int32 end;

    i = 0;
    while (bitstream[i] == 0 && i < *size)
    {
        i++;
    }
    if (i >= *size)
    {
        *nal_unit = bitstream;
        return false; /* cannot find any start_code_prefix. */
    }
    else if (bitstream[i] != 0x1)
    {
        i = -1;  /* start_code_prefix is not at the beginning, continue */
    }

    i++;
    *nal_unit = bitstream + i; /* point to the beginning of the NAL unit */

    if (getPtrOnly)
    {
        // size not needed, just return with ptr
        return true;
    }

    j = end = i;
    while (!FoundStartCode)
    {
        while ((j + 1 < *size) && (bitstream[j] != 0 || bitstream[j+1] != 0))  /* see 2 consecutive zero bytes */
        {
            j++;
        }
        end = j;   /* stop and check for start code */
        while (j + 2 < *size && bitstream[j+2] == 0) /* keep reading for zero byte */
        {
            j++;
        }
        if (j + 2 >= *size)
        {
            *size -= i;
            return true;  /* cannot find the second start_code_prefix */
        }
        if (bitstream[j+2] == 0x1)
        {
            FoundStartCode = 1;
        }
        else
        {
            /* could be emulation code 0x3 */
            j += 2; /* continue the search */
        }
    }

    *size = end - i;

    return true;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool PVMFOMXEncNode::CheckM4vVopStartCode(uint8* data, int* len)
{
    int32 count = 0;
    int32 i = *len;

    if (i < 4)  // at least the size of frame header
    {
        return false;
    }
    while (--i)
    {
        if ((count > 1) && (data[0] == 0x01) && (data[1] == 0xB6))
        {
            i += 2;
            break;
        }

        if (*data++)
            count = 0;
        else
            count++;
    }

    // i is number of bytes left (including 00 00 01 B6)
    if (i > 0)
    {
        *len = (*len - i - 1); // len before finding VOP start code
        return true;
    }

    return false;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
OMX_TICKS PVMFOMXEncNode::ConvertTimestampIntoOMXTicks(const MediaClockConverter& src)
{
    // This is similar to mediaclockconverter set_value method - except without using the modulo for upper part of 64 bits

    // Timescale value cannot be zero
    OSCL_ASSERT(src.get_timescale() != 0);
    if (src.get_timescale() == 0)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                        (0, "PVMFOMXEncNode-%s::ConvertTimestampIntoOMXTicks Input timescale is 0", iNodeTypeId));

        SetState(EPVMFNodeError);
        ReportErrorEvent(PVMFErrResourceConfiguration);
        return (OMX_TICKS) 0;
    }

    OSCL_ASSERT(iTimeScale != 0);
    if (0 == iTimeScale)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                        (0, "PVMFOMXEncNode-%s::ConvertTimestampIntoOMXTicks target timescale is 0", iNodeTypeId));

        SetState(EPVMFNodeError);
        ReportErrorEvent(PVMFErrResourceConfiguration);
        return (OMX_TICKS) 0;
    }

    uint64 value = (uint64(src.get_wrap_count())) << 32;
    value += src.get_current_timestamp();
    // rounding up
    value = (uint64(value) * iTimeScale + uint64(src.get_timescale() - 1)) / src.get_timescale();
    return (OMX_TICKS) value;


}
////////////////////////////////////////////////////////////////////////////////////
uint32 PVMFOMXEncNode::ConvertOMXTicksIntoTimestamp(const OMX_TICKS &src)
{
    // omx ticks use microsecond timescale (iTimeScale = 1000000)
    // This is similar to mediaclockconverter set_value method

    // Timescale value cannot be zero
    OSCL_ASSERT(iOutTimeScale != 0);
    if (0 == iOutTimeScale)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                        (0, "PVMFOMXEncNode-%s::ConvertOMXTicksIntoTimestamp Output timescale is 0", iNodeTypeId));

        SetState(EPVMFNodeError);
        ReportErrorEvent(PVMFErrResourceConfiguration);
        return (uint32) 0;
    }

    OSCL_ASSERT(iTimeScale != 0);
    if (0 == iTimeScale)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                        (0, "PVMFOMXEncNode-%s::ConvertOMXTicksIntoTimestamp target timescale is 0", iNodeTypeId));

        SetState(EPVMFNodeError);
        ReportErrorEvent(PVMFErrResourceConfiguration);
        return (uint32) 0;
    }

    uint32 current_ts;

    uint64 value = (uint64) src;

    // rounding up
    value = (uint64(value) * iOutTimeScale + uint64(iTimeScale - 1)) / iTimeScale;

    current_ts = (uint32)(value & 0xFFFFFFFF);
    return (uint32) current_ts;

}

////////////////////////////////////////////////////////////////////////////////
bool PVMFOMXEncNode::CheckComponentForMultRoles(OMX_STRING aCompName, OMX_STRING aRole)
{
    OMX_ERRORTYPE err = OMX_ErrorNone;

    // find out how many roles the component supports
    OMX_U32 NumRoles;
    err = OMX_MasterGetRolesOfComponent(aCompName, &NumRoles, NULL);
    if (err != OMX_ErrorNone)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                    (0, "PVMFOMXEncNode-%s::CheckComponentForMultRoles() Problem getting component roles", iNodeTypeId));

        return false;
    }

    // if the component supports multiple roles, call OMX_SetParameter
    if (NumRoles > 1)
    {
        OMX_PARAM_COMPONENTROLETYPE RoleParam;
        CONFIG_SIZE_AND_VERSION(RoleParam);
        oscl_strncpy((OMX_STRING)RoleParam.cRole, aRole, OMX_MAX_STRINGNAME_SIZE);
        err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamStandardComponentRole, &RoleParam);
        if (err != OMX_ErrorNone)
        {
            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                            (0, "PVMFOMXEncNode-%s::CheckComponentForMultRoles() Problem setting component role", iNodeTypeId));

            return false;
        }
    }

    return true;
}

////////////////////////////////////////////////////////////////////////////////
bool PVMFOMXEncNode::CheckComponentCapabilities(PVMFFormatType* aOutFormat)
{
    OMX_ERRORTYPE err = OMX_ErrorNone;

    // GET CAPABILITY FLAGS FROM PV COMPONENT, IF this fails, use defaults
    PV_OMXComponentCapabilityFlagsType Cap_flags;
    err = OMX_GetParameter(iOMXEncoder, (OMX_INDEXTYPE) PV_OMX_COMPONENT_CAPABILITY_TYPE_INDEX, &Cap_flags);
    if (err != OMX_ErrorNone)
    {
        SetDefaultCapabilityFlags();
    }
    else
    {
        iIsOMXComponentMultiThreaded = (OMX_TRUE == Cap_flags.iIsOMXComponentMultiThreaded) ? true : false;
        iOMXComponentSupportsExternalInputBufferAlloc = (OMX_TRUE == Cap_flags.iOMXComponentSupportsExternalInputBufferAlloc) ? true : false;
        iOMXComponentSupportsExternalOutputBufferAlloc = (OMX_TRUE == Cap_flags.iOMXComponentSupportsExternalOutputBufferAlloc) ? true : false;
        iOMXComponentSupportsMovableInputBuffers = (OMX_TRUE == Cap_flags.iOMXComponentSupportsMovableInputBuffers) ? true : false;
        iOMXComponentSupportsPartialFrames = (OMX_TRUE == Cap_flags.iOMXComponentSupportsPartialFrames) ? true : false;
        iOMXComponentUsesNALStartCodes = (OMX_TRUE == Cap_flags.iOMXComponentUsesNALStartCodes) ? true : false;
        iOMXComponentCanHandleIncompleteFrames = (OMX_TRUE == Cap_flags.iOMXComponentCanHandleIncompleteFrames) ? true : false;
        iOMXComponentUsesFullAVCFrames = (OMX_TRUE == Cap_flags.iOMXComponentUsesFullAVCFrames) ? true : false;
    }

    /* iOMXComponentUsesNALStartCodes:    The component inserts start codes before NALs

      iOMXComponentUsesFullAVCFrames
       && !iOMXComponentUsesNALStartCodes:  The component outputs full frames, and stores NAL start codes using the
                 OMX ExtraData structure in the output buffer

      iOMXComponentUsesFullAVCFrames
       && iOMXComponentUsesNALStartCodes:  The component outputs full frames, and delimits NALs by their start codes

      aOutFormat == PVMF_MIME_H264_VIDEO_RAW
       && !iOMXComponentUsesNALStartCodes:  The node inserts the start codes and hides them / exposes them when needed

      aOutFormat == PVMF_MIME_H264_VIDEO_RAW
       && !iOMXComponentUsesNALStartCodes
       && iOMXComponentUsesFullAVCFrames:  This is an invalid combination.  If the node wants raw output, and the component
                 uses full frames, and no start codes, then there is no way to detect the
                 NAL boundaries.
    */

    if (*aOutFormat == PVMF_MIME_H264_VIDEO_RAW &&
            iOMXComponentUsesFullAVCFrames && !iOMXComponentUsesNALStartCodes)
    {
        // This is an invalid combination (see above). Therefore, return an error.


        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                        (0, "PVMFOMXEncNode-%s::CheckComponentCapabilities() Component cannot support %s format", iNodeTypeId, PVMF_MIME_H264_VIDEO_RAW));

        return false;
    }

    // find out about parameters
    if (aOutFormat->isAudio())
    {
        if (!NegotiateAudioComponentParameters())
        {
            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                            (0, "PVMFOMXEncNode-%s::CheckComponentCapabilities() Cannot get component parameters", iNodeTypeId));

            return false;
        }
    }
    else
    {

        if (!NegotiateVideoComponentParameters())
        {
            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                            (0, "PVMFOMXEncNode-%s::CheckComponentCapabilities() Cannot get component parameters", iNodeTypeId));

            return false;
        }
    }

    return true;
}


