Home | History | Annotate | Download | only in src
      1 /* ------------------------------------------------------------------
      2  * Copyright (C) 1998-2009 PacketVideo
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
     13  * express or implied.
     14  * See the License for the specific language governing permissions
     15  * and limitations under the License.
     16  * -------------------------------------------------------------------
     17  */
     18 #include "pvmf_omx_enc_node.h"
     19 #include "pvlogger.h"
     20 #include "oscl_error_codes.h"
     21 #include "pvmf_omx_enc_port.h"
     22 #include "pv_mime_string_utils.h"
     23 #include "oscl_snprintf.h"
     24 #include "pvmf_media_cmd.h"
     25 #include "pvmf_media_msg_format_ids.h"
     26 #include "pvmi_kvp_util.h"
     27 
     28 #ifdef _DEBUG
     29 #include <stdio.h>
     30 #endif
     31 
     32 #include "OMX_Core.h"
     33 #include "pvmf_omx_enc_callbacks.h"     //used for thin AO in encoder's callbacks
     34 #include "pv_omxcore.h"
     35 
     36 #define CONFIG_SIZE_AND_VERSION(param)                  \
     37     param.nSize=sizeof(param);                          \
     38     param.nVersion.s.nVersionMajor = SPECVERSIONMAJOR;  \
     39     param.nVersion.s.nVersionMinor = SPECVERSIONMINOR;  \
     40     param.nVersion.s.nRevision = SPECREVISION;          \
     41     param.nVersion.s.nStep = SPECSTEP;
     42 
     43 
     44 #define CHECK_OMX_ERR_AND_RETURN(Err, str)                              \
     45     if (Err != OMX_ErrorNone)                                           \
     46     {                                                                   \
     47         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, str)); \
     48     }
     49 
     50 
     51 #define PVOMXENC_EXTRA_YUVBUFFER_POOLNUM 3
     52 #define PVOMXENC_MEDIADATA_POOLNUM (PVOMXENCMAXNUMDPBFRAMESPLUS1 + PVOMXENC_EXTRA_YUVBUFFER_POOLNUM)
     53 #define PVOMXENC_MEDIADATA_CHUNKSIZE 128
     54 
     55 #include "utils/Log.h"
     56 #undef LOG_TAG
     57 #define LOG_TAG "PVOMXEncNode"
     58 
     59 const uint32 DEFAULT_VOL_HEADER_LENGTH = 28;
     60 const uint8 DEFAULT_VOL_HEADER[DEFAULT_VOL_HEADER_LENGTH] =
     61 {
     62     0x00, 0x00, 0x01, 0xB0, 0x08, 0x00, 0x00, 0x01,
     63     0xB5, 0x09, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
     64     0x01, 0x20, 0x00, 0x84, 0x40, 0xFA, 0x28, 0x2C,
     65     0x20, 0x90, 0xA2, 0x1F
     66 };
     67 
     68 
     69 #ifdef _TEST_AE_ERROR_HANDLING
     70 const uint32 FAIL_NODE_CMD_START = 2;
     71 const uint32 FAIL_NODE_CMD_STOP = 3;
     72 const uint32 FAIL_NODE_CMD_FLUSH = 4;
     73 const uint32 FAIL_NODE_CMD_PAUSE = 5;
     74 const uint32 FAIL_NODE_CMD_RELEASE_PORT = 7;
     75 #endif
     76 
     77 #define PVMF_OMXENC_NUM_METADATA_VALUES 6
     78 
     79 // Constant character strings for metadata keys
     80 static const char PVOMXENCMETADATA_CODECINFO_VIDEO_FORMAT_KEY[] = "codec-info/video/format";
     81 static const char PVOMXENCMETADATA_CODECINFO_VIDEO_WIDTH_KEY[] = "codec-info/video/width";
     82 static const char PVOMXENCMETADATA_CODECINFO_VIDEO_HEIGHT_KEY[] = "codec-info/video/height";
     83 static const char PVOMXENCMETADATA_CODECINFO_VIDEO_PROFILE_KEY[] = "codec-info/video/profile";
     84 static const char PVOMXENCMETADATA_CODECINFO_VIDEO_LEVEL_KEY[] = "codec-info/video/level";
     85 static const char PVOMXENCMETADATA_CODECINFO_VIDEO_AVGBITRATE_KEY[] = "codec-info/video/avgbitrate";//(bits per sec)
     86 
     87 
     88 static const char PVOMXENCMETADATA_SEMICOLON[] = ";";
     89 
     90 static const char LOG_ID_AUDIO_AMRNB[]  = "Audio_AMRNB";
     91 static const char LOG_ID_AUDIO_AMRWB[]  = "Audio_AMRWB";
     92 static const char LOG_ID_AUDIO_AAC[]  = "Audio_AAC";
     93 static const char LOG_ID_VIDEO_H263[] = "Video_H263";
     94 static const char LOG_ID_VIDEO_M4V[] =  "Video_M4V";
     95 static const char LOG_ID_VIDEO_AVC[] =  "Video_AVC";
     96 static const char LOG_ID_UNKNOWN[] = "TypeNotSetYet";
     97 
     98 // OMX CALLBACKS
     99 // 1) AO OMX component running in the same thread as the OMX node
    100 //  In this case, the callbacks can be called directly from the component
    101 //  The callback: OMX Component->CallbackEventHandler->EventHandlerProcessing
    102 //  The callback can perform do RunIfNotReady
    103 
    104 // 2) Multithreaded component
    105 //  In this case, the callback is made using the threadsafe callback (TSCB) AO
    106 //  Component thread : OMX Component->CallbackEventHandler->TSCB(ReceiveEvent) => event is queued
    107 //  Node thread      : dequeue event => TSCB(ProcessEvent)->ProcessCallbackEventHandler->EventHandlerProcessing
    108 
    109 
    110 
    111 // callback for Event Handler - in multithreaded case, event is queued to be processed later
    112 //  in AO case, event is processed immediately by calling EventHandlerProcessing
    113 OMX_ERRORTYPE CallbackEventHandlerEnc(OMX_OUT OMX_HANDLETYPE aComponent,
    114                                       OMX_OUT OMX_PTR aAppData,
    115                                       OMX_OUT OMX_EVENTTYPE aEvent,
    116                                       OMX_OUT OMX_U32 aData1,
    117                                       OMX_OUT OMX_U32 aData2,
    118                                       OMX_OUT OMX_PTR aEventData)
    119 {
    120 
    121     PVMFOMXEncNode *Node = (PVMFOMXEncNode *) aAppData;
    122 
    123     if (Node->IsComponentMultiThreaded())
    124     {
    125         // allocate the memory for the callback event specific data
    126         //EventHandlerSpecificData* ED = (EventHandlerSpecificData*) oscl_malloc(sizeof (EventHandlerSpecificData));
    127         EventHandlerSpecificData* ED = (EventHandlerSpecificData*) Node->iThreadSafeHandlerEventHandler->iMemoryPool->allocate(sizeof(EventHandlerSpecificData));
    128 
    129         // pack the relevant data into the structure
    130         ED->hComponent = aComponent;
    131         ED->pAppData = aAppData;
    132         ED->eEvent = aEvent;
    133         ED->nData1 = aData1;
    134         ED->nData2 = aData2;
    135         ED->pEventData = aEventData;
    136 
    137         // convert the pointer into OsclAny ptr
    138         OsclAny* P = (OsclAny*) ED;
    139 
    140 
    141         // CALL the generic callback AO API:
    142         Node->iThreadSafeHandlerEventHandler->ReceiveEvent(P);
    143 
    144         return OMX_ErrorNone;
    145     }
    146     else
    147     {
    148 
    149         OMX_ERRORTYPE status;
    150         status = Node->EventHandlerProcessing(aComponent, aAppData, aEvent, aData1, aData2, aEventData);
    151         return status;
    152     }
    153 
    154 }
    155 
    156 
    157 // callback for EmptyBufferDone - in multithreaded case, event is queued to be processed later
    158 //  in AO case, event is processed immediately by calling EmptyBufferDoneProcessing
    159 OMX_ERRORTYPE CallbackEmptyBufferDoneEnc(OMX_OUT OMX_HANDLETYPE aComponent,
    160         OMX_OUT OMX_PTR aAppData,
    161         OMX_OUT OMX_BUFFERHEADERTYPE* aBuffer)
    162 {
    163 
    164     PVMFOMXEncNode *Node = (PVMFOMXEncNode *) aAppData;
    165     if (Node->IsComponentMultiThreaded())
    166     {
    167 
    168         // allocate the memory for the callback event specific data
    169         //EmptyBufferDoneSpecificData* ED = (EmptyBufferDoneSpecificData*) oscl_malloc(sizeof (EmptyBufferDoneSpecificData));
    170         EmptyBufferDoneSpecificData* ED = (EmptyBufferDoneSpecificData*) Node->iThreadSafeHandlerEmptyBufferDone->iMemoryPool->allocate(sizeof(EmptyBufferDoneSpecificData));
    171 
    172         // pack the relevant data into the structure
    173         ED->hComponent = aComponent;
    174         ED->pAppData = aAppData;
    175         ED->pBuffer = aBuffer;
    176 
    177         // convert the pointer into OsclAny ptr
    178         OsclAny* P = (OsclAny*) ED;
    179 
    180         // CALL the generic callback AO API:
    181         Node->iThreadSafeHandlerEmptyBufferDone->ReceiveEvent(P);
    182 
    183         return OMX_ErrorNone;
    184     }
    185     else
    186     {
    187         OMX_ERRORTYPE status;
    188         status = Node->EmptyBufferDoneProcessing(aComponent, aAppData, aBuffer);
    189         return status;
    190     }
    191 
    192 }
    193 
    194 // callback for FillBufferDone - in multithreaded case, event is queued to be processed later
    195 //  in AO case, event is processed immediately by calling FillBufferDoneProcessing
    196 OMX_ERRORTYPE CallbackFillBufferDoneEnc(OMX_OUT OMX_HANDLETYPE aComponent,
    197                                         OMX_OUT OMX_PTR aAppData,
    198                                         OMX_OUT OMX_BUFFERHEADERTYPE* aBuffer)
    199 {
    200     PVMFOMXEncNode *Node = (PVMFOMXEncNode *) aAppData;
    201     if (Node->IsComponentMultiThreaded())
    202     {
    203 
    204         // allocate the memory for the callback event specific data
    205         //FillBufferDoneSpecificData* ED = (FillBufferDoneSpecificData*) oscl_malloc(sizeof (FillBufferDoneSpecificData));
    206         FillBufferDoneSpecificData* ED = (FillBufferDoneSpecificData*) Node->iThreadSafeHandlerFillBufferDone->iMemoryPool->allocate(sizeof(FillBufferDoneSpecificData));
    207 
    208         // pack the relevant data into the structure
    209         ED->hComponent = aComponent;
    210         ED->pAppData = aAppData;
    211         ED->pBuffer = aBuffer;
    212 
    213         // convert the pointer into OsclAny ptr
    214         OsclAny* P = (OsclAny*) ED;
    215 
    216         // CALL the generic callback AO API:
    217         Node->iThreadSafeHandlerFillBufferDone->ReceiveEvent(P);
    218 
    219         return OMX_ErrorNone;
    220     }
    221     else
    222     {
    223         OMX_ERRORTYPE status;
    224         status = Node->FillBufferDoneProcessing(aComponent, aAppData, aBuffer);
    225         return status;
    226     }
    227 
    228 }
    229 
    230 // Callback processing in multithreaded case - dequeued event - call EventHandlerProcessing
    231 OsclReturnCode PVMFOMXEncNode::ProcessCallbackEventHandler_MultiThreaded(OsclAny* P)
    232 {
    233 
    234     // re-cast the pointer
    235 
    236     EventHandlerSpecificData* ED = (EventHandlerSpecificData*) P;
    237 
    238     OMX_HANDLETYPE aComponent = ED->hComponent;
    239     OMX_PTR aAppData = ED->pAppData;
    240     OMX_EVENTTYPE aEvent = ED->eEvent;
    241     OMX_U32 aData1 = ED->nData1;
    242     OMX_U32 aData2 = ED->nData2;
    243     OMX_PTR aEventData = ED->pEventData;
    244 
    245 
    246     EventHandlerProcessing(aComponent, aAppData, aEvent, aData1, aData2, aEventData);
    247 
    248 
    249     // release the allocated memory when no longer needed
    250 
    251     iThreadSafeHandlerEventHandler->iMemoryPool->deallocate(ED);
    252     ED = NULL;
    253 
    254     return OsclSuccess;
    255 }
    256 
    257 
    258 
    259 // Callback processing in multithreaded case - dequeued event - call EmptyBufferDoneProcessing
    260 OsclReturnCode PVMFOMXEncNode::ProcessCallbackEmptyBufferDone_MultiThreaded(OsclAny* P)
    261 {
    262 
    263 
    264     // re-cast the pointer
    265     EmptyBufferDoneSpecificData* ED = (EmptyBufferDoneSpecificData*) P;
    266 
    267     OMX_HANDLETYPE aComponent = ED->hComponent;
    268     OMX_PTR aAppData = ED->pAppData;
    269     OMX_BUFFERHEADERTYPE* aBuffer = ED->pBuffer;
    270 
    271     EmptyBufferDoneProcessing(aComponent, aAppData, aBuffer);
    272 
    273     // release the allocated memory when no longer needed
    274 
    275     iThreadSafeHandlerEmptyBufferDone->iMemoryPool->deallocate(ED);
    276     ED = NULL;
    277 
    278     return OsclSuccess;
    279 }
    280 
    281 
    282 // Callback processing in multithreaded case - dequeued event - call FillBufferDoneProcessing
    283 OsclReturnCode PVMFOMXEncNode::ProcessCallbackFillBufferDone_MultiThreaded(OsclAny* P)
    284 {
    285 
    286     // re-cast the pointer
    287     FillBufferDoneSpecificData* ED = (FillBufferDoneSpecificData*) P;
    288 
    289     OMX_HANDLETYPE aComponent = ED->hComponent;
    290     OMX_PTR aAppData = ED->pAppData;
    291     OMX_BUFFERHEADERTYPE* aBuffer = ED->pBuffer;
    292 
    293 
    294     FillBufferDoneProcessing(aComponent, aAppData, aBuffer);
    295 
    296 
    297     // release the allocated memory when no longer needed
    298 
    299     iThreadSafeHandlerFillBufferDone->iMemoryPool->deallocate(ED);
    300     ED = NULL;
    301 
    302     return OsclSuccess;
    303 }
    304 /////////////////////////////////////////////////////////////////////////////
    305 // Class Destructor
    306 /////////////////////////////////////////////////////////////////////////////
    307 PVMFOMXEncNode::~PVMFOMXEncNode()
    308 {
    309     LogDiagnostics();
    310 
    311     //Clearup encoder
    312     DeleteOMXEncoder();
    313 
    314     // Cleanup callback AOs and Mempools
    315     if (iThreadSafeHandlerEventHandler)
    316     {
    317         OSCL_DELETE(iThreadSafeHandlerEventHandler);
    318         iThreadSafeHandlerEventHandler = NULL;
    319     }
    320     if (iThreadSafeHandlerEmptyBufferDone)
    321     {
    322         OSCL_DELETE(iThreadSafeHandlerEmptyBufferDone);
    323         iThreadSafeHandlerEmptyBufferDone = NULL;
    324     }
    325     if (iThreadSafeHandlerFillBufferDone)
    326     {
    327         OSCL_DELETE(iThreadSafeHandlerFillBufferDone);
    328         iThreadSafeHandlerFillBufferDone = NULL;
    329     }
    330 
    331     if (iMediaDataMemPool)
    332     {
    333         iMediaDataMemPool->removeRef();
    334         iMediaDataMemPool = NULL;
    335     }
    336 
    337     if (iOutBufMemoryPool)
    338     {
    339         iOutBufMemoryPool->removeRef();
    340         iOutBufMemoryPool = NULL;
    341     }
    342 
    343     ipFixedSizeBufferAlloc = NULL;
    344     if(ipExternalInputBufferAllocatorInterface)
    345     {
    346         ipExternalInputBufferAllocatorInterface->removeRef();
    347         ipExternalInputBufferAllocatorInterface = NULL;
    348     }
    349 
    350     if (iInBufMemoryPool)
    351     {
    352         iInBufMemoryPool->removeRef();
    353         iInBufMemoryPool = NULL;
    354     }
    355 
    356     if (in_ctrl_struct_ptr)
    357     {
    358         oscl_free(in_ctrl_struct_ptr);
    359         in_ctrl_struct_ptr = NULL;
    360     }
    361 
    362     if (in_buff_hdr_ptr)
    363     {
    364         oscl_free(in_buff_hdr_ptr);
    365         in_buff_hdr_ptr = NULL;
    366     }
    367 
    368     if (out_ctrl_struct_ptr)
    369     {
    370         oscl_free(out_ctrl_struct_ptr);
    371         out_ctrl_struct_ptr = NULL;
    372     }
    373 
    374     if (out_buff_hdr_ptr)
    375     {
    376         oscl_free(out_buff_hdr_ptr);
    377         out_buff_hdr_ptr = NULL;
    378     }
    379 
    380     //Thread logoff
    381     if (IsAdded())
    382     {
    383         RemoveFromScheduler();
    384         iIsAdded = false;
    385     }
    386 
    387     //Cleanup allocated interfaces
    388 
    389     //Cleanup allocated ports
    390     ReleaseAllPorts();
    391 
    392     //Cleanup commands
    393     //The command queues are self-deleting, but we want to
    394     //notify the observer of unprocessed commands.
    395     while (!iCurrentCommand.empty())
    396     {
    397         CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFFailure);
    398     }
    399     while (!iInputCommands.empty())
    400     {
    401         CommandComplete(iInputCommands, iInputCommands.front(), PVMFFailure);
    402     }
    403 
    404     if (iNALSizeArray != NULL)
    405     {
    406         oscl_free(iNALSizeArray);
    407     }
    408 
    409     if (iNALPtrArray != NULL)
    410     {
    411         oscl_free(iNALPtrArray);
    412     }
    413 
    414     //Release Input buffer
    415     iDataIn.Unbind();
    416 
    417 }
    418 
    419 /////////////////////////////////////////////////////////////////////////////
    420 // Add AO to the scheduler
    421 /////////////////////////////////////////////////////////////////////////////
    422 PVMFStatus PVMFOMXEncNode::ThreadLogon()
    423 {
    424     PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFOMXEncNode:ThreadLogon"));
    425 
    426     switch (iInterfaceState)
    427     {
    428         case EPVMFNodeCreated:
    429             if (!IsAdded())
    430             {
    431                 AddToScheduler();
    432                 iIsAdded = true;
    433             }
    434 
    435             SetState(EPVMFNodeIdle);
    436             return PVMFSuccess;
    437             // break;   This break statement was removed to avoid compiler warning for Unreachable Code
    438         default:
    439             return PVMFErrInvalidState;
    440             // break;   This break statement was removed to avoid compiler warning for Unreachable Code
    441     }
    442 }
    443 
    444 /////////////////////////////////////////////////////////////////////////////
    445 // Remove AO from the scheduler
    446 /////////////////////////////////////////////////////////////////////////////
    447 PVMFStatus PVMFOMXEncNode::ThreadLogoff()
    448 {
    449     PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFOMXEncNode-%s::ThreadLogoff", iNodeTypeId));
    450 
    451     switch (iInterfaceState)
    452     {
    453         case EPVMFNodeIdle:
    454             if (IsAdded())
    455             {
    456                 RemoveFromScheduler();
    457                 iIsAdded = false;
    458             }
    459             iLogger = NULL;
    460             SetState(EPVMFNodeCreated);
    461             return PVMFSuccess;
    462             // break;   This break statement was removed to avoid compiler warning for Unreachable Code
    463 
    464         default:
    465             return PVMFErrInvalidState;
    466             // break;   This break statement was removed to avoid compiler warning for Unreachable Code
    467     }
    468 }
    469 
    470 /////////////////////////////////////////////////////////////////////////////
    471 PVMFStatus PVMFOMXEncNode::GetCapability(PVMFNodeCapability& aNodeCapability)
    472 {
    473     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::GetCapability() called", iNodeTypeId));
    474 
    475     aNodeCapability = iCapability;
    476     return PVMFSuccess;
    477 }
    478 
    479 /////////////////////////////////////////////////////////////////////////////
    480 PVMFPortIter* PVMFOMXEncNode::GetPorts(const PVMFPortFilter* aFilter)
    481 {
    482     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::GetPorts() %s called", iNodeTypeId));
    483 
    484     OSCL_UNUSED_ARG(aFilter);
    485 
    486     return NULL;
    487 }
    488 
    489 /////////////////////////////////////////////////////////////////////////////
    490 PVMFCommandId PVMFOMXEncNode::QueueCommandL(PVMFOMXEncNodeCommand& aCmd)
    491 {
    492     PVMFCommandId id;
    493 
    494     id = iInputCommands.AddL(aCmd);
    495 
    496     if (iInputCommands.size() == 1)
    497     {
    498         //wakeup the AO all the rest of input commands will reschedule the AO in Run
    499         RunIfNotReady();
    500     }
    501     return id;
    502 }
    503 
    504 /////////////////////////////////////////////////////////////////////////////
    505 PVMFCommandId PVMFOMXEncNode::QueryUUID(PVMFSessionId s, const PvmfMimeString& aMimeType,
    506                                         Oscl_Vector<PVUuid, PVMFOMXEncNodeAllocator>& aUuids,
    507                                         bool aExactUuidsOnly,
    508                                         const OsclAny* aContext)
    509 {
    510     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::QueryUUID() called", iNodeTypeId));
    511     PVMFOMXEncNodeCommand cmd;
    512     cmd.PVMFOMXEncNodeCommandBase::Construct(s, PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_QUERYUUID, aMimeType, aUuids, aExactUuidsOnly, aContext);
    513     return QueueCommandL(cmd);
    514 }
    515 
    516 /////////////////////////////////////////////////////////////////////////////
    517 PVMFCommandId PVMFOMXEncNode::QueryInterface(PVMFSessionId s, const PVUuid& aUuid,
    518         PVInterface*& aInterfacePtr,
    519         const OsclAny* aContext)
    520 {
    521     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::QueryInterface() called", iNodeTypeId));
    522     PVMFOMXEncNodeCommand cmd;
    523     cmd.PVMFOMXEncNodeCommandBase::Construct(s, PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_QUERYINTERFACE, aUuid, aInterfacePtr, aContext);
    524     return QueueCommandL(cmd);
    525 }
    526 
    527 /////////////////////////////////////////////////////////////////////////////
    528 PVMFCommandId PVMFOMXEncNode::RequestPort(PVMFSessionId s, int32 aPortTag, const PvmfMimeString* aPortConfig, const OsclAny* aContext)
    529 {
    530     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::RequestPort() called", iNodeTypeId));
    531     PVMFOMXEncNodeCommand cmd;
    532 
    533     // IMPORTANT NOTE - ENGINE IS SENDING THE MIME TYPE FOR THE ENCODER INPUT/OUTPUT FORMAT THRU THE PORT PARAMETER
    534     cmd.PVMFOMXEncNodeCommandBase::Construct(s, PVMF_GENERIC_NODE_REQUESTPORT, aPortTag, aPortConfig, aContext);
    535     return QueueCommandL(cmd);
    536 
    537 }
    538 
    539 /////////////////////////////////////////////////////////////////////////////
    540 PVMFStatus PVMFOMXEncNode::ReleasePort(PVMFSessionId s, PVMFPortInterface& aPort, const OsclAny* aContext)
    541 {
    542     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::ReleasePort() called", iNodeTypeId));
    543     PVMFOMXEncNodeCommand cmd;
    544     cmd.PVMFOMXEncNodeCommandBase::Construct(s, PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_RELEASEPORT, aPort, aContext);
    545     return QueueCommandL(cmd);
    546 }
    547 
    548 /////////////////////////////////////////////////////////////////////////////
    549 PVMFCommandId PVMFOMXEncNode::Init(PVMFSessionId s, const OsclAny* aContext)
    550 {
    551     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::Init() called", iNodeTypeId));
    552     PVMFOMXEncNodeCommand cmd;
    553     cmd.PVMFOMXEncNodeCommandBase::Construct(s, PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_INIT, aContext);
    554     return QueueCommandL(cmd);
    555 }
    556 
    557 /////////////////////////////////////////////////////////////////////////////
    558 PVMFCommandId PVMFOMXEncNode::Prepare(PVMFSessionId s, const OsclAny* aContext)
    559 {
    560     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::Prepare() called", iNodeTypeId));
    561     PVMFOMXEncNodeCommand cmd;
    562     cmd.PVMFOMXEncNodeCommandBase::Construct(s, PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_PREPARE, aContext);
    563     return QueueCommandL(cmd);
    564 }
    565 
    566 /////////////////////////////////////////////////////////////////////////////
    567 PVMFCommandId PVMFOMXEncNode::Start(PVMFSessionId s, const OsclAny* aContext)
    568 {
    569     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::Start() called", iNodeTypeId));
    570     PVMFOMXEncNodeCommand cmd;
    571     cmd.PVMFOMXEncNodeCommandBase::Construct(s, PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_START, aContext);
    572     return QueueCommandL(cmd);
    573 }
    574 
    575 /////////////////////////////////////////////////////////////////////////////
    576 PVMFCommandId PVMFOMXEncNode::Stop(PVMFSessionId s, const OsclAny* aContext)
    577 {
    578     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::Stop() called", iNodeTypeId));
    579     PVMFOMXEncNodeCommand cmd;
    580     cmd.PVMFOMXEncNodeCommandBase::Construct(s, PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_STOP, aContext);
    581     return QueueCommandL(cmd);
    582 }
    583 
    584 /////////////////////////////////////////////////////////////////////////////
    585 PVMFCommandId PVMFOMXEncNode::Flush(PVMFSessionId s, const OsclAny* aContext)
    586 {
    587     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::Flush() called", iNodeTypeId));
    588     PVMFOMXEncNodeCommand cmd;
    589     cmd.PVMFOMXEncNodeCommandBase::Construct(s, PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_FLUSH, aContext);
    590     return QueueCommandL(cmd);
    591 }
    592 
    593 /////////////////////////////////////////////////////////////////////////////
    594 PVMFCommandId PVMFOMXEncNode::Pause(PVMFSessionId s, const OsclAny* aContext)
    595 {
    596     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::Pause() called", iNodeTypeId));
    597     PVMFOMXEncNodeCommand cmd;
    598     cmd.PVMFOMXEncNodeCommandBase::Construct(s, PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_PAUSE, aContext);
    599     return QueueCommandL(cmd);
    600 }
    601 
    602 /////////////////////////////////////////////////////////////////////////////
    603 PVMFCommandId PVMFOMXEncNode::Reset(PVMFSessionId s, const OsclAny* aContext)
    604 {
    605     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::Reset() called", iNodeTypeId));
    606     PVMFOMXEncNodeCommand cmd;
    607     cmd.PVMFOMXEncNodeCommandBase::Construct(s, PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_RESET, aContext);
    608     return QueueCommandL(cmd);
    609 }
    610 
    611 /////////////////////////////////////////////////////////////////////////////
    612 PVMFCommandId PVMFOMXEncNode::CancelAllCommands(PVMFSessionId s, const OsclAny* aContext)
    613 {
    614     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::CancelAllCommands() called", iNodeTypeId));
    615     PVMFOMXEncNodeCommand cmd;
    616     cmd.PVMFOMXEncNodeCommandBase::Construct(s, PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_CANCELALL, aContext);
    617     return QueueCommandL(cmd);
    618 }
    619 
    620 /////////////////////////////////////////////////////////////////////////////
    621 PVMFCommandId PVMFOMXEncNode::CancelCommand(PVMFSessionId s, PVMFCommandId aCmdId, const OsclAny* aContext)
    622 {
    623     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::CancelCommand() called", iNodeTypeId));
    624     PVMFOMXEncNodeCommand cmd;
    625     cmd.PVMFOMXEncNodeCommandBase::Construct(s, PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_CANCELCMD, aCmdId, aContext);
    626     return QueueCommandL(cmd);
    627 }
    628 
    629 
    630 
    631 
    632 
    633 /////////////////////
    634 // Private Section //
    635 /////////////////////
    636 
    637 /////////////////////////////////////////////////////////////////////////////
    638 // Class Constructor
    639 /////////////////////////////////////////////////////////////////////////////
    640 PVMFOMXEncNode::PVMFOMXEncNode(int32 aPriority) :
    641         OsclActiveObject(aPriority, "PVMFOMXEncNode"),
    642         iInPort(NULL),
    643         iOutPort(NULL),
    644         iOutBufMemoryPool(NULL),
    645         iMediaDataMemPool(NULL),
    646         iOMXComponentOutputBufferSize(0),
    647         iOutputAllocSize(0),
    648         iNumOutstandingOutputBuffers(0),
    649         iNumOutstandingInputBuffers(0),
    650         iProcessingState(EPVMFOMXEncNodeProcessingState_Idle),
    651         iOMXEncoder(NULL),
    652         iSendBOS(false),
    653         iStreamID(0),
    654         iBOSTimestamp(0),
    655         iSeqNum(0),
    656         iSeqNum_In(0),
    657         iIsAdded(true),
    658         iLogger(NULL),
    659         iDataPathLogger(NULL),
    660         iClockLogger(NULL),
    661         iExtensionRefCount(0),
    662         iEndOfDataReached(false),
    663         iEndOfDataTimestamp(0),
    664         iDiagnosticsLogger(NULL),
    665         iDiagnosticsLogged(false),
    666         iAvgBitrateValue(0),
    667         iResetInProgress(false),
    668         iResetMsgSent(false),
    669         iStopInResetMsgSent(false),
    670         ipExternalInputBufferAllocatorInterface(NULL),
    671         ipFixedSizeBufferAlloc(NULL)
    672 {
    673     iInterfaceState = EPVMFNodeCreated;
    674 
    675 
    676     // Allocate memory for VOL header
    677     uint refCounterSize = oscl_mem_aligned_size(sizeof(OsclRefCounterDA));
    678     uint VolHdrSize = refCounterSize + DEFAULT_VOL_HEADER_LENGTH;
    679     uint8 *memBufferVOLHeader = NULL;
    680 
    681     uint ParamSetSize = refCounterSize + DEFAULT_PARAMS_SET_LENGTH;
    682     uint8 *memBufferParamSet = NULL;
    683 
    684 
    685     int32 err;
    686     OSCL_TRY(err,
    687 
    688              //Create the input command queue.  Use a reserve to avoid lots of
    689              //dynamic memory allocation.
    690              iInputCommands.Construct(PVMF_OMXENC_NODE_COMMAND_ID_START, PVMF_OMXENC_NODE_COMMAND_VECTOR_RESERVE);
    691 
    692              //Create the "current command" queue.  It will only contain one
    693              //command at a time, so use a reserve of 1.
    694              iCurrentCommand.Construct(0, 1);
    695 
    696              //Set the node capability data.
    697              //This node can support an unlimited number of ports.
    698              iCapability.iCanSupportMultipleInputPorts = false;
    699              iCapability.iCanSupportMultipleOutputPorts = false;
    700              iCapability.iHasMaxNumberOfPorts = true;
    701              iCapability.iMaxNumberOfPorts = 2;
    702 
    703              // video output
    704              iCapability.iOutputFormatCapability.push_back(PVMF_MIME_H264_VIDEO_MP4);
    705              iCapability.iOutputFormatCapability.push_back(PVMF_MIME_H264_VIDEO_RAW);
    706              //iCapability.iOutputFormatCapability.push_back(PVMF_MIME_H264_VIDEO);
    707              iCapability.iOutputFormatCapability.push_back(PVMF_MIME_M4V);
    708              iCapability.iOutputFormatCapability.push_back(PVMF_MIME_H2631998);
    709              iCapability.iOutputFormatCapability.push_back(PVMF_MIME_H2632000);
    710              //iCapability.iOutputFormatCapability.push_back(PVMF_MIME_WMV);
    711              // audio output
    712              iCapability.iOutputFormatCapability.push_back(PVMF_MIME_AMR_IETF);
    713              iCapability.iOutputFormatCapability.push_back(PVMF_MIME_AMRWB_IETF);
    714              iCapability.iOutputFormatCapability.push_back(PVMF_MIME_AMR_IF2);
    715              iCapability.iOutputFormatCapability.push_back(PVMF_MIME_ADTS);
    716              iCapability.iOutputFormatCapability.push_back(PVMF_MIME_ADIF);
    717              iCapability.iOutputFormatCapability.push_back(PVMF_MIME_MPEG4_AUDIO);
    718 
    719              // video input
    720              iCapability.iInputFormatCapability.push_back(PVMF_MIME_YUV420);
    721              iCapability.iInputFormatCapability.push_back(PVMF_MIME_YUV422);
    722              iCapability.iInputFormatCapability.push_back(PVMF_MIME_YUV422_INTERLEAVED_UYVY);
    723              iCapability.iInputFormatCapability.push_back(PVMF_MIME_YUV422_INTERLEAVED_YUYV);
    724              iCapability.iInputFormatCapability.push_back(PVMF_MIME_RGB24);
    725              iCapability.iInputFormatCapability.push_back(PVMF_MIME_RGB12);
    726 
    727              // audio input
    728              iCapability.iInputFormatCapability.push_back(PVMF_MIME_PCM16);
    729 
    730 
    731 
    732              iAvailableMetadataKeys.reserve(PVMF_OMXENC_NUM_METADATA_VALUES);
    733              iAvailableMetadataKeys.clear();
    734 
    735              // for VOL header
    736              memBufferVOLHeader = (uint8*)iAlloc.allocate(VolHdrSize);
    737              if (!memBufferVOLHeader)
    738 {
    739     OSCL_LEAVE(PVMFErrNoMemory);
    740     }
    741 
    742     memBufferParamSet = (uint8*) iAlloc.allocate(ParamSetSize);
    743     if (!memBufferParamSet)
    744 {
    745     OSCL_LEAVE(PVMFErrNoMemory);
    746     }
    747 
    748             );
    749 
    750     // Save default VOL header
    751     oscl_memset(memBufferVOLHeader, 0, DEFAULT_VOL_HEADER_LENGTH);
    752     OsclMemoryFragment volHeader;
    753     OsclRefCounter* refCounterVOLHeader = new(memBufferVOLHeader) OsclRefCounterDA(memBufferVOLHeader,
    754             (OsclDestructDealloc*)&iAlloc);
    755     memBufferVOLHeader += refCounterSize;
    756     volHeader.ptr = memBufferVOLHeader;
    757     oscl_memcpy(volHeader.ptr, (OsclAny*)DEFAULT_VOL_HEADER, DEFAULT_VOL_HEADER_LENGTH);
    758     volHeader.len = DEFAULT_VOL_HEADER_LENGTH;
    759     iVolHeader = OsclRefCounterMemFrag(volHeader, refCounterVOLHeader, DEFAULT_VOL_HEADER_LENGTH);
    760 
    761 
    762     // construct SPS&PPS placeholder
    763     oscl_memset(memBufferParamSet, 0, DEFAULT_PARAMS_SET_LENGTH);
    764     OsclMemoryFragment paramSet;
    765     OsclRefCounter* refCounterParamSet = new(memBufferParamSet) OsclRefCounterDA(memBufferParamSet,
    766             (OsclDestructDealloc*)&iAlloc);
    767     memBufferParamSet += refCounterSize;
    768     paramSet.ptr = memBufferParamSet;
    769     paramSet.len = DEFAULT_PARAMS_SET_LENGTH;
    770 
    771     iParamSet = OsclRefCounterMemFrag(paramSet, refCounterParamSet, DEFAULT_PARAMS_SET_LENGTH);
    772 
    773     // initialize length and number of sps/ppss
    774     iParamSet.getMemFrag().len = 0;
    775     iNumPPSs = 0;
    776     iNumSPSs = 0;
    777     iSpsPpsSequenceOver = false;
    778     iFirstNAL = false; //set this to false so that mp4 can proceed without a problem.
    779     // in case of AVC, this flag will be set after spspps
    780 
    781     iNALSizeArray = NULL;
    782     iNALPtrArray = NULL;
    783     iNALSizeArrayMaxElems = 0;
    784     iNumNALs = 0;
    785     iFirstNALStartCodeSize = 0;
    786 
    787     iThreadSafeHandlerEventHandler = NULL;
    788     iThreadSafeHandlerEmptyBufferDone = NULL;
    789     iThreadSafeHandlerFillBufferDone = NULL;
    790 
    791     iInBufMemoryPool = NULL;
    792     iOutBufMemoryPool = NULL;
    793 
    794     in_ctrl_struct_ptr = NULL;
    795     in_buff_hdr_ptr = NULL;
    796     out_ctrl_struct_ptr = NULL;
    797     out_buff_hdr_ptr = NULL;
    798 
    799     // init to some value
    800     iOMXComponentOutputBufferSize = 0;
    801     iNumOutputBuffers = 0;
    802     iOMXComponentInputBufferSize = 0;
    803     iNumInputBuffers = 0;
    804 
    805     iDoNotSendOutputBuffersDownstreamFlag = false;
    806     iDoNotSaveInputBuffersFlag = false;
    807 
    808 
    809     iOutputBuffersFreed = true;// buffers have not been created yet, so they can be considered freed
    810     iInputBuffersFreed = true;
    811 
    812     // dynamic port reconfig init vars
    813     iSecondPortReportedChange = false;
    814     iDynamicReconfigInProgress = false;
    815 
    816     // EOS flag init
    817     iIsEOSSentToComponent = false;
    818     iIsEOSReceivedFromComponent = false;
    819 
    820     // init state of component
    821     iCurrentEncoderState = OMX_StateInvalid;
    822 
    823     iTimeStampOut = 0;
    824     iTimeStampPrevious = 0;
    825     iBufferLenOut = 0;
    826     iBufferLenPrevious = 0;
    827     iEndOfFrameFlagPrevious = 0;
    828     iKeyFrameFlagPrevious = 0;
    829     iEndOfNALFlagPrevious = 0;
    830 
    831 
    832     iEndOfFrameFlagOut = 0;
    833     iKeyFrameFlagOut = 0;
    834     iEndOfNALFlagOut = 0;
    835 
    836     //if timescale value is 1 000 000 - it means that
    837     //timestamp is expressed in units of 1/10^6 (i.e. microseconds)
    838 
    839     iTimeScale = 1000000;
    840     iInTimeScale = 1000;
    841     iOutTimeScale = 1000;
    842 
    843     iInputTimestampClock.set_timescale(iInTimeScale); // keep the timescale set to input timestamp
    844 
    845 
    846 
    847     // counts output frames (for logging)
    848     iFrameCounter = 0;
    849     iInFormat = PVMF_MIME_FORMAT_UNKNOWN;
    850     iOutFormat = PVMF_MIME_FORMAT_UNKNOWN;
    851 
    852     // zero out encoder param structure
    853 
    854     oscl_memset(&iVideoInputFormat, 0, sizeof(iVideoInputFormat));
    855 
    856     // set default values
    857     iVideoInputFormat.iFrameWidth = DEFAULT_FRAME_WIDTH;
    858     iVideoInputFormat.iFrameHeight = DEFAULT_FRAME_HEIGHT;
    859     iVideoInputFormat.iFrameRate = (float)DEFAULT_FRAME_RATE;
    860     iVideoInputFormat.iFrameOrientation = 0;
    861 
    862     oscl_memset(&iVideoEncodeParam, 0, sizeof(iVideoEncodeParam));
    863 
    864     iVideoEncodeParam.iEncodeID = 0;
    865     iVideoEncodeParam.iNumLayer = 1;
    866     iVideoEncodeParam.iFrameWidth[0] = DEFAULT_FRAME_WIDTH;
    867     iVideoEncodeParam.iFrameHeight[0] = DEFAULT_FRAME_HEIGHT;
    868     iVideoEncodeParam.iBitRate[0] = DEFAULT_BITRATE;
    869     iVideoEncodeParam.iFrameRate[0] = (float)DEFAULT_FRAME_RATE;
    870     iVideoEncodeParam.iFrameQuality = 10;
    871     iVideoEncodeParam.iSceneDetection = false;
    872     iVideoEncodeParam.iRVLCEnable = false;
    873     iVideoEncodeParam.iIFrameInterval = DEFAULT_I_FRAME_INTERVAL;
    874     iVideoEncodeParam.iBufferDelay = (float)0.2;
    875     iVideoEncodeParam.iShortHeader = false;
    876     iVideoEncodeParam.iDataPartitioning = false;
    877     iVideoEncodeParam.iResyncMarker = true;
    878 
    879     // set the default rate control type to variable bit rate control
    880     // since it has better performance
    881     iVideoEncodeParam.iRateControlType = PVMFVEN_RATE_CONTROL_VBR;
    882     iVideoEncodeParam.iIquant[0] = 15;
    883     iVideoEncodeParam.iPquant[0] = 12;
    884     iVideoEncodeParam.iBquant[0] = 12;
    885     iVideoEncodeParam.iSearchRange = 16;
    886     iVideoEncodeParam.iMV8x8 = false;
    887     iVideoEncodeParam.iMVHalfPel = true;
    888     iVideoEncodeParam.iPacketSize = 256;
    889     iVideoEncodeParam.iNoCurrentSkip = false;
    890     iVideoEncodeParam.iNoFrameSkip = false;
    891     iVideoEncodeParam.iClipDuration = 0;
    892     iVideoEncodeParam.iProfileLevel = EI_CORE_LEVEL2;
    893     /////////////////AVC SPECIFIC///////////////////////////
    894     iVideoEncodeParam.iEncMode = EI_ENCMODE_RECORDER;
    895     iVideoEncodeParam.iAVCProfile = EI_PROFILE_BASELINE;
    896     iVideoEncodeParam.iAVCLevel = EI_LEVEL_11;
    897 
    898 
    899     oscl_memset(&iAudioInputFormat, 0, sizeof(iAudioInputFormat));
    900     // Currently, set according to AMR values
    901     iAudioInputFormat.iInputInterleaveMode = EINTERLEAVE_LR;
    902     iAudioInputFormat.iInputBitsPerSample = 16;
    903     iAudioInputFormat.iInputNumChannels = 1;
    904     iAudioInputFormat.iInputSamplingRate = 8000;
    905 
    906     oscl_memset(&iAudioEncodeParam, 0, sizeof(iAudioEncodeParam));
    907 
    908     iAudioEncodeParam.iMaxNumOutputFramesPerBuffer = MAX_NUM_AMR_FRAMES_PER_BUFFER;
    909     iAudioEncodeParam.iAMRBitrate = GSM_AMR_12_2;
    910     iAudioEncodeParam.iOutputBitrate = 24000;
    911     iAudioEncodeParam.iOutputNumChannels = iAudioInputFormat.iInputNumChannels;
    912     iAudioEncodeParam.iOutputSamplingRate = iAudioInputFormat.iInputSamplingRate;
    913 
    914 
    915 #ifdef _TEST_AE_ERROR_HANDLING
    916     iErrorHandlingInit = false;
    917     iErrorHandlingEncodeCount = 0;
    918     iCountFrames = 0;
    919     iErrorDataPathStall = 0;
    920     iErrorNodeCmd = 0;
    921     iErrorConfigHeader = false;
    922     iErrorEncodeFlag = 0;
    923 #endif
    924 
    925     iInputTimestampClock.set_clock(iBOSTimestamp, 0);
    926     iOMXTicksTimestamp = ConvertTimestampIntoOMXTicks(iInputTimestampClock);
    927 
    928     sendYuvFsi = true;
    929 
    930     iNodeTypeId = LOG_ID_UNKNOWN;
    931     iLogger = PVLogger::GetLoggerObject("PVMFOMXEncNode");
    932     iRunlLogger = PVLogger::GetLoggerObject("Run.PVMFOMXEncNode");
    933     iDataPathLogger = PVLogger::GetLoggerObject("datapath");
    934     iClockLogger = PVLogger::GetLoggerObject("clock");
    935     iDiagnosticsLogger = PVLogger::GetLoggerObject("pvplayerdiagnostics.encnode.OMXEncnode");
    936 }
    937 
    938 /////////////////////////////////////////////////////////////////////////////
    939 // Local Run Routine
    940 /////////////////////////////////////////////////////////////////////////////
    941 void PVMFOMXEncNode::Run()
    942 {
    943     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::Run() In", iNodeTypeId));
    944 
    945     // if reset is in progress, call DoReset again until Reset Msg is sent
    946     if ((iResetInProgress == true) &&
    947             (iResetMsgSent == false) &&
    948             (iCurrentCommand.size() > 0) &&
    949             (iCurrentCommand.front().iCmd == PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_RESET)
    950        )
    951     {
    952         DoReset(iCurrentCommand.front());
    953         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, (0, "PVMFOMXEncNode-%s::Run() - Calling DoReset", iNodeTypeId));
    954         return; // don't do anything else
    955     }
    956     //Check for NODE commands...
    957     if (!iInputCommands.empty())
    958     {
    959         if (ProcessCommand(iInputCommands.front()))
    960         {
    961             if (iInterfaceState != EPVMFNodeCreated
    962                     && (!iInputCommands.empty() || (iInPort && (iInPort->IncomingMsgQueueSize() > 0)) ||
    963                         (iDataIn.GetRep() != NULL)))
    964             {
    965                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, (0, "PVMFOMXEncNode-%s::Run() - rescheduling after process command", iNodeTypeId));
    966                 RunIfNotReady();
    967             }
    968             return;
    969         }
    970 
    971         if (!iInputCommands.empty())
    972         {
    973             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, (0, "PVMFOMXEncNode-%s::Run() - rescheduling to process more commands", iNodeTypeId));
    974             RunIfNotReady();
    975         }
    976     }
    977     else
    978     {
    979         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, (0, "PVMFOMXEncNode-%s::Run() - Input commands empty", iNodeTypeId));
    980     }
    981 
    982     if (((iCurrentCommand.size() == 0) && (iInterfaceState != EPVMFNodeStarted)) ||
    983             ((iCurrentCommand.size() > 0) && (iCurrentCommand.front().iCmd == PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_START) && (iInterfaceState != EPVMFNodeStarted)))
    984     {
    985         // rescheduling because of input data will be handled in Command Processing Part
    986         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, (0, "PVMFOMXEncNode-%s::Run() - Node not in Started state yet", iNodeTypeId));
    987         return;
    988     }
    989 
    990 
    991     // Process port activity, push out all outgoing messages
    992     if (iOutPort)
    993     {
    994         while (iOutPort->OutgoingMsgQueueSize())
    995         {
    996             // if port is busy it is going to wakeup from port ready event
    997             if (!ProcessOutgoingMsg(iOutPort))
    998             {
    999                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, (0, "PVMFOMXEncNode-%s::Run() - Outgoing Port Busy, cannot send more msgs", iNodeTypeId));
   1000                 break;
   1001             }
   1002         }
   1003     }
   1004     int loopCount = 0;
   1005 #if (PVLOGGER_INST_LEVEL >= PVLOGMSG_INST_REL)
   1006     uint32 startticks = OsclTickCount::TickCount();
   1007     uint32 starttime = OsclTickCount::TicksToMsec(startticks);
   1008 #endif
   1009     do // Try to consume all the data from the Input port
   1010     {
   1011         // Process port activity if there is no input data that is being processed
   1012         // Do not accept any input if EOS needs to be sent out
   1013         if (iInPort && (iInPort->IncomingMsgQueueSize() > 0) && (iDataIn.GetRep() == NULL) && !iEndOfDataReached)
   1014         {
   1015             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, (0, "PVMFOMXEncNode-%s::Run() - Getting more input", iNodeTypeId));
   1016             if (!ProcessIncomingMsg(iInPort))
   1017             {
   1018                 //Re-schedule to come back.
   1019                 RunIfNotReady();
   1020                 return;
   1021             }
   1022         }
   1023 
   1024         if (iSendBOS)
   1025         {
   1026             SendBeginOfMediaStreamCommand();
   1027         }
   1028 
   1029         // If in init or ready to encode state, process data in the input port if there is input available and input buffers are present
   1030         // (note: at EOS, iDataIn will not be available)
   1031         if ((iDataIn.GetRep() != NULL) ||
   1032                 ((iNumOutstandingOutputBuffers < iNumOutputBuffers) &&
   1033                  (iProcessingState == EPVMFOMXEncNodeProcessingState_ReadyToEncode) &&
   1034                  (iResetMsgSent == false)) ||
   1035                 ((iDynamicReconfigInProgress == true) && (iResetMsgSent == false))
   1036            )
   1037         {
   1038             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
   1039                             (0, "PVMFOMXEncNode-%s::Run() - Calling HandleProcessingState", iNodeTypeId));
   1040 
   1041             // input data is available, that means there is data to be encoded
   1042             if (HandleProcessingState() != PVMFSuccess)
   1043             {
   1044                 // If HandleProcessingState does not return Success, we must wait for an event
   1045                 // no point in  rescheduling
   1046                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
   1047                                 (0, "PVMFOMXEncNode-%s::Run() - HandleProcessingState did not return Success", iNodeTypeId));
   1048                 return;
   1049             }
   1050         }
   1051         loopCount++;
   1052     }
   1053     while (iInPort &&
   1054             (((iInPort->IncomingMsgQueueSize() > 0) || (iDataIn.GetRep() != NULL)) && (iNumOutstandingInputBuffers < iNumInputBuffers))
   1055             && (!iEndOfDataReached)
   1056             && (iResetMsgSent == false)
   1057           );
   1058 #if (PVLOGGER_INST_LEVEL >= PVLOGMSG_INST_REL)
   1059     uint32 endticks = OsclTickCount::TickCount();
   1060     uint32 endtime = OsclTickCount::TicksToMsec(endticks);
   1061     uint32 timeinloop;
   1062     timeinloop  = (endtime - starttime);
   1063     PVLOGGER_LOGMSG(PVLOGMSG_INST_REL, iRunlLogger, PVLOGMSG_INFO,
   1064                     (0, "PVMFOMXEncNode-%s::Run() - LoopCount = %d, Time spent in loop(in ms) = %d, iNumOutstandingInputBuffers = %d, iNumOutstandingOutputBuffers = %d ", iNodeTypeId,
   1065                      loopCount, timeinloop, iNumOutstandingInputBuffers, iNumOutstandingOutputBuffers));
   1066 #endif
   1067     // EOS processing:
   1068     // first send an empty buffer to OMX component and mark the EOS flag
   1069     // wait for the OMX component to send async event to indicate that it has reached this EOS buffer
   1070     // then, create and send the EOS message downstream
   1071 
   1072     if (iEndOfDataReached && !iDynamicReconfigInProgress)
   1073     {
   1074 
   1075         // if EOS was not sent yet and we have an available input buffer, send EOS buffer to component
   1076         if (!iIsEOSSentToComponent && (iNumOutstandingInputBuffers < iNumInputBuffers))
   1077         {
   1078             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
   1079                             (0, "PVMFOMXEncNode-%s::Run() - Sending EOS marked buffer To Component ", iNodeTypeId));
   1080 
   1081             iIsEOSSentToComponent = true;
   1082 
   1083 
   1084             // if the component is not yet initialized or if it's in the middle of port reconfig,
   1085             // don't send EOS buffer to component. It does not care. Just set the flag as if we received
   1086             // EOS from the component to enable sending EOS downstream
   1087             if (iProcessingState != EPVMFOMXEncNodeProcessingState_ReadyToEncode)
   1088             {
   1089 
   1090                 iIsEOSReceivedFromComponent = true;
   1091             }
   1092             else if (!SendEOSBufferToOMXComponent())
   1093             {
   1094                 // for some reason, Component can't receive the EOS buffer
   1095                 // it could be that it is not initialized yet (because EOS could be the first msg). In this case,
   1096                 // send the EOS downstream anyway
   1097                 iIsEOSReceivedFromComponent = true;
   1098             }
   1099         }
   1100 
   1101         // DV: we must wait for event (acknowledgment from component)
   1102         // before sending EOS downstream. This is because OMX Component will send
   1103         // the EOS event only after processing remaining buffers
   1104 
   1105         if (iIsEOSReceivedFromComponent)
   1106         {
   1107 
   1108             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
   1109                             (0, "PVMFOMXEncNode-%s::Run() - Received EOS from component, Sending EOS msg downstream ", iNodeTypeId));
   1110 
   1111             if (iOutPort && iOutPort->IsOutgoingQueueBusy())
   1112             {
   1113                 // note: we already tried to empty the outgoing q. If it's still busy,
   1114                 // it means that output port is busy. Just return and wait for the port to become free.
   1115                 // this will wake up the node and it will send out a msg from the q etc.
   1116                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
   1117                                 (0, "PVMFOMXEncNode-%s::Run() - - EOS cannot be sent downstream, outgoing queue busy - wait", iNodeTypeId));
   1118                 return;
   1119             }
   1120 
   1121             if (SendEndOfTrackCommand()) // this will only q the EOS
   1122             {
   1123                 // EOS send downstream OK, so reset the flag
   1124                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
   1125                                 (0, "PVMFOMXEncNode-%s::Run() - EOS was queued to be sent downstream", iNodeTypeId));
   1126 
   1127                 iEndOfDataReached = false; // to resume normal processing, reset the flags
   1128                 iIsEOSSentToComponent = false;
   1129                 iIsEOSReceivedFromComponent = false;
   1130 
   1131                 RunIfNotReady(); // Run again to send out the EOS msg from the outgoing q, and resume
   1132                 // normal processing
   1133 
   1134                 // END OF STREAM EVENT reported by the downstream node.
   1135                 //ReportInfoEvent(PVMFInfoEndOfData);
   1136             }
   1137         }
   1138         else
   1139         {
   1140             // keep sending output buffers, it's possible that the component needs to flush output
   1141             //  data at the end
   1142             while (iNumOutstandingOutputBuffers < iNumOutputBuffers)
   1143             {
   1144                 if (!SendOutputBufferToOMXComponent())
   1145                     break;
   1146             }
   1147         }
   1148 
   1149     }
   1150 
   1151 
   1152     //Check for flash command complition...
   1153     if (iInPort && iOutPort && (iCurrentCommand.size() > 0) &&
   1154             (iCurrentCommand.front().iCmd == PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_FLUSH) &&
   1155             (iInPort->IncomingMsgQueueSize() == 0) &&
   1156             (iOutPort->OutgoingMsgQueueSize() == 0) &&
   1157             (iDataIn.GetRep() == NULL) &&
   1158             (iNumOutstandingOutputBuffers == iNumOutputBuffers) && // all output buffers are with the component or outstanding
   1159             (iNumOutstandingInputBuffers == 0) // all input buffers were processed and returned. These 2 conditions mean the component is idle
   1160        )
   1161     {
   1162         //flush command is almost completed
   1163         //Debug check-- all the port queues should be empty at this point.
   1164         OMX_ERRORTYPE err = OMX_ErrorNone;
   1165         OMX_STATETYPE sState = OMX_StateInvalid;
   1166 
   1167         OSCL_ASSERT(iInPort->IncomingMsgQueueSize() == 0 && iOutPort->OutgoingMsgQueueSize() == 0);
   1168 
   1169         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, (0, "PVMFOMXEncNode-%s::Run() - Flush pending", iNodeTypeId));
   1170 
   1171         // now, drive the state of the omx component to IDLE - wait for the callback from the component and send cmd complete from there
   1172         iDataIn.Unbind();
   1173         iPreviousMediaData.Unbind(); // make sure nothing is holding this data
   1174         if ((iOutFormat == PVMF_MIME_H264_VIDEO_MP4) || (iOutFormat == PVMF_MIME_H264_VIDEO_RAW))
   1175         {
   1176             // prepare for next start
   1177             iFirstNAL = true;
   1178         }
   1179 
   1180         // Clear the data flags
   1181 
   1182         iEndOfDataReached = false;
   1183         iIsEOSSentToComponent = false;
   1184         iIsEOSReceivedFromComponent = false;
   1185 
   1186 
   1187         iDoNotSendOutputBuffersDownstreamFlag = true; // stop sending output buffers downstream
   1188         iDoNotSaveInputBuffersFlag = true;
   1189 
   1190 
   1191         //Get state of OpenMAX encoder
   1192         err = OMX_GetState(iOMXEncoder, &sState);
   1193         if (err != OMX_ErrorNone)
   1194         {
   1195             //Error condition report
   1196             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   1197                             (0, "PVMFOMXEncNode-%s::Run(): Flush pending - Can't get State of encoder!", iNodeTypeId));
   1198 
   1199             sState = OMX_StateInvalid;
   1200         }
   1201 
   1202         if ((sState == OMX_StateExecuting) || (sState == OMX_StatePause))
   1203         {
   1204             /* Change state to OMX_StateIdle from OMX_StateExecuting or OMX_StatePause. */
   1205 
   1206             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1207                             (0, "PVMFOMXEncNode-%s::Run(): Flush pending:  Changing Component State Executing->Idle or Pause->Idle", iNodeTypeId));
   1208 
   1209             err = OMX_SendCommand(iOMXEncoder, OMX_CommandStateSet, OMX_StateIdle, NULL);
   1210             if (err != OMX_ErrorNone)
   1211             {
   1212                 //Error condition report
   1213                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   1214                                 (0, "PVMFOMXEncNode-%s::Run(): Flush pending : Can't send StateSet command to encoder!", iNodeTypeId));
   1215 
   1216                 CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFErrInvalidState);
   1217                 return;
   1218             }
   1219 
   1220             // prevent the node from sending more buffers etc.
   1221             // if port reconfiguration is in process, let the state remain one of the port config states
   1222             //  if there is a start command, we can do it seemlessly (by continuing the port reconfig)
   1223             if (iProcessingState == EPVMFOMXEncNodeProcessingState_ReadyToEncode)
   1224                 iProcessingState = EPVMFOMXEncNodeProcessingState_Stopping;
   1225 
   1226         }
   1227         else
   1228         {
   1229             //Error condition report
   1230             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   1231                             (0, "PVMFOMXEncNode-%s::Run(): Flush pending : Encoder is not in the Executing or Pause state!", iNodeTypeId));
   1232 
   1233             CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFErrInvalidState);
   1234             return;
   1235         }
   1236 
   1237 
   1238     }
   1239 
   1240     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::Run() Out", iNodeTypeId));
   1241 }
   1242 
   1243 /////////////////////////////////////////////////////////////////////////////
   1244 // This routine will dispatch recived commands
   1245 /////////////////////////////////////////////////////////////////////////////
   1246 bool PVMFOMXEncNode::ProcessCommand(PVMFOMXEncNodeCommand& aCmd)
   1247 {
   1248     //normally this node will not start processing one command
   1249     //until the prior one is finished.  However, a hi priority
   1250     //command such as Cancel must be able to interrupt a command
   1251     //in progress.
   1252     if (!iCurrentCommand.empty() && !aCmd.hipri())
   1253         return false;
   1254 
   1255     switch (aCmd.iCmd)
   1256     {
   1257         case PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_QUERYUUID:
   1258             DoQueryUuid(aCmd);
   1259             break;
   1260 
   1261         case PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_QUERYINTERFACE:
   1262             DoQueryInterface(aCmd);
   1263             break;
   1264 
   1265         case PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_REQUESTPORT:
   1266             DoRequestPort(aCmd);
   1267             break;
   1268 
   1269         case PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_RELEASEPORT:
   1270             DoReleasePort(aCmd);
   1271             break;
   1272 
   1273         case PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_INIT:
   1274             DoInit(aCmd);
   1275             break;
   1276 
   1277         case PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_PREPARE:
   1278             DoPrepare(aCmd);
   1279             break;
   1280 
   1281         case PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_START:
   1282             DoStart(aCmd);
   1283             break;
   1284 
   1285         case PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_STOP:
   1286             DoStop(aCmd);
   1287             break;
   1288 
   1289         case PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_FLUSH:
   1290             DoFlush(aCmd);
   1291             break;
   1292 
   1293         case PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_PAUSE:
   1294             DoPause(aCmd);
   1295             break;
   1296 
   1297         case PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_RESET:
   1298             DoReset(aCmd);
   1299             break;
   1300 
   1301         case PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_CANCELCMD:
   1302             DoCancelCommand(aCmd);
   1303             break;
   1304 
   1305         case PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_CANCELALL:
   1306             DoCancelAllCommands(aCmd);
   1307             break;
   1308 
   1309         case PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_GETNODEMETADATAKEY:
   1310         {
   1311             PVMFStatus retval = DoGetNodeMetadataKey(aCmd);
   1312             CommandComplete(iInputCommands, aCmd, retval);
   1313         }
   1314         break;
   1315 
   1316         case PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_GETNODEMETADATAVALUE:
   1317         {
   1318             PVMFStatus retval = DoGetNodeMetadataValue(aCmd);
   1319             CommandComplete(iInputCommands, aCmd, retval);
   1320         }
   1321         break;
   1322 
   1323         default://unknown command type
   1324             CommandComplete(iInputCommands, aCmd, PVMFFailure);
   1325             break;
   1326     }
   1327 
   1328     return true;
   1329 }
   1330 
   1331 /////////////////////////////////////////////////////////////////////////////
   1332 // This routine will process incomming message from the port
   1333 /////////////////////////////////////////////////////////////////////////////
   1334 bool PVMFOMXEncNode::ProcessIncomingMsg(PVMFPortInterface* aPort)
   1335 {
   1336     //Called by the AO to process one buffer off the port's
   1337     //incoming data queue.  This routine will dequeue and
   1338     //dispatch the data.
   1339 
   1340     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1341                     (0, "0x%x PVMFOMXEncNode-%s::ProcessIncomingMsg: aPort=0x%x", this, iNodeTypeId, aPort));
   1342 
   1343     PVMFStatus status = PVMFFailure;
   1344 
   1345 
   1346     //#define SIMULATE_BOS
   1347 #ifdef SIMULATE_BOS
   1348 
   1349     if (((PVMFOMXEncPort*)aPort)->iNumFramesConsumed == 6))
   1350     {
   1351 
   1352         PVMFSharedMediaCmdPtr BOSCmdPtr = PVMFMediaCmd::createMediaCmd();
   1353 
   1354         // Set the format ID to BOS
   1355         BOSCmdPtr->setFormatID(PVMF_MEDIA_CMD_BOS_FORMAT_ID);
   1356 
   1357         // Set the timestamp
   1358         BOSCmdPtr->setTimestamp(201);
   1359         BOSCmdPtr->setStreamID(0);
   1360 
   1361         // Convert to media message and send it out
   1362         PVMFSharedMediaMsgPtr mediaMsgOut;
   1363         convertToPVMFMediaCmdMsg(mediaMsgOut, BOSCmdPtr);
   1364 
   1365         //store the stream id and time stamp of bos message
   1366         iStreamID = mediaMsgOut->getStreamID();
   1367         iBOSTimestamp = mediaMsgOut->getTimestamp();
   1368 
   1369         iInputTimestampClock.set_clock(iBOSTimestamp, 0);
   1370         iOMXTicksTimestamp = ConvertTimestampIntoOMXTicks(iInputTimestampClock);
   1371 
   1372         iSendBOS = true;
   1373 
   1374 #ifdef _DEBUG
   1375         printf("PVMFOMXEncNode-%s::ProcessIncomingMsg() SIMULATED BOS\n", iNodeTypeId);
   1376 #endif
   1377         ((PVMFOMXEncPort*)aPort)->iNumFramesConsumed++;
   1378         return true;
   1379 
   1380     }
   1381 #endif
   1382 //#define SIMULATE_PREMATURE_EOS
   1383 #ifdef SIMULATE_PREMATURE_EOS
   1384     if (((PVMFOMXEncPort*)aPort)->iNumFramesConsumed == 5)
   1385     {
   1386         PVMFSharedMediaCmdPtr EOSCmdPtr = PVMFMediaCmd::createMediaCmd();
   1387 
   1388         // Set the format ID to EOS
   1389         EOSCmdPtr->setFormatID(PVMF_MEDIA_CMD_EOS_FORMAT_ID);
   1390 
   1391         // Set the timestamp
   1392         EOSCmdPtr->setTimestamp(200);
   1393 
   1394         // Convert to media message and send it out
   1395         PVMFSharedMediaMsgPtr mediaMsgOut;
   1396         convertToPVMFMediaCmdMsg(mediaMsgOut, EOSCmdPtr);
   1397 
   1398         ((PVMFOMXEncPort*)aPort)->iNumFramesConsumed++;
   1399 
   1400         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1401                         (0, "PVMFOMXEncNode-%s::ProcessIncomingMsg: SIMULATED EOS", iNodeTypeId));
   1402 #ifdef _DEBUG
   1403         printf("PVMFOMXEncNode-%s::ProcessIncomingMsg() SIMULATED EOS\n", iNodeTypeId);
   1404 #endif
   1405         // Set EOS flag
   1406         iEndOfDataReached = true;
   1407         // Save the timestamp for the EOS cmd
   1408         iEndOfDataTimestamp = mediaMsgOut->getTimestamp();
   1409 
   1410         return true;
   1411     }
   1412 
   1413 #endif
   1414 
   1415 
   1416 
   1417     PVMFSharedMediaMsgPtr msg;
   1418 
   1419     status = aPort->DequeueIncomingMsg(msg);
   1420     if (status != PVMFSuccess)
   1421 {
   1422     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   1423                     (0, "0x%x PVMFOMXEncNode-%s::ProcessIncomingMsg: Error - DequeueIncomingMsg failed", this, iNodeTypeId));
   1424         return false;
   1425     }
   1426 
   1427     if (msg->getFormatID() == PVMF_MEDIA_CMD_BOS_FORMAT_ID)
   1428     {
   1429         //store the stream id and time stamp of bos message
   1430         iStreamID = msg->getStreamID();
   1431         iBOSTimestamp = msg->getTimestamp();
   1432 
   1433         // we need to initialize the timestamp here - so that updates later on are accurate (in terms of rollover etc)
   1434         iInputTimestampClock.set_clock(iBOSTimestamp, 0);
   1435         iOMXTicksTimestamp = ConvertTimestampIntoOMXTicks(iInputTimestampClock);
   1436 
   1437         iSendBOS = true;
   1438 
   1439         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1440                         (0, "PVMFOMXEncNode-%s::ProcessIncomingMsg: Received BOS stream %d, timestamp %d", iNodeTypeId, iStreamID, iBOSTimestamp));
   1441         ((PVMFOMXEncPort*)aPort)->iNumFramesConsumed++;
   1442         return true;
   1443     }
   1444     else if (msg->getFormatID() == PVMF_MEDIA_CMD_EOS_FORMAT_ID)
   1445     {
   1446         // Set EOS flag
   1447         iEndOfDataReached = true;
   1448         // Save the timestamp for the EOS cmd
   1449         iEndOfDataTimestamp = msg->getTimestamp();
   1450 
   1451         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1452                         (0, "PVMFOMXEncNode-%s::ProcessIncomingMsg: Received EOS", iNodeTypeId));
   1453 
   1454         ((PVMFOMXEncPort*)aPort)->iNumFramesConsumed++;
   1455         return true; // do not do conversion into media data, just set the flag and leave
   1456     }
   1457 
   1458     convertToPVMFMediaData(iDataIn, msg);
   1459 
   1460 
   1461     iCurrFragNum = 0; // for new message, reset the fragment counter
   1462 
   1463 
   1464     ((PVMFOMXEncPort*)aPort)->iNumFramesConsumed++;
   1465     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::ProcessIncomingMsg() Received %d frames", iNodeTypeId, ((PVMFOMXEncPort*)aPort)->iNumFramesConsumed));
   1466 
   1467 //return true if we processed an activity...
   1468     return true;
   1469 }
   1470 
   1471 /////////////////////////////////////////////////////////////////////////////
   1472 // This routine will process outgoing message by sending it into output the port
   1473 /////////////////////////////////////////////////////////////////////////////
   1474 bool PVMFOMXEncNode::ProcessOutgoingMsg(PVMFPortInterface* aPort)
   1475 {
   1476     //Called by the AO to process one message off the outgoing
   1477     //message queue for the given port.  This routine will
   1478     //try to send the data to the connected port.
   1479 
   1480     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1481                     (0, "0x%x PVMFOMXEncNode-%s::ProcessOutgoingMsg: aPort=0x%x", this, iNodeTypeId, aPort));
   1482 
   1483     PVMFStatus status = aPort->Send();
   1484     if (status == PVMFErrBusy)
   1485     {
   1486         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
   1487                         (0, "0x%x PVMFOMXEncNode-%s::ProcessOutgoingMsg: Connected port goes into busy state", this, iNodeTypeId));
   1488     }
   1489 
   1490     //Report any unexpected failure in port processing...
   1491     //(the InvalidState error happens when port input is suspended,
   1492     //so don't report it.)
   1493     if (status != PVMFErrBusy
   1494             && status != PVMFSuccess
   1495             && status != PVMFErrInvalidState)
   1496     {
   1497         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   1498                         (0, "0x%x PVMFOMXEncNode-%s::ProcessOutgoingMsg: Error - ProcessPortActivity failed. port=0x%x, type=%d",
   1499                          this, iNodeTypeId, iOutPort, PVMF_PORT_ACTIVITY_OUTGOING_MSG));
   1500         ReportErrorEvent(PVMFErrPortProcessing);
   1501     }
   1502 
   1503     //return true if we processed an activity...
   1504     return (status != PVMFErrBusy);
   1505 }
   1506 
   1507 /////////////////////////////////////////////////////////////////////////////
   1508 // This routine will process received data usign State Machine
   1509 /////////////////////////////////////////////////////////////////////////////
   1510 PVMFStatus PVMFOMXEncNode::HandleProcessingState()
   1511 {
   1512     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::HandleProcessingState() In", iNodeTypeId));
   1513 
   1514     PVMFStatus status = PVMFSuccess;
   1515 
   1516     switch (iProcessingState)
   1517     {
   1518 
   1519             // The FOLLOWING 4 states handle Dynamic Port Reconfiguration
   1520         case EPVMFOMXEncNodeProcessingState_PortReconfig:
   1521         {
   1522             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1523                             (0, "PVMFOMXEncNode-%s::HandleProcessingState() Port Reconfiguration -> Sending Port Disable Command", iNodeTypeId));
   1524 
   1525             // port reconfiguration is required. Only one port at a time is disabled and then re-enabled after buffer resizing
   1526             OMX_SendCommand(iOMXEncoder, OMX_CommandPortDisable, iPortIndexForDynamicReconfig, NULL);
   1527             // the port will now start returning outstanding buffers
   1528             // set the flag to prevent output from going downstream (in case of output port being reconfigd)
   1529             // set the flag to prevent input from being saved and returned to component (in case of input port being reconfigd)
   1530             // set the state to wait for port saying it is disabled
   1531             if (iPortIndexForDynamicReconfig == iOutputPortIndex)
   1532             {
   1533                 iDoNotSendOutputBuffersDownstreamFlag = true;
   1534             }
   1535             else if (iPortIndexForDynamicReconfig == iInputPortIndex)
   1536             {
   1537                 iDoNotSaveInputBuffersFlag = true;
   1538 
   1539             }
   1540             iProcessingState = EPVMFOMXEncNodeProcessingState_WaitForBufferReturn;
   1541 
   1542 
   1543             // fall through to the next case to check if all buffers are already back
   1544         }
   1545 
   1546         case EPVMFOMXEncNodeProcessingState_WaitForBufferReturn:
   1547         {
   1548             // as buffers are coming back, Run may be called, wait until all buffers are back, then Free them all
   1549 
   1550             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1551                             (0, "PVMFOMXEncNode-%s::HandleProcessingState() Port Reconfiguration -> WaitForBufferReturn ", iNodeTypeId));
   1552             // check if it's output port being reconfigured
   1553             if (iPortIndexForDynamicReconfig == iOutputPortIndex)
   1554             {
   1555                 // if all buffers have returned, free them
   1556                 if (iNumOutstandingOutputBuffers == 0)
   1557                 {
   1558                     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1559                                     (0, "PVMFOMXEncNode-%s::HandleProcessingState() Port Reconfiguration -> all output buffers are back, free them", iNodeTypeId));
   1560                     if (false == iOutputBuffersFreed)
   1561                     {
   1562                         if (!FreeBuffersFromComponent(iOutBufMemoryPool, // allocator
   1563                                                       iOutputAllocSize,  // size to allocate from pool (hdr only or hdr+ buffer)
   1564                                                       iNumOutputBuffers, // number of buffers
   1565                                                       iOutputPortIndex, // port idx
   1566                                                       false // this is not input
   1567                                                      ))
   1568                         {
   1569                             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   1570                                             (0, "PVMFOMXEncNode-%s::HandleProcessingState() Port Reconfiguration -> Cannot free output buffers ", iNodeTypeId));
   1571 
   1572                             SetState(EPVMFNodeError);
   1573                             ReportErrorEvent(PVMFErrNoMemory);
   1574                             return PVMFErrNoMemory;
   1575                         }
   1576                     }
   1577                     // if the callback (that port is disabled) has not arrived yet, wait for it
   1578                     // if it has arrived, it will set the state to PortReEnable
   1579                     if (iProcessingState != EPVMFOMXEncNodeProcessingState_PortReEnable)
   1580                         iProcessingState = EPVMFOMXEncNodeProcessingState_WaitForPortDisable;
   1581 
   1582                     status = PVMFSuccess; // allow rescheduling of the node potentially
   1583                 }
   1584                 else
   1585                     status = PVMFErrNoMemory; // must wait for buffers to come back. No point in automatic rescheduling
   1586                 // but each buffer will reschedule the node when it comes in
   1587             }
   1588             else
   1589             {
   1590                 // this is input port
   1591 
   1592                 // if all buffers have returned, free them
   1593                 if (iNumOutstandingInputBuffers == 0)
   1594                 {
   1595 
   1596                     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1597                                     (0, "PVMFOMXEncNode-%s::HandleProcessingState() Port Reconfiguration -> all input buffers are back, free them", iNodeTypeId));
   1598                     if (false == iInputBuffersFreed)
   1599                     {
   1600                         if (!FreeBuffersFromComponent(iInBufMemoryPool, // allocator
   1601                                                       iInputAllocSize,   // size to allocate from pool (hdr only or hdr+ buffer)
   1602                                                       iNumInputBuffers, // number of buffers
   1603                                                       iInputPortIndex, // port idx
   1604                                                       true // this is input
   1605                                                      ))
   1606                         {
   1607                             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   1608                                             (0, "PVMFOMXEncNode-%s::HandleProcessingState() Port Reconfiguration -> Cannot free input buffers ", iNodeTypeId));
   1609 
   1610                             SetState(EPVMFNodeError);
   1611                             ReportErrorEvent(PVMFErrNoMemory);
   1612                             return PVMFErrNoMemory;
   1613 
   1614                         }
   1615                     }
   1616                     // if the callback (that port is disabled) has not arrived yet, wait for it
   1617                     // if it has arrived, it will set the state to PortReEnable
   1618                     if (iProcessingState != EPVMFOMXEncNodeProcessingState_PortReEnable)
   1619                         iProcessingState = EPVMFOMXEncNodeProcessingState_WaitForPortDisable;
   1620 
   1621                     status = PVMFSuccess; // allow rescheduling of the node
   1622                 }
   1623                 else
   1624                     status = PVMFErrNoMemory; // must wait for buffers to come back. No point in automatic
   1625                 // rescheduling. Each buffer will reschedule the node
   1626                 // when it comes in
   1627             }
   1628 
   1629 
   1630             // the state will be changed to PortReEnable once we get confirmation that Port was actually disabled
   1631             break;
   1632         }
   1633 
   1634         case EPVMFOMXEncNodeProcessingState_WaitForPortDisable:
   1635         {
   1636 
   1637             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1638                             (0, "PVMFOMXEncNode-%s::HandleProcessingState() Port Reconfiguration -> wait for port disable callback", iNodeTypeId));
   1639             // do nothing. Just wait for the port to become disabled (we'll get event from component, which will
   1640             // transition the state to PortReEnable
   1641             status = PVMFErrNoMemory; // prevent Rescheduling the node
   1642             break;
   1643         }
   1644 
   1645         case EPVMFOMXEncNodeProcessingState_PortReEnable:
   1646         {
   1647 
   1648             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1649                             (0, "PVMFOMXEncNode-%s::HandleProcessingState() Port Reconfiguration -> Sending reenable port command", iNodeTypeId));
   1650             // set the port index so that we get parameters for the proper port
   1651             iParamPort.nPortIndex = iPortIndexForDynamicReconfig;
   1652             // iParamPort.nVersion = OMX_VERSION;
   1653 
   1654             // get new parameters of the port
   1655             OMX_GetParameter(iOMXEncoder, OMX_IndexParamPortDefinition, &iParamPort);
   1656 
   1657             // send command for port re-enabling (for this to happen, we must first recreate the buffers)
   1658             OMX_SendCommand(iOMXEncoder, OMX_CommandPortEnable, iPortIndexForDynamicReconfig, NULL);
   1659 
   1660             // is this output port?
   1661             if (iPortIndexForDynamicReconfig == iOutputPortIndex)
   1662             {
   1663                 iOMXComponentOutputBufferSize = ((iParamPort.format.video.nFrameWidth + 15) & (~15)) * ((iParamPort.format.video.nFrameHeight + 15) & (~15)) * 3 / 2;
   1664 
   1665                 // check the new buffer size
   1666                 if (iInPort)
   1667                 {
   1668                     if (((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO ||
   1669                             ((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO_MP4 ||
   1670                             ((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO_RAW ||
   1671                             ((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_M4V ||
   1672                             ((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_H2631998 ||
   1673                             ((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_H2632000)
   1674                     {
   1675                         iOMXComponentOutputBufferSize = ((iParamPort.format.video.nFrameWidth + 15) & (~15)) * ((iParamPort.format.video.nFrameHeight + 15) & (~15)) * 3 / 2;
   1676                     }
   1677                     else if (((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_WMV)
   1678                     {
   1679                         // This is a requirement for the WMV encoder that we have currently
   1680                         iOMXComponentOutputBufferSize = ((iParamPort.format.video.nFrameWidth + 3) & (~3)) * (iParamPort.format.video.nFrameHeight) * 3 / 2;
   1681                     }
   1682                     else
   1683                     {
   1684                         OSCL_ASSERT(false);
   1685                     }
   1686                 }
   1687                 // set the new width / height
   1688                 iYUVWidth =  iParamPort.format.video.nFrameWidth;
   1689                 iYUVHeight = iParamPort.format.video.nFrameHeight;
   1690 
   1691                 if (iOMXComponentOutputBufferSize < iParamPort.nBufferSize)
   1692                     iOMXComponentOutputBufferSize = iParamPort.nBufferSize;
   1693 
   1694                 // do we need to increase the number of buffers?
   1695                 if (iNumOutputBuffers < iParamPort.nBufferCountMin)
   1696                     iNumOutputBuffers = iParamPort.nBufferCountMin;
   1697 
   1698                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1699                                 (0, "PVMFOMXEncNode-%s::HandleProcessingState() new output buffers %d, size %d", iNodeTypeId, iNumOutputBuffers, iOMXComponentOutputBufferSize));
   1700 
   1701                 /* Allocate output buffers */
   1702                 if (!CreateOutMemPool(iNumOutputBuffers))
   1703                 {
   1704 
   1705                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   1706                                     (0, "PVMFOMXEncNode-%s::HandleProcessingState() Port Reconfiguration -> Cannot allocate output buffers ", iNodeTypeId));
   1707 
   1708                     SetState(EPVMFNodeError);
   1709                     ReportErrorEvent(PVMFErrNoMemory);
   1710                     return PVMFErrNoMemory;
   1711                 }
   1712 
   1713                 if (!ProvideBuffersToComponent(iOutBufMemoryPool, // allocator
   1714                                                iOutputAllocSize,     // size to allocate from pool (hdr only or hdr+ buffer)
   1715                                                iNumOutputBuffers, // number of buffers
   1716                                                iOMXComponentOutputBufferSize, // actual buffer size
   1717                                                iOutputPortIndex, // port idx
   1718                                                iOMXComponentSupportsExternalOutputBufferAlloc, // can component use OMX_UseBuffer
   1719                                                false // this is not input
   1720                                               ))
   1721                 {
   1722 
   1723 
   1724                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   1725                                     (0, "PVMFOMXEncNode-%s::HandleProcessingState() Port Reconfiguration -> Cannot provide output buffers to component", iNodeTypeId));
   1726 
   1727                     SetState(EPVMFNodeError);
   1728                     ReportErrorEvent(PVMFErrNoMemory);
   1729                     return PVMFErrNoMemory;
   1730 
   1731                 }
   1732 
   1733                 // do not drop output any more, i.e. enable output to be sent downstream
   1734                 iDoNotSendOutputBuffersDownstreamFlag = false;
   1735 
   1736 
   1737             }
   1738             else
   1739             {
   1740                 // this is input port
   1741 
   1742                 iOMXComponentInputBufferSize = iParamPort.nBufferSize;
   1743                 // do we need to increase the number of buffers?
   1744                 if (iNumInputBuffers < iParamPort.nBufferCountMin)
   1745                     iNumInputBuffers = iParamPort.nBufferCountMin;
   1746 
   1747                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1748                                 (0, "PVMFOMXEncNode-%s::HandleProcessingState() new buffers %d, size %d", iNodeTypeId, iNumInputBuffers, iOMXComponentInputBufferSize));
   1749 
   1750                 /* Allocate input buffers */
   1751                 if (!CreateInputMemPool(iNumInputBuffers))
   1752                 {
   1753                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   1754                                     (0, "PVMFOMXEncNode-%s::HandleProcessingState() Port Reconfiguration -> Cannot allocate new input buffers to component", iNodeTypeId));
   1755 
   1756                     SetState(EPVMFNodeError);
   1757                     ReportErrorEvent(PVMFErrNoMemory);
   1758                     return PVMFErrNoMemory;
   1759                 }
   1760 
   1761                 if (!ProvideBuffersToComponent(iInBufMemoryPool, // allocator
   1762                                                iInputAllocSize,  // size to allocate from pool (hdr only or hdr+ buffer)
   1763                                                iNumInputBuffers, // number of buffers
   1764                                                iOMXComponentInputBufferSize, // actual buffer size
   1765                                                iInputPortIndex, // port idx
   1766                                                iOMXComponentSupportsExternalInputBufferAlloc, // can component use OMX_UseBuffer
   1767                                                true // this is input
   1768                                               ))
   1769                 {
   1770 
   1771 
   1772                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   1773                                     (0, "PVMFOMXEncNode-%s::HandleProcessingState() Port Reconfiguration -> Cannot provide new input buffers to component", iNodeTypeId));
   1774 
   1775                     SetState(EPVMFNodeError);
   1776                     ReportErrorEvent(PVMFErrNoMemory);
   1777                     return PVMFErrNoMemory;
   1778 
   1779                 }
   1780                 // do not drop partially consumed input
   1781                 iDoNotSaveInputBuffersFlag = false;
   1782 
   1783 
   1784             }
   1785 
   1786             // if the callback that the port was re-enabled has not arrived yet, wait for it
   1787             // if it has arrived, it will set the state to either PortReconfig or to ReadyToEncode
   1788             if (iProcessingState != EPVMFOMXEncNodeProcessingState_PortReconfig &&
   1789                     iProcessingState != EPVMFOMXEncNodeProcessingState_ReadyToEncode)
   1790                 iProcessingState = EPVMFOMXEncNodeProcessingState_WaitForPortEnable;
   1791 
   1792             status = PVMFSuccess; // allow rescheduling of the node
   1793             break;
   1794         }
   1795 
   1796         case EPVMFOMXEncNodeProcessingState_WaitForPortEnable:
   1797         {
   1798             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1799                             (0, "PVMFOMXEncNode-%s::HandleProcessingState() Port Reconfiguration -> wait for port enable callback", iNodeTypeId));
   1800             // do nothing. Just wait for the port to become enabled (we'll get event from component, which will
   1801             // transition the state to ReadyToEncode
   1802             status = PVMFErrNoMemory; // prevent ReScheduling
   1803             break;
   1804         }
   1805 
   1806         // NORMAL DATA FLOW STATE:
   1807         case EPVMFOMXEncNodeProcessingState_ReadyToEncode:
   1808         {
   1809 
   1810             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1811                             (0, "PVMFOMXEncNode-%s::HandleProcessingState() Ready To Encode start", iNodeTypeId));
   1812             // In normal data flow and decoding state
   1813             // Send all available output buffers to the encoder
   1814 
   1815             while (iNumOutstandingOutputBuffers < iNumOutputBuffers)
   1816             {
   1817                 // grab buffer header from the mempool if possible, and send to component
   1818                 if (!SendOutputBufferToOMXComponent())
   1819 
   1820                     break;
   1821 
   1822             }
   1823 
   1824 
   1825             // next, see if partially consumed input buffer needs to be resent back to OMX component
   1826             // NOTE: it is not allowed that the component returns more than 1 partially consumed input buffers
   1827             //       i.e. if a partially consumed input buffer is returned, it is assumed that the OMX component
   1828             //       will be waiting to get data
   1829 
   1830             if (iInputBufferToResendToComponent != NULL)
   1831             {
   1832                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
   1833                                 (0, "PVMFOMXEncNode-%s::HandleProcessingState() Sending previous - partially consumed input back to the OMX component", iNodeTypeId));
   1834 
   1835                 OMX_EmptyThisBuffer(iOMXEncoder, iInputBufferToResendToComponent);
   1836                 iInputBufferToResendToComponent = NULL; // do this only once
   1837             }
   1838             else if ((iNumOutstandingInputBuffers < iNumInputBuffers) && (iDataIn.GetRep() != NULL))
   1839             {
   1840                 // try to get an input buffer header
   1841                 // and send the input data over to the component
   1842                 SendInputBufferToOMXComponent();
   1843             }
   1844 
   1845             status = PVMFSuccess;
   1846             break;
   1847 
   1848 
   1849         }
   1850         case EPVMFOMXEncNodeProcessingState_Stopping:
   1851         {
   1852 
   1853             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1854                             (0, "PVMFOMXEncNode-%s::HandleProcessingState() Stopping -> wait for Component to move from Executing->Idle", iNodeTypeId));
   1855 
   1856 
   1857             status = PVMFErrNoMemory; // prevent rescheduling
   1858             break;
   1859         }
   1860 
   1861         case EPVMFOMXEncNodeProcessingState_WaitForOutgoingQueue:
   1862             status = PVMFErrNoMemory;
   1863             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));
   1864             break;
   1865 
   1866         default:
   1867             break;
   1868     }
   1869 
   1870     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::HandleProcessingState() Out", iNodeTypeId));
   1871 
   1872     return status;
   1873 
   1874 }
   1875 /////////////////////////////////////////////////////////////////////////////
   1876 bool PVMFOMXEncNode::SendOutputBufferToOMXComponent()
   1877 {
   1878     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1879                     (0, "PVMFOMXEncNode-%s::SendOutputBufferToOMXComponent() In", iNodeTypeId));
   1880 
   1881 
   1882     OutputBufCtrlStruct *output_buf = NULL;
   1883     int32  errcode = 0;
   1884     uint32 ii;
   1885 
   1886     // try to get output buffer header
   1887     OSCL_TRY(errcode, output_buf = (OutputBufCtrlStruct *) iOutBufMemoryPool->allocate(iOutputAllocSize));
   1888     if (errcode != 0)
   1889     {
   1890         if (errcode == OsclErrNoResources)
   1891         {
   1892 
   1893             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger,
   1894                             PVLOGMSG_DEBUG, (0, "PVMFOMXEncNode-%s::SendOutputBufferToOMXComponent() No more output buffers in the mempool", iNodeTypeId));
   1895 
   1896             iOutBufMemoryPool->notifyfreechunkavailable(*this, (OsclAny *) iOutBufMemoryPool); // To signal when next deallocate() is called on mempool
   1897 
   1898             return false;
   1899         }
   1900         else
   1901         {
   1902             // Memory allocation for the pool failed
   1903             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   1904                             (0, "PVMFOMXEncNode-%s::SendOutputBufferToOMXComponent() Output mempool error", iNodeTypeId));
   1905 
   1906 
   1907             SetState(EPVMFNodeError);
   1908             ReportErrorEvent(PVMFErrNoMemory);
   1909             return false;
   1910         }
   1911 
   1912     }
   1913 
   1914     //for every allocated buffer, make sure you notify when buffer is released. Keep track of allocated buffers
   1915     // use mempool as context to recognize which buffer (input or output) was returned
   1916     iOutBufMemoryPool->notifyfreechunkavailable(*this, (OsclAny *)iOutBufMemoryPool);
   1917     iNumOutstandingOutputBuffers++;
   1918 
   1919     for (ii = 0; ii < iNumOutputBuffers; ii++)
   1920     {
   1921         if (output_buf == out_ctrl_struct_ptr[ii])
   1922         {
   1923             break;
   1924         }
   1925     }
   1926 
   1927     if (ii == iNumOutputBuffers)
   1928         return false;
   1929 
   1930     output_buf->pBufHdr = (OMX_BUFFERHEADERTYPE *)out_buff_hdr_ptr[ii];
   1931 
   1932 
   1933 
   1934     output_buf->pBufHdr->nFilledLen = 0; // make sure you tell OMX component buffer is empty
   1935     output_buf->pBufHdr->nOffset = 0;
   1936     output_buf->pBufHdr->pAppPrivate = output_buf; // set pAppPrivate to be pointer to output_buf
   1937     // (this is context for future release of this buffer to the mempool)
   1938     // this was done during buffer creation, but still repeat just in case
   1939 
   1940     output_buf->pBufHdr->nFlags = 0; // zero out the flags
   1941     OMX_FillThisBuffer(iOMXEncoder, output_buf->pBufHdr);
   1942 
   1943 
   1944 
   1945     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1946                     (0, "PVMFOMXEncNode-%s::SendOutputBufferToOMXComponent() Out", iNodeTypeId));
   1947 
   1948     return true;
   1949 }
   1950 ////////////////////////////////////////////////////////////////////////////////
   1951 bool PVMFOMXEncNode::NegotiateVideoComponentParameters()
   1952 {
   1953     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1954                     (0, "PVMFOMXEncNode-%s::NegotiateVideoParameters() In", iNodeTypeId));
   1955 
   1956     OMX_ERRORTYPE Err;
   1957     OMX_CONFIG_ROTATIONTYPE InputRotationType;
   1958 
   1959     // first get the number of ports and port indices
   1960     OMX_PORT_PARAM_TYPE VideoPortParameters;
   1961     uint32 NumPorts;
   1962     uint32 ii;
   1963 
   1964     // get starting number
   1965     CONFIG_SIZE_AND_VERSION(VideoPortParameters);
   1966 
   1967     Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamVideoInit, &VideoPortParameters);
   1968     NumPorts = VideoPortParameters.nPorts; // must be at least 2 of them (in&out)
   1969 
   1970     if (Err != OMX_ErrorNone || NumPorts < 2)
   1971     {
   1972         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1973                         (0, "PVMFOMXEncNode-%s::NegotiateVideoComponentParameters() There is insuffucient (%d) ports", iNodeTypeId, NumPorts));
   1974         return false;
   1975     }
   1976 
   1977 
   1978     // loop through video ports starting from the starting index to find index of the first input port
   1979     for (ii = VideoPortParameters.nStartPortNumber ; ii < VideoPortParameters.nStartPortNumber + NumPorts; ii++)
   1980     {
   1981         // get port parameters, and determine if it is input or output
   1982         // if there are more than 2 ports, the first one we encounter that has input direction is picked
   1983 
   1984 
   1985         CONFIG_SIZE_AND_VERSION(iParamPort);
   1986         //port
   1987         iParamPort.nPortIndex = ii; // iInputPortIndex; //OMF_MC_H264D_PORT_INDEX_OF_STREAM;
   1988         Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamPortDefinition, &iParamPort);
   1989 
   1990         if (Err != OMX_ErrorNone)
   1991         {
   1992             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1993                             (0, "PVMFOMXEncNode-%s::NegotiateVideoComponentParameters() Problem negotiating with port %d ", iNodeTypeId, ii));
   1994 
   1995             return false;
   1996         }
   1997 
   1998         if (iParamPort.eDir == OMX_DirInput)
   1999         {
   2000             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2001                             (0, "PVMFOMXEncNode-%s::NegotiateVideoComponentParameters() Found Input port index %d ", iNodeTypeId, ii));
   2002 
   2003             iInputPortIndex = ii;
   2004             break;
   2005         }
   2006     }
   2007     if (ii == VideoPortParameters.nStartPortNumber + NumPorts)
   2008     {
   2009         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2010                         (0, "PVMFOMXEncNode-%s::NegotiateVideoComponentParameters() Cannot find any input port ", iNodeTypeId));
   2011         return false;
   2012     }
   2013 
   2014 
   2015     // loop through video ports starting from the starting index to find index of the first output port
   2016     for (ii = VideoPortParameters.nStartPortNumber ; ii < VideoPortParameters.nStartPortNumber + NumPorts; ii++)
   2017     {
   2018         // get port parameters, and determine if it is input or output
   2019         // if there are more than 2 ports, the first one we encounter that has output direction is picked
   2020 
   2021 
   2022         CONFIG_SIZE_AND_VERSION(iParamPort);
   2023         //port
   2024         iParamPort.nPortIndex = ii;
   2025         Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamPortDefinition, &iParamPort);
   2026 
   2027         if (Err != OMX_ErrorNone)
   2028         {
   2029             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2030                             (0, "PVMFOMXEncNode-%s::NegotiateVideoComponentParameters() Problem negotiating with port %d ", iNodeTypeId, ii));
   2031 
   2032             return false;
   2033         }
   2034 
   2035         if (iParamPort.eDir == OMX_DirOutput)
   2036         {
   2037             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2038                             (0, "PVMFOMXEncNode-%s::NegotiateVideoComponentParameters() Found Output port index %d ", iNodeTypeId, ii));
   2039 
   2040             iOutputPortIndex = ii;
   2041             break;
   2042         }
   2043     }
   2044     if (ii == VideoPortParameters.nStartPortNumber + NumPorts)
   2045     {
   2046         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2047                         (0, "PVMFOMXEncNode-%s::NegotiateVideoComponentParameters() Cannot find any output port ", iNodeTypeId));
   2048         return false;
   2049     }
   2050 
   2051 
   2052 
   2053     // now get input parameters
   2054 
   2055 
   2056     //INPUT PORT
   2057 
   2058     // first check if encode parameters have been set correctly
   2059     if ((0 == iVideoEncodeParam.iFrameWidth[0]) ||
   2060             (0 == iVideoEncodeParam.iFrameHeight[0]) ||
   2061             (0 == iVideoEncodeParam.iFrameRate[0])   ||
   2062             (0 == iVideoEncodeParam.iBitRate[0]) ||
   2063             (0 == iVideoInputFormat.iFrameWidth) ||
   2064             (0 == iVideoInputFormat.iFrameHeight) ||
   2065             (0 == iVideoInputFormat.iFrameRate)
   2066        )
   2067     {
   2068         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2069                         (0, "PVMFOMXEncNode-%s::NegotiateVideoComponentParameters() Encode parameters not set correctly", iNodeTypeId));
   2070         return false;
   2071     }
   2072 
   2073     // first of all, check if the port supports the adequate port format
   2074     OMX_VIDEO_PARAM_PORTFORMATTYPE Video_port_format;
   2075     OMX_COLOR_FORMATTYPE DesiredPortColorFormat;
   2076 
   2077     if (iInFormat == PVMF_MIME_RGB24)
   2078     {
   2079         DesiredPortColorFormat = OMX_COLOR_Format24bitRGB888;
   2080     }
   2081     else if (iInFormat == PVMF_MIME_RGB12)
   2082     {
   2083         DesiredPortColorFormat = OMX_COLOR_Format12bitRGB444;
   2084     }
   2085     else if (iInFormat == PVMF_MIME_YUV420)
   2086     {
   2087         //TODO: get color format from MIO. JJ 03/09/09
   2088         DesiredPortColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
   2089         //DesiredPortColorFormat = OMX_COLOR_FormatYUV420Planar;
   2090     }
   2091     else if (iInFormat == PVMF_MIME_YUV422_INTERLEAVED_UYVY)
   2092     {
   2093         DesiredPortColorFormat = OMX_COLOR_FormatCbYCrY;
   2094     }
   2095     else if (iInFormat == PVMF_MIME_YUV422_INTERLEAVED_YUYV)
   2096     {
   2097         DesiredPortColorFormat = OMX_COLOR_FormatYCbYCr;
   2098     }
   2099     else
   2100     {
   2101         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2102                         (0, "PVMFOMXEncNode-%s::NegotiateVideoComponentParameters() Problem with input port %d color format", iNodeTypeId, iInputPortIndex));
   2103         return false;
   2104     }
   2105 
   2106     CONFIG_SIZE_AND_VERSION(Video_port_format);
   2107 
   2108     Video_port_format.nPortIndex = iInputPortIndex; // set input port as target
   2109 
   2110     // loop over supported formats until we hit the one we want
   2111     // or until the component has no more supported formats (in which case it returns OMX_ErrorNoMore
   2112     Err = OMX_ErrorNone;
   2113     Video_port_format.nIndex = 0; //init the format counter
   2114     while (OMX_ErrorNone == Err)
   2115     {
   2116 
   2117         Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamVideoPortFormat, &Video_port_format);
   2118         if ((OMX_ErrorNone != Err))
   2119         {
   2120             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2121                             (0, "PVMFOMXEncNode-%s::NegotiateVideoComponentParameters() Problem getting port format for input port %d or no desired port format found", iNodeTypeId, iInputPortIndex));
   2122             return false;
   2123         }
   2124 
   2125         if ((Video_port_format.eColorFormat == DesiredPortColorFormat))
   2126             break;
   2127 
   2128         Video_port_format.nIndex ++;
   2129     }
   2130 
   2131     // OK, we've found the desired format, set it as the one used
   2132     Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamVideoPortFormat, &Video_port_format);
   2133     if ((OMX_ErrorNone != Err))
   2134     {
   2135         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2136                         (0, "PVMFOMXEncNode-%s::NegotiateVideoComponentParameters() Problem setting port format for input port %d ", iNodeTypeId, iInputPortIndex));
   2137         return false;
   2138     }
   2139 
   2140 
   2141 
   2142     CONFIG_SIZE_AND_VERSION(iParamPort);
   2143     iParamPort.nPortIndex = iInputPortIndex;
   2144     Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamPortDefinition, &iParamPort);
   2145     if (Err != OMX_ErrorNone)
   2146     {
   2147         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2148                         (0, "PVMFOMXEncNode-%s::NegotiateVideoComponentParameters() Problem negotiating with input port %d ", iNodeTypeId, iInputPortIndex));
   2149         return false;
   2150     }
   2151 
   2152     if (iInFormat == PVMF_MIME_RGB24)
   2153     {
   2154         iOMXComponentInputBufferSize = (iVideoInputFormat.iFrameWidth * iVideoInputFormat.iFrameHeight * 3);
   2155         iParamPort.format.video.eColorFormat = OMX_COLOR_Format24bitRGB888;
   2156     }
   2157     else if (iInFormat == PVMF_MIME_RGB12)
   2158     {
   2159         iOMXComponentInputBufferSize = (iVideoInputFormat.iFrameWidth * iVideoInputFormat.iFrameHeight * 2);
   2160         iParamPort.format.video.eColorFormat = OMX_COLOR_Format12bitRGB444;
   2161     }
   2162     else if (iInFormat == PVMF_MIME_YUV420)
   2163     {
   2164         iOMXComponentInputBufferSize = (iVideoInputFormat.iFrameWidth * iVideoInputFormat.iFrameHeight * 3) >> 1;
   2165         //TODO: get color format from MIO. JJ 03/09/09
   2166         iParamPort.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
   2167         //iParamPort.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar;
   2168     }
   2169     else if (iInFormat == PVMF_MIME_YUV422_INTERLEAVED_UYVY)
   2170     {
   2171         iOMXComponentInputBufferSize = iVideoInputFormat.iFrameWidth * iVideoInputFormat.iFrameHeight * 2;
   2172         iParamPort.format.video.eColorFormat = OMX_COLOR_FormatCbYCrY;
   2173     }
   2174     else if (iInFormat == PVMF_MIME_YUV422_INTERLEAVED_YUYV)
   2175     {
   2176         iOMXComponentInputBufferSize = iVideoInputFormat.iFrameWidth * iVideoInputFormat.iFrameHeight * 2;
   2177         iParamPort.format.video.eColorFormat = OMX_COLOR_FormatYCbYCr;
   2178     }
   2179     else
   2180     {
   2181         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2182                         (0, "PVMFOMXEncNode-%s::NegotiateVideoComponentParameters() Problem with input port %d color format", iNodeTypeId, iInputPortIndex));
   2183         return false;
   2184     }
   2185 
   2186     //The input buffer size is a read-only parameter and the encoder component needs to adjust it.
   2187     // We (the client) determine the size of the buffers based on width/height -
   2188     // the component doesn't know width/height yet
   2189 
   2190     //iParamPort.nBufferSize = iOMXComponentInputBufferSize;
   2191 
   2192     // set the width and height of video frame and input framerate
   2193 
   2194     iParamPort.format.video.nFrameWidth = iVideoInputFormat.iFrameWidth;
   2195     iParamPort.format.video.nFrameHeight = iVideoInputFormat.iFrameHeight;
   2196     // This is Q16 value, so shift by 16 first and cast to preserve accuracy
   2197     iParamPort.format.video.xFramerate = (uint32)(iVideoInputFormat.iFrameRate * (1 << 16));
   2198 
   2199     // indicate that input is uncompressed so that color format is valid
   2200     iParamPort.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
   2201 
   2202 
   2203     // let the component decide about the number of input buffers
   2204     iNumInputBuffers = iParamPort.nBufferCountActual;
   2205 
   2206     // do we need to increase the number of buffers?
   2207     if (iNumInputBuffers < iParamPort.nBufferCountMin)
   2208         iNumInputBuffers = iParamPort.nBufferCountMin;
   2209 
   2210 
   2211     /*  OMX_UseBuffer, ie. if OMX client instead of OMX component is to allocate buffers,
   2212     *   if the buffers are allocated in MIO, check MIO allocator the max number of buffers;
   2213     *   else (the buffer is allocated by OMX client itself) floor the number of buffers to  NUMBER_INPUT_BUFFER
   2214     *   validate with OMX component whether it is ok with the number decided above.
   2215     *   Note: the spec says in OMX_UseBuffer, the OMX client can decide number of input buffers.
   2216     */
   2217     if(iOMXComponentSupportsExternalInputBufferAlloc)
   2218     {
   2219         ipExternalInputBufferAllocatorInterface = NULL;
   2220         PvmiKvp* kvp = NULL;
   2221         int numKvp = 0;
   2222         PvmiKeyType aIdentifier = (PvmiKeyType)PVMF_BUFFER_ALLOCATOR_KEY;
   2223         int32 err, err1;
   2224         OSCL_TRY(err, ((PVMFOMXEncPort*)iInPort)->pvmiGetBufferAllocatorSpecificInfoSync(aIdentifier, kvp, numKvp););
   2225 
   2226         if ((err == OsclErrNone) && (NULL != kvp))
   2227         {
   2228             ipExternalInputBufferAllocatorInterface = (PVInterface*) kvp->value.key_specific_value;
   2229 
   2230             if (ipExternalInputBufferAllocatorInterface)
   2231             {
   2232                 PVInterface* pTempPVInterfacePtr = NULL;
   2233 
   2234                 OSCL_TRY(err, ipExternalInputBufferAllocatorInterface->queryInterface(PVMFFixedSizeBufferAllocUUID, pTempPVInterfacePtr););
   2235 
   2236                 OSCL_TRY(err1, ((PVMFOMXEncPort*)iInPort)->releaseParametersSync(kvp, numKvp););
   2237                 OSCL_FIRST_CATCH_ANY(err1,
   2238                         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
   2239                             (0, "PVMFOMXEncNode-%s::NegotiateComponentParameters() - Unable to Release Parameters", iNodeTypeId));
   2240                         );
   2241 
   2242                 if ((err == OsclErrNone) && (NULL != pTempPVInterfacePtr))
   2243                 {
   2244                     ipFixedSizeBufferAlloc = OSCL_STATIC_CAST(PVMFFixedSizeBufferAlloc*, pTempPVInterfacePtr);
   2245 
   2246                     uint32 iNumBuffers = ipFixedSizeBufferAlloc->getNumBuffers();
   2247                     uint32 iBufferSize = ipFixedSizeBufferAlloc->getBufferSize();
   2248 
   2249                     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
   2250                             (0, "PVMFOMXEncNode-%s iNumBuffers %d iBufferSize %d iOMXComponentInputBufferSize %d iParamPort.nBufferCountMin %d", iNodeTypeId, iNumBuffers , iBufferSize , iOMXComponentInputBufferSize, iParamPort.nBufferCountMin ) );
   2251 
   2252                     //TODO should let camera decide number of buffers.
   2253                     if ((iNumBuffers < iParamPort.nBufferCountMin) || (iBufferSize < iOMXComponentInputBufferSize ))
   2254                     {
   2255                         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   2256                             (0, "PVMFOMXEncNode-%s::NegotiateComponentParameters() - not enough buffer. Got %d x %d. Require %d x %d", iNodeTypeId, iNumBuffers , iBufferSize , iOMXComponentInputBufferSize, iParamPort.nBufferCountMin));
   2257                         //ipFixedSizeBufferAlloc = NULL;
   2258 
   2259                         ipExternalInputBufferAllocatorInterface->removeRef();
   2260                         ipExternalInputBufferAllocatorInterface = NULL;
   2261                     }
   2262                     else
   2263                     {
   2264                         iNumInputBuffers = iNumBuffers;
   2265                         iOMXComponentInputBufferSize = iBufferSize;
   2266                     }
   2267                 }
   2268                 else
   2269                 {
   2270                     ipExternalInputBufferAllocatorInterface->removeRef();
   2271                     ipExternalInputBufferAllocatorInterface = NULL;
   2272 
   2273                 }
   2274             }
   2275         }
   2276     }
   2277 
   2278     // if component allows us to allocate buffers, we'll decide how many to allocate
   2279     if (iOMXComponentSupportsExternalInputBufferAlloc && (iParamPort.nBufferCountMin < NUMBER_INPUT_BUFFER))
   2280     {
   2281         if(NULL == ipFixedSizeBufferAlloc)
   2282         {
   2283         // preset the number of input buffers
   2284         iNumInputBuffers = NUMBER_INPUT_BUFFER;
   2285         }
   2286     }
   2287 
   2288     // set the number of input buffer
   2289     iParamPort.nBufferCountActual = iNumInputBuffers;
   2290 
   2291     // set the number of actual input buffers
   2292     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2293                     (0, "PVMFOMXEncNode-%s::NegotiateVideoComponentParameters() Inport buffers %d,size %d", iNodeTypeId, iNumInputBuffers, iOMXComponentInputBufferSize));
   2294 
   2295     // lock in the input port parameters
   2296     CONFIG_SIZE_AND_VERSION(iParamPort);
   2297     Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamPortDefinition, &iParamPort);
   2298     if (Err != OMX_ErrorNone)
   2299     {
   2300         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2301                         (0, "PVMFOMXEncNode-%s::NegotiateVideoComponentParameters() Problem setting parameters in input port %d ", iNodeTypeId, iInputPortIndex));
   2302         return false;
   2303     }
   2304 
   2305 
   2306     //////////////////// OUTPUT PORT //////////////////////////////////////////////
   2307     CONFIG_SIZE_AND_VERSION(Video_port_format);
   2308 
   2309     Video_port_format.nPortIndex = iOutputPortIndex; // set output port as target
   2310     OMX_VIDEO_CODINGTYPE DesiredPortFormat = OMX_VIDEO_CodingUnused;
   2311     if (iOutFormat == PVMF_MIME_M4V)
   2312     {
   2313         DesiredPortFormat = OMX_VIDEO_CodingMPEG4;
   2314     }
   2315     else if (iOutFormat == PVMF_MIME_H2631998 ||
   2316              iOutFormat == PVMF_MIME_H2632000)
   2317     {
   2318         DesiredPortFormat = OMX_VIDEO_CodingH263;
   2319     }
   2320     else if (iOutFormat == PVMF_MIME_H264_VIDEO_RAW ||
   2321              iOutFormat == PVMF_MIME_H264_VIDEO_MP4)
   2322     {
   2323         DesiredPortFormat = OMX_VIDEO_CodingAVC;
   2324     }
   2325     else
   2326     {
   2327         DesiredPortFormat = OMX_VIDEO_CodingUnused;
   2328     }
   2329 
   2330     if (DesiredPortFormat == OMX_VIDEO_CodingUnused)
   2331     {
   2332         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2333                         (0, "PVMFOMXEncNode-%s::NegotiateVideoComponentParameters() Problem with output port %d format", iNodeTypeId, iOutputPortIndex));
   2334         return false;
   2335     }
   2336     // loop over supported formats until we hit the one we want
   2337     // or until the component has no more supported formats (in which case it returns OMX_ErrorNoMore
   2338     Err = OMX_ErrorNone;
   2339     Video_port_format.nIndex = 0; //init the format counter
   2340     while (OMX_ErrorNone == Err)
   2341     {
   2342 
   2343         Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamVideoPortFormat, &Video_port_format);
   2344         if ((OMX_ErrorNone != Err))
   2345         {
   2346             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2347                             (0, "PVMFOMXEncNode-%s::NegotiateVideoComponentParameters() Problem getting port format for output port %d or no desired port format found", iNodeTypeId, iOutputPortIndex));
   2348             return false;
   2349         }
   2350 
   2351         if ((Video_port_format.eCompressionFormat == DesiredPortFormat))
   2352             break;
   2353 
   2354         Video_port_format.nIndex ++;
   2355     }
   2356 
   2357     // OK, we've found the desired format, set it as the one used
   2358     Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamVideoPortFormat, &Video_port_format);
   2359     if ((OMX_ErrorNone != Err))
   2360     {
   2361         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2362                         (0, "PVMFOMXEncNode-%s::NegotiateVideoComponentParameters() Problem setting port format for output port %d ", iNodeTypeId, iOutputPortIndex));
   2363         return false;
   2364     }
   2365 
   2366 
   2367 
   2368 
   2369     //Port 1 for output port
   2370     CONFIG_SIZE_AND_VERSION(iParamPort);
   2371     iParamPort.nPortIndex = iOutputPortIndex;
   2372     Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamPortDefinition, &iParamPort);
   2373     if (Err != OMX_ErrorNone)
   2374     {
   2375         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2376                         (0, "PVMFOMXEncNode-%s::NegotiateVideoComponentParameters() Problem negotiating with output port %d ", iNodeTypeId, iOutputPortIndex));
   2377         return false;
   2378     }
   2379 
   2380     // let the component decide num output buffers
   2381     iNumOutputBuffers = iParamPort.nBufferCountActual;
   2382 
   2383 
   2384     //check the number
   2385     if (iNumOutputBuffers < iParamPort.nBufferCountMin)
   2386         iNumOutputBuffers = iParamPort.nBufferCountMin;
   2387 
   2388 
   2389     // set the number ourselves
   2390     if (iOMXComponentSupportsExternalOutputBufferAlloc && (iParamPort.nBufferCountMin < NUMBER_OUTPUT_BUFFER))
   2391     {
   2392         iNumOutputBuffers = NUMBER_OUTPUT_BUFFER;
   2393     }
   2394 
   2395     iParamPort.nBufferCountActual = iNumOutputBuffers;
   2396 
   2397 
   2398     // set the output (target) bitrate, framerate, width/height etc.
   2399     iParamPort.format.video.nFrameWidth = iVideoEncodeParam.iFrameWidth[0];
   2400     iParamPort.format.video.nFrameHeight = iVideoEncodeParam.iFrameHeight[0];
   2401     // Q16 value, cast after the shift to preserve the accuracy.
   2402     iParamPort.format.video.xFramerate = (uint32)(iVideoEncodeParam.iFrameRate[0] * (1 << 16));
   2403 
   2404     iParamPort.format.video.nBitrate = iVideoEncodeParam.iBitRate[0];
   2405     iParamPort.format.video.eColorFormat = OMX_COLOR_FormatUnused;
   2406 
   2407     if (iOutFormat == PVMF_MIME_M4V)
   2408     {
   2409         iParamPort.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4;
   2410     }
   2411     else if (iOutFormat == PVMF_MIME_H2631998 ||
   2412              iOutFormat == PVMF_MIME_H2632000)
   2413     {
   2414         iParamPort.format.video.eCompressionFormat = OMX_VIDEO_CodingH263;
   2415     }
   2416     else if (iOutFormat == PVMF_MIME_H264_VIDEO_RAW ||
   2417              iOutFormat == PVMF_MIME_H264_VIDEO_MP4)
   2418     {
   2419         iParamPort.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
   2420     }
   2421     else
   2422     {
   2423         iParamPort.format.video.eCompressionFormat = OMX_VIDEO_CodingAutoDetect;
   2424     }
   2425 
   2426     CONFIG_SIZE_AND_VERSION(iParamPort);
   2427     Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamPortDefinition, &iParamPort);
   2428     if (Err != OMX_ErrorNone)
   2429     {
   2430         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2431                         (0, "PVMFOMXEncNode-%s::NegotiateVideoComponentParameters() Problem setting parameters in output port %d ", iNodeTypeId, iOutputPortIndex));
   2432         return false;
   2433     }
   2434 
   2435     //ask for the calculated buffer size
   2436     Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamPortDefinition, &iParamPort);
   2437     if (Err != OMX_ErrorNone)
   2438     {
   2439         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2440                         (0, "PVMFOMXEncNode-%s::NegotiateVideoComponentParameters() Problem negotiating with output port %d ", iNodeTypeId, iOutputPortIndex));
   2441         return false;
   2442     }
   2443 
   2444     iOMXComponentOutputBufferSize = iParamPort.nBufferSize;
   2445     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2446                     (0, "PVMFOMXEncNode-%s::NegotiateVideoComponentParameters() Outport buffers %d size %d", iNodeTypeId, iNumOutputBuffers, iOMXComponentOutputBufferSize));
   2447 
   2448     CONFIG_SIZE_AND_VERSION(InputRotationType);
   2449     InputRotationType.nPortIndex = iInputPortIndex;
   2450     Err = OMX_GetParameter(iOMXEncoder, OMX_IndexConfigCommonRotate, &InputRotationType);
   2451     if (Err != OMX_ErrorNone)
   2452     {
   2453         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2454                         (0, "PVMFOMXEncNode-%s::NegotiateVideoComponentParameters() Problem getting OMX_IndexConfigCommonRotate param ", iNodeTypeId));
   2455     }
   2456 
   2457     //Set the OMX_CONFIG_ROTATIONTYPE parameters
   2458     InputRotationType.nRotation = ((iVideoInputFormat.iFrameOrientation == 1) ? 180 : 0);
   2459     Err = OMX_SetParameter(iOMXEncoder, OMX_IndexConfigCommonRotate, &InputRotationType);
   2460     if (Err != OMX_ErrorNone)
   2461     {
   2462         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2463                         (0, "PVMFOMXEncNode-%s::NegotiateVideoComponentParameters() Problem setting OMX_IndexConfigCommonRotate param ", iNodeTypeId));
   2464     }
   2465 
   2466 
   2467     // now call codec specific parameter setting
   2468     bool status = true;
   2469     if (iOutFormat == PVMF_MIME_M4V)
   2470     {
   2471         status = SetMP4EncoderParameters();
   2472     }
   2473     else if (iOutFormat == PVMF_MIME_H2631998 ||
   2474              iOutFormat == PVMF_MIME_H2632000)
   2475     {
   2476         status = SetH263EncoderParameters();
   2477     }
   2478     else if (iOutFormat == PVMF_MIME_H264_VIDEO_RAW ||
   2479              iOutFormat == PVMF_MIME_H264_VIDEO_MP4)
   2480     {
   2481         status = SetH264EncoderParameters();
   2482     }
   2483 
   2484     return status;
   2485 }
   2486 bool PVMFOMXEncNode::SetMP4EncoderParameters()
   2487 {
   2488     OMX_ERRORTYPE Err = OMX_ErrorNone;
   2489 
   2490     OMX_VIDEO_PARAM_MPEG4TYPE Mpeg4Type;
   2491     OMX_VIDEO_PARAM_BITRATETYPE BitRateType;
   2492     OMX_VIDEO_PARAM_QUANTIZATIONTYPE QuantParam;
   2493     OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE ErrCorrType;
   2494 
   2495     // DV: VALUES HERE ARE FOR THE MOST PART HARDCODED BASED ON PV DEFAULTS
   2496     OMX_VIDEO_PARAM_MOTIONVECTORTYPE MotionVector;
   2497     OMX_VIDEO_PARAM_INTRAREFRESHTYPE RefreshParam;
   2498 
   2499 
   2500     CONFIG_SIZE_AND_VERSION(Mpeg4Type);
   2501     Mpeg4Type.nPortIndex = iOutputPortIndex;
   2502 
   2503     Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamVideoMpeg4, &Mpeg4Type);
   2504     if (OMX_ErrorNone != Err)
   2505     {
   2506         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2507                         (0, "PVMFOMXEncNode-%s::SetMP4EncoderParameters Parameter Invalid", iNodeTypeId));
   2508     }
   2509 
   2510 
   2511     //Set the OMX_VIDEO_PARAM_MPEG4TYPE parameters
   2512 
   2513     Mpeg4Type.nPortIndex = iOutputPortIndex;
   2514     // extra parameters - hardcoded
   2515     Mpeg4Type.nSliceHeaderSpacing = 0;
   2516     Mpeg4Type.bSVH = OMX_FALSE; //((iEncoderParam.iContentType == EI_H263)? true: false);
   2517     Mpeg4Type.bGov = OMX_FALSE; // disable or enable GOV header
   2518     // extra parameters - hardcoded
   2519     Mpeg4Type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
   2520 
   2521 
   2522     // params based on iFrame interval
   2523     if (iVideoEncodeParam.iIFrameInterval == -1) // encode only one frame
   2524     {
   2525         Mpeg4Type.nPFrames = 0xFFFFFFFF;
   2526     }
   2527     else if (iVideoEncodeParam.iIFrameInterval == 0) // no P frames
   2528     {
   2529         Mpeg4Type.nPFrames = 0;
   2530         Mpeg4Type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI; // maps to only supporting I-frames
   2531     }
   2532     else
   2533     {
   2534         Mpeg4Type.nPFrames = (OMX_U32)(iVideoEncodeParam.iIFrameInterval * iVideoEncodeParam.iFrameRate[0] - 1);
   2535     }
   2536 
   2537     // extra parameters - hardcoded
   2538     Mpeg4Type.nBFrames = 0;
   2539     Mpeg4Type.nIDCVLCThreshold = 0;
   2540     Mpeg4Type.bACPred = OMX_TRUE;
   2541     Mpeg4Type.nMaxPacketSize = iVideoEncodeParam.iPacketSize;
   2542     Mpeg4Type.nTimeIncRes = 1000; // (in relation to (should be higher than) frame rate )
   2543     Mpeg4Type.nHeaderExtension = 0;
   2544     Mpeg4Type.bReversibleVLC = ((iVideoEncodeParam.iRVLCEnable == true) ? OMX_TRUE : OMX_FALSE);
   2545 
   2546     switch (iVideoEncodeParam.iProfileLevel)
   2547     {
   2548 
   2549         case EI_SIMPLE_LEVEL0:
   2550             Mpeg4Type.eProfile = OMX_VIDEO_MPEG4ProfileSimple;
   2551             Mpeg4Type.eLevel = OMX_VIDEO_MPEG4Level0;
   2552             break;
   2553 
   2554         case EI_SIMPLE_LEVEL1:
   2555             Mpeg4Type.eProfile = OMX_VIDEO_MPEG4ProfileSimple;
   2556             Mpeg4Type.eLevel = OMX_VIDEO_MPEG4Level1;
   2557             break;
   2558 
   2559         case EI_SIMPLE_LEVEL2:
   2560             Mpeg4Type.eProfile = OMX_VIDEO_MPEG4ProfileSimple;
   2561             Mpeg4Type.eLevel = OMX_VIDEO_MPEG4Level2;
   2562             break;
   2563 
   2564         case EI_SIMPLE_LEVEL3:
   2565             Mpeg4Type.eProfile = OMX_VIDEO_MPEG4ProfileSimple;
   2566             Mpeg4Type.eLevel = OMX_VIDEO_MPEG4Level3;
   2567             break;
   2568 
   2569         case EI_CORE_LEVEL1:
   2570             Mpeg4Type.eProfile = OMX_VIDEO_MPEG4ProfileCore;
   2571             Mpeg4Type.eLevel = OMX_VIDEO_MPEG4Level1;
   2572             break;
   2573 
   2574         case EI_CORE_LEVEL2:
   2575             Mpeg4Type.eProfile = OMX_VIDEO_MPEG4ProfileCore;
   2576             Mpeg4Type.eLevel = OMX_VIDEO_MPEG4Level2;
   2577             break;
   2578 
   2579         case EI_SIMPLE_SCALABLE_LEVEL0:
   2580             Mpeg4Type.eProfile = OMX_VIDEO_MPEG4ProfileSimpleScalable;
   2581             Mpeg4Type.eLevel = OMX_VIDEO_MPEG4Level0;
   2582             break;
   2583 
   2584         case EI_SIMPLE_SCALABLE_LEVEL1:
   2585             Mpeg4Type.eProfile = OMX_VIDEO_MPEG4ProfileSimpleScalable;
   2586             Mpeg4Type.eLevel = OMX_VIDEO_MPEG4Level1;
   2587             break;
   2588 
   2589         case EI_SIMPLE_SCALABLE_LEVEL2:
   2590             Mpeg4Type.eProfile = OMX_VIDEO_MPEG4ProfileSimpleScalable;
   2591             Mpeg4Type.eLevel = OMX_VIDEO_MPEG4Level2;
   2592             break;
   2593 
   2594         case EI_CORE_SCALABLE_LEVEL1:
   2595             Mpeg4Type.eProfile = OMX_VIDEO_MPEG4ProfileCoreScalable;
   2596             Mpeg4Type.eLevel = OMX_VIDEO_MPEG4Level1;
   2597             break;
   2598 
   2599         case EI_CORE_SCALABLE_LEVEL2:
   2600             Mpeg4Type.eProfile = OMX_VIDEO_MPEG4ProfileCoreScalable;
   2601             Mpeg4Type.eLevel = OMX_VIDEO_MPEG4Level2;
   2602             break;
   2603 
   2604         case EI_CORE_SCALABLE_LEVEL3:
   2605             Mpeg4Type.eProfile = OMX_VIDEO_MPEG4ProfileCoreScalable;
   2606             Mpeg4Type.eLevel = OMX_VIDEO_MPEG4Level3;
   2607             break;
   2608 
   2609     }
   2610 
   2611     Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamVideoMpeg4, &Mpeg4Type);
   2612     if (OMX_ErrorNone != Err)
   2613     {
   2614         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2615                         (0, "PVMFOMXEncNode-%s::SetMP4EncoderParameters Parameter Invalid", iNodeTypeId));
   2616     }
   2617 
   2618     //OMX_VIDEO_PARAM_BITRATETYPE Settings
   2619     CONFIG_SIZE_AND_VERSION(BitRateType);
   2620 
   2621     BitRateType.nPortIndex = iOutputPortIndex;
   2622     Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamVideoBitrate, &BitRateType);
   2623 
   2624     if (OMX_ErrorNone != Err)
   2625     {
   2626         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2627                         (0, "PVMFOMXEncNode-%s::SetMP4EncoderParameters Parameter Invalid", iNodeTypeId));
   2628     }
   2629 
   2630     //Set the parameters now
   2631     BitRateType.nPortIndex = iOutputPortIndex;
   2632     BitRateType.eControlRate = static_cast<OMX_VIDEO_CONTROLRATETYPE>(iVideoEncodeParam.iRateControlType);
   2633     BitRateType.nTargetBitrate = iVideoEncodeParam.iBitRate[0];
   2634     Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamVideoBitrate, &BitRateType);
   2635 
   2636     if (OMX_ErrorNone != Err)
   2637     {
   2638         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2639                         (0, "PVMFOMXEncNode-%s::SetMP4EncoderParameters Parameter Invalid", iNodeTypeId));
   2640     }
   2641 
   2642     //OMX_VIDEO_PARAM_QUANTIZATIONTYPE Settings
   2643     if (BitRateType.eControlRate == OMX_Video_ControlRateDisable)
   2644     {
   2645         CONFIG_SIZE_AND_VERSION(QuantParam);
   2646         QuantParam.nPortIndex = iOutputPortIndex;
   2647 
   2648         Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamVideoQuantization, &QuantParam);
   2649         if (OMX_ErrorNone != Err)
   2650         {
   2651             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2652                             (0, "PVMFOMXEncNode-%s::SetMP4EncoderParameters Parameter Invalid", iNodeTypeId));
   2653         }
   2654 
   2655         //Set the parameters now
   2656         QuantParam.nPortIndex = iOutputPortIndex;
   2657         QuantParam.nQpI = DEFAULT_OMX_MP4ENC_QPI;
   2658         QuantParam.nQpP = DEFAULT_OMX_MP4ENC_QPP;
   2659         QuantParam.nQpB = DEFAULT_OMX_MP4ENC_QPB;
   2660         Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamVideoQuantization, &QuantParam);
   2661         if (OMX_ErrorNone != Err)
   2662         {
   2663             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2664                             (0, "PVMFOMXEncNode-%s::SetMP4EncoderParameters Parameter Invalid", iNodeTypeId));
   2665         }
   2666     }
   2667 
   2668 
   2669 
   2670     //OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE Settings (For streaming/2-way)
   2671 
   2672     CONFIG_SIZE_AND_VERSION(ErrCorrType);
   2673     ErrCorrType.nPortIndex = iOutputPortIndex;
   2674     Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamVideoErrorCorrection, &ErrCorrType);
   2675     if (OMX_ErrorNone != Err)
   2676     {
   2677         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2678                         (0, "PVMFOMXEncNode-%s::SetMP4EncoderParameters Parameter Invalid", iNodeTypeId));
   2679     }
   2680 
   2681     //Set the parameters now
   2682     ErrCorrType.nPortIndex = iOutputPortIndex;
   2683     ErrCorrType.bEnableDataPartitioning = ((iVideoEncodeParam.iDataPartitioning == true) ? OMX_TRUE : OMX_FALSE);
   2684     ErrCorrType.bEnableResync = ((iVideoEncodeParam.iResyncMarker == true) ? OMX_TRUE : OMX_FALSE);
   2685 
   2686     // extra parameters - hardcoded
   2687     ErrCorrType.bEnableHEC = OMX_FALSE;
   2688     ErrCorrType.nResynchMarkerSpacing = iVideoEncodeParam.iPacketSize;
   2689     ErrCorrType.bEnableRVLC = ((iVideoEncodeParam.iRVLCEnable == true) ? OMX_TRUE : OMX_FALSE); // corresponds to encode param rvlcEnable
   2690 
   2691     Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamVideoErrorCorrection, &ErrCorrType);
   2692     if (OMX_ErrorNone != Err)
   2693     {
   2694         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2695                         (0, "PVMFOMXEncNode-%s::SetMP4EncoderParameters Parameter Invalid", iNodeTypeId));
   2696     }
   2697 
   2698 
   2699     //OMX_VIDEO_PARAM_MOTIONVECTORTYPE Settings
   2700     CONFIG_SIZE_AND_VERSION(MotionVector);
   2701     MotionVector.nPortIndex = iOutputPortIndex;
   2702 
   2703     Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamVideoMotionVector, &MotionVector);
   2704     if (OMX_ErrorNone != Err)
   2705     {
   2706         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2707                         (0, "PVMFOMXEncNode-%s::SetMP4EncoderParameters Parameter Invalid", iNodeTypeId));
   2708     }
   2709 
   2710     MotionVector.nPortIndex = iOutputPortIndex;
   2711 
   2712     // extra parameters - hardcoded
   2713     MotionVector.sXSearchRange = iVideoEncodeParam.iSearchRange;
   2714     MotionVector.sYSearchRange = iVideoEncodeParam.iSearchRange;
   2715     MotionVector.bFourMV = ((iVideoEncodeParam.iMV8x8 == true) ? OMX_TRUE : OMX_FALSE);
   2716     MotionVector.eAccuracy = ((iVideoEncodeParam.iMVHalfPel == true) ? OMX_Video_MotionVectorHalfPel : OMX_Video_MotionVectorPixel);
   2717     MotionVector.bUnrestrictedMVs = OMX_TRUE;
   2718 
   2719     Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamVideoMotionVector, &MotionVector);
   2720     if (OMX_ErrorNone != Err)
   2721     {
   2722         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2723                         (0, "PVMFOMXEncNode-%s::SetMP4EncoderParameters Parameter Invalid", iNodeTypeId));
   2724     }
   2725 
   2726 
   2727     //OMX_VIDEO_PARAM_INTRAREFRESHTYPE Settings
   2728     CONFIG_SIZE_AND_VERSION(RefreshParam);
   2729     RefreshParam.nPortIndex = iOutputPortIndex;
   2730 
   2731     Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamVideoIntraRefresh, &RefreshParam);
   2732     if (OMX_ErrorNone != Err)
   2733     {
   2734         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2735                         (0, "PVMFOMXEncNode-%s::SetMP4EncoderParameters Parameter Invalid", iNodeTypeId));
   2736     }
   2737 
   2738     // extra parameters - hardcoded based on PV defaults
   2739     RefreshParam.nPortIndex = iOutputPortIndex;
   2740     RefreshParam.eRefreshMode = OMX_VIDEO_IntraRefreshBoth;
   2741     RefreshParam.nCirMBs = iVideoEncodeParam.iNumIntraMBRefresh;
   2742 
   2743     Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamVideoIntraRefresh, &RefreshParam);
   2744     if (OMX_ErrorNone != Err)
   2745     {
   2746         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2747                         (0, "PVMFOMXEncNode-%s::SetMP4EncoderParameters Parameter Invalid", iNodeTypeId));
   2748     }
   2749 
   2750     return true;
   2751 }
   2752 
   2753 bool PVMFOMXEncNode::SetH263EncoderParameters()
   2754 {
   2755 
   2756     OMX_ERRORTYPE Err = OMX_ErrorNone;
   2757 
   2758     OMX_VIDEO_PARAM_H263TYPE H263Type;
   2759     OMX_VIDEO_PARAM_BITRATETYPE BitRateType;
   2760     OMX_VIDEO_PARAM_QUANTIZATIONTYPE QuantParam;
   2761     OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE ErrCorrType;
   2762 
   2763     // DV: VALUES HERE ARE FOR THE MOST PART HARDCODED BASED ON PV DEFAULTS
   2764     OMX_VIDEO_PARAM_MOTIONVECTORTYPE MotionVector;
   2765     OMX_VIDEO_PARAM_INTRAREFRESHTYPE RefreshParam;
   2766 
   2767 
   2768     CONFIG_SIZE_AND_VERSION(H263Type);
   2769     H263Type.nPortIndex = iOutputPortIndex;
   2770 
   2771     Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamVideoH263, &H263Type);
   2772     if (OMX_ErrorNone != Err)
   2773     {
   2774         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2775                         (0, "PVMFOMXEncNode-%s::SetH263EncoderParameters OMX_GetParameter() failed for index(0x%x)", iNodeTypeId, OMX_IndexParamVideoH263));
   2776     }
   2777 
   2778 
   2779     //Set the OMX_VIDEO_PARAM_H263TYPE parameters
   2780 
   2781     //DV: Here, we only set the nPFrames and AllowedFrameTypes, i.e. iIFrameInterval related variables
   2782 
   2783     H263Type.nPortIndex = iOutputPortIndex;
   2784 
   2785     H263Type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
   2786     if (iVideoEncodeParam.iIFrameInterval == -1) // encode only one I frame followed by P frames
   2787     {
   2788         H263Type.nPFrames = 0xFFFFFFFF;
   2789     }
   2790     else if (iVideoEncodeParam.iIFrameInterval == 0) // no P frames
   2791     {
   2792         H263Type.nPFrames = 0;
   2793         H263Type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI; // maps to only supporting I-frames
   2794     }
   2795     else
   2796     {
   2797         H263Type.nPFrames = (OMX_U32)(iVideoEncodeParam.iIFrameInterval * iVideoEncodeParam.iFrameRate[0] - 1);
   2798     }
   2799 
   2800     // extra parameters - hardcoded
   2801     H263Type.nBFrames = 0;
   2802     H263Type.eProfile = OMX_VIDEO_H263ProfileBaseline;
   2803 
   2804     // the supported level is up to OMX_VIDEO_H263Level45
   2805     if (H263Type.eLevel > OMX_VIDEO_H263Level45)
   2806     {
   2807         H263Type.eLevel = OMX_VIDEO_H263Level45;
   2808     }
   2809     H263Type.bPLUSPTYPEAllowed = OMX_FALSE;
   2810     H263Type.bForceRoundingTypeToZero = OMX_FALSE;
   2811     H263Type.nPictureHeaderRepetition = 0;
   2812     H263Type.nGOBHeaderInterval = 0;
   2813 
   2814     Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamVideoH263, &H263Type);
   2815     if (OMX_ErrorNone != Err)
   2816     {
   2817         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2818                         (0, "PVMFOMXEncNode-%s::SetH263EncoderParameters OMX_SetParameter() failed for index(0x%x)", iNodeTypeId, OMX_IndexParamVideoH263));
   2819     }
   2820 
   2821     //OMX_VIDEO_PARAM_BITRATETYPE Settings
   2822     CONFIG_SIZE_AND_VERSION(BitRateType);
   2823 
   2824     BitRateType.nPortIndex = iOutputPortIndex;
   2825     Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamVideoBitrate, &BitRateType);
   2826     if (OMX_ErrorNone != Err)
   2827     {
   2828         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2829                         (0, "PVMFOMXEncNode-%s::SetH263EncoderParameters OMX_GetParameter() failed for index(0x%x)", iNodeTypeId, OMX_IndexParamVideoBitrate));
   2830     }
   2831 
   2832     //Set the parameters now
   2833     BitRateType.nPortIndex = iOutputPortIndex;
   2834     BitRateType.eControlRate = static_cast<OMX_VIDEO_CONTROLRATETYPE>(iVideoEncodeParam.iRateControlType);
   2835     BitRateType.nTargetBitrate = iVideoEncodeParam.iBitRate[0];
   2836     Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamVideoBitrate, &BitRateType);
   2837     if (OMX_ErrorNone != Err)
   2838     {
   2839         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2840                         (0, "PVMFOMXEncNode-%s::SetH263EncoderParameters OMX_SetParameter() failed for index(0x%x)", iNodeTypeId, OMX_IndexParamVideoBitrate));
   2841     }
   2842 
   2843 
   2844     //OMX_VIDEO_PARAM_QUANTIZATIONTYPE Settings
   2845     if (BitRateType.eControlRate == OMX_Video_ControlRateDisable)
   2846     {
   2847         CONFIG_SIZE_AND_VERSION(QuantParam);
   2848         QuantParam.nPortIndex = iOutputPortIndex;
   2849 
   2850         Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamVideoQuantization, &QuantParam);
   2851         if (OMX_ErrorNone != Err)
   2852         {
   2853             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2854                             (0, "PVMFOMXEncNode-%s::SetH263EncoderParameters OMX_GetParameter() failed for index(0x%x", iNodeTypeId, OMX_IndexParamVideoQuantization));
   2855         }
   2856 
   2857         //Set the parameters now
   2858         QuantParam.nPortIndex = iOutputPortIndex;
   2859         QuantParam.nQpI = DEFAULT_OMX_MP4ENC_QPI;
   2860         QuantParam.nQpP = DEFAULT_OMX_MP4ENC_QPP;
   2861         QuantParam.nQpB = DEFAULT_OMX_MP4ENC_QPB;
   2862         Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamVideoQuantization, &QuantParam);
   2863         if (OMX_ErrorNone != Err)
   2864         {
   2865             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2866                             (0, "PVMFOMXEncNode-%s::SetH263EncoderParameters OMX_SetParameter() failed for index(0x%x)", iNodeTypeId, OMX_IndexParamVideoQuantization));
   2867         }
   2868     }
   2869 
   2870 
   2871     //OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE Settings (For streaming/2-way)
   2872 
   2873     CONFIG_SIZE_AND_VERSION(ErrCorrType);
   2874     ErrCorrType.nPortIndex = iOutputPortIndex;
   2875     Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamVideoErrorCorrection, &ErrCorrType);
   2876     if (OMX_ErrorNone != Err)
   2877     {
   2878         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2879                         (0, "PVMFOMXEncNode-%s::SetH263EncoderParameters OMX_GetParameter() faile for index(0x%x)", iNodeTypeId, OMX_IndexParamVideoErrorCorrection));
   2880     }
   2881 
   2882     //Set the parameters now
   2883     ErrCorrType.nPortIndex = iOutputPortIndex;
   2884     //if (iVideoEncodeParam.iContentType == EI_M4V_STREAMING)
   2885     //{
   2886     //    ErrCorrType.bEnableDataPartitioning = OMX_TRUE;
   2887     //}
   2888     //else
   2889     //{
   2890     //    ErrCorrType.bEnableDataPartitioning = OMX_FALSE;
   2891     //}
   2892     ErrCorrType.bEnableHEC = OMX_FALSE;
   2893     ErrCorrType.bEnableResync = OMX_FALSE;
   2894     ErrCorrType.nResynchMarkerSpacing = 0;
   2895     ErrCorrType.bEnableRVLC = OMX_FALSE;        // corresponds to encode param rvlcEnable
   2896     Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamVideoErrorCorrection, &ErrCorrType);
   2897     if (OMX_ErrorNone != Err)
   2898     {
   2899         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2900                         (0, "PVMFOMXEncNode-%s::SetH263EncoderParameters OMX_SetParameter() failed for index(0x%x)", iNodeTypeId, OMX_IndexParamVideoErrorCorrection));
   2901     }
   2902 
   2903 
   2904 
   2905     //OMX_VIDEO_PARAM_MOTIONVECTORTYPE Settings
   2906     CONFIG_SIZE_AND_VERSION(MotionVector);
   2907     MotionVector.nPortIndex = iOutputPortIndex;
   2908 
   2909     Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamVideoMotionVector, &MotionVector);
   2910     if (OMX_ErrorNone != Err)
   2911     {
   2912         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2913                         (0, "PVMFOMXEncNode-%s::SetH263EncoderParameters OMX_GetParameter() failed for index(0x%x)", iNodeTypeId, OMX_IndexParamVideoMotionVector));
   2914     }
   2915 
   2916     // extra parameters - hardcoded
   2917     MotionVector.sXSearchRange = iVideoEncodeParam.iSearchRange;
   2918     MotionVector.sYSearchRange = iVideoEncodeParam.iSearchRange;
   2919     MotionVector.bFourMV =  OMX_FALSE;
   2920     MotionVector.eAccuracy = ((iVideoEncodeParam.iMVHalfPel == true) ? OMX_Video_MotionVectorHalfPel : OMX_Video_MotionVectorPixel);
   2921     MotionVector.bUnrestrictedMVs = OMX_FALSE;
   2922 
   2923 
   2924     Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamVideoMotionVector, &MotionVector);
   2925     if (OMX_ErrorNone != Err)
   2926     {
   2927         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2928                         (0, "PVMFOMXEncNode-%s::SetH263EncoderParameters OMX_SetParameter() failed for index(0x%x", iNodeTypeId, OMX_IndexParamVideoMotionVector));
   2929     }
   2930 
   2931 
   2932     //OMX_VIDEO_PARAM_INTRAREFRESHTYPE Settings
   2933 
   2934     CONFIG_SIZE_AND_VERSION(RefreshParam);
   2935     RefreshParam.nPortIndex = iOutputPortIndex;
   2936 
   2937     Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamVideoIntraRefresh, &RefreshParam);
   2938     if (OMX_ErrorNone != Err)
   2939     {
   2940         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2941                         (0, "PVMFOMXEncNode-%s::SetH263EncoderParameters OMX_GetParameter() failed for index(0x%x)", iNodeTypeId, OMX_IndexParamVideoIntraRefresh));
   2942     }
   2943 
   2944     // extra parameters - hardcoded based on PV defaults
   2945     RefreshParam.nPortIndex = iOutputPortIndex;
   2946     RefreshParam.eRefreshMode = OMX_VIDEO_IntraRefreshBoth;
   2947     RefreshParam.nCirMBs = iVideoEncodeParam.iNumIntraMBRefresh;
   2948 
   2949 
   2950     Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamVideoIntraRefresh, &RefreshParam);
   2951     if (OMX_ErrorNone != Err)
   2952     {
   2953         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2954                         (0, "PVMFOMXEncNode-%s::SetH263EncoderParameters OMX_SetParameter() failed for index(0x%x)", iNodeTypeId, OMX_IndexParamVideoIntraRefresh));
   2955     }
   2956 
   2957     return true;
   2958 }
   2959 
   2960 bool PVMFOMXEncNode::SetH264EncoderParameters()
   2961 {
   2962     OMX_ERRORTYPE Err = OMX_ErrorNone;
   2963 
   2964     OMX_VIDEO_PARAM_AVCTYPE H264Type;
   2965     OMX_VIDEO_PARAM_BITRATETYPE BitRateType;
   2966     OMX_VIDEO_PARAM_QUANTIZATIONTYPE QuantParam;
   2967 
   2968     // to be refined
   2969     OMX_VIDEO_PARAM_MOTIONVECTORTYPE MotionVector;
   2970     OMX_VIDEO_PARAM_INTRAREFRESHTYPE RefreshParam;
   2971     OMX_VIDEO_PARAM_VBSMCTYPE VbsmcType;
   2972 
   2973 
   2974     CONFIG_SIZE_AND_VERSION(H264Type);
   2975     H264Type.nPortIndex = iOutputPortIndex;
   2976 
   2977     Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamVideoAvc, &H264Type);
   2978     if (OMX_ErrorNone != Err)
   2979     {
   2980         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2981                         (0, "PVMFOMXEncNode-%s::SetH264EncoderParameters Parameter Invalid", iNodeTypeId));
   2982     }
   2983 
   2984 
   2985     H264Type.nPortIndex = iOutputPortIndex;
   2986 
   2987     H264Type.nAllowedPictureTypes  = OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
   2988     if (iVideoEncodeParam.iIFrameInterval == -1) // encode only one I frame followed by P frames
   2989     {
   2990         H264Type.nPFrames = 0xFFFFFFFF;
   2991     }
   2992     else if (iVideoEncodeParam.iIFrameInterval == 0) // no P frames
   2993     {
   2994         H264Type.nPFrames = 0;
   2995         H264Type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI; // maps to only supporting I-frames
   2996     }
   2997     else
   2998     {
   2999         H264Type.nPFrames = (OMX_U32)(iVideoEncodeParam.iIFrameInterval * iVideoEncodeParam.iFrameRate[0] - 1);
   3000     }
   3001 
   3002     // extra parameters -hardcoded
   3003     H264Type.nSliceHeaderSpacing = 0;
   3004     H264Type.nBFrames = 0;
   3005     H264Type.bUseHadamard = OMX_TRUE;
   3006     H264Type.nRefFrames = 1;
   3007     H264Type.nRefIdx10ActiveMinus1 = 0;
   3008     H264Type.nRefIdx11ActiveMinus1 = 0;
   3009     H264Type.bEnableUEP = OMX_FALSE;
   3010     H264Type.bEnableFMO = OMX_FALSE;
   3011     H264Type.bEnableASO = OMX_FALSE;
   3012     H264Type.bEnableRS = OMX_FALSE;
   3013     //H264Type.eProfile = OMX_VIDEO_AVCProfileBaseline;
   3014     //H264Type.eLevel = OMX_VIDEO_AVCLevel1b;
   3015     H264Type.bFrameMBsOnly = OMX_TRUE;
   3016     H264Type.bMBAFF = OMX_FALSE;
   3017     H264Type.bEntropyCodingCABAC = OMX_FALSE;
   3018     H264Type.bWeightedPPrediction = OMX_FALSE;
   3019     H264Type.bconstIpred = OMX_FALSE;
   3020     H264Type.bDirect8x8Inference = OMX_FALSE;
   3021     H264Type.bDirectSpatialTemporal = OMX_FALSE;
   3022     H264Type.nCabacInitIdc = 0;
   3023     H264Type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
   3024 
   3025 
   3026     Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamVideoAvc, &H264Type);
   3027     if (OMX_ErrorNone != Err)
   3028     {
   3029         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3030                         (0, "PVMFOMXEncNode-%s::SetH264EncoderParameters Parameter Invalid", iNodeTypeId));
   3031     }
   3032 
   3033 
   3034     //OMX_VIDEO_PARAM_BITRATETYPE Settings
   3035     CONFIG_SIZE_AND_VERSION(BitRateType);
   3036 
   3037     BitRateType.nPortIndex = iOutputPortIndex;
   3038     Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamVideoBitrate, &BitRateType);
   3039     if (OMX_ErrorNone != Err)
   3040     {
   3041         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3042                         (0, "PVMFOMXEncNode-%s::SetH264EncoderParameters Parameter Invalid", iNodeTypeId));
   3043     }
   3044 
   3045     //Set the parameters now
   3046     BitRateType.nPortIndex = iOutputPortIndex;
   3047     BitRateType.eControlRate = static_cast<OMX_VIDEO_CONTROLRATETYPE>(iVideoEncodeParam.iRateControlType);
   3048     BitRateType.nTargetBitrate = iVideoEncodeParam.iBitRate[0];
   3049     Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamVideoBitrate, &BitRateType);
   3050     if (OMX_ErrorNone != Err)
   3051     {
   3052         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3053                         (0, "PVMFOMXEncNode-%s::SetH264EncoderParameters Parameter Invalid", iNodeTypeId));
   3054     }
   3055 
   3056 
   3057     //OMX_VIDEO_PARAM_QUANTIZATIONTYPE Settings
   3058     if (BitRateType.eControlRate == OMX_Video_ControlRateDisable)
   3059     {
   3060         CONFIG_SIZE_AND_VERSION(QuantParam);
   3061         QuantParam.nPortIndex = iOutputPortIndex;
   3062 
   3063         Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamVideoQuantization, &QuantParam);
   3064         if (OMX_ErrorNone != Err)
   3065         {
   3066             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3067                             (0, "PVMFOMXEncNode-%s::SetH264EncoderParameters Parameter Invalid", iNodeTypeId));
   3068         }
   3069 
   3070         //Set the parameters now
   3071         QuantParam.nPortIndex = iOutputPortIndex;
   3072         QuantParam.nQpI = DEFAULT_OMX_AVCENC_QPI;
   3073         QuantParam.nQpP = DEFAULT_OMX_AVCENC_QPP;
   3074         QuantParam.nQpB = DEFAULT_OMX_AVCENC_QPB;
   3075         Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamVideoQuantization, &QuantParam);
   3076         if (OMX_ErrorNone != Err)
   3077         {
   3078             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3079                             (0, "PVMFOMXEncNode-%s::SetH264EncoderParameters Parameter Invalid", iNodeTypeId));
   3080         }
   3081     }
   3082 
   3083 
   3084 
   3085 
   3086     //OMX_VIDEO_PARAM_MOTIONVECTORTYPE Settings
   3087     CONFIG_SIZE_AND_VERSION(MotionVector);
   3088     MotionVector.nPortIndex = iOutputPortIndex;
   3089 
   3090     Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamVideoMotionVector, &MotionVector);
   3091     if (OMX_ErrorNone != Err)
   3092     {
   3093         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3094                         (0, "PVMFOMXEncNode-%s::SetH264EncoderParameters Parameter Invalid", iNodeTypeId));
   3095     }
   3096 
   3097     // extra parameters - hardcoded
   3098     MotionVector.sXSearchRange = iVideoEncodeParam.iSearchRange;
   3099     MotionVector.sYSearchRange = iVideoEncodeParam.iSearchRange;
   3100     MotionVector.bFourMV =  OMX_FALSE;
   3101     MotionVector.eAccuracy = OMX_Video_MotionVectorQuarterPel; // hardcoded
   3102     MotionVector.bUnrestrictedMVs = OMX_TRUE;
   3103 
   3104 
   3105     Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamVideoMotionVector, &MotionVector);
   3106     if (OMX_ErrorNone != Err)
   3107     {
   3108         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3109                         (0, "PVMFOMXEncNode-%s::SetH264EncoderParameters Parameter Invalid", iNodeTypeId));
   3110     }
   3111 
   3112 
   3113     //OMX_VIDEO_PARAM_INTRAREFRESHTYPE Settings
   3114 
   3115     CONFIG_SIZE_AND_VERSION(RefreshParam);
   3116     RefreshParam.nPortIndex = iOutputPortIndex;
   3117 
   3118     Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamVideoIntraRefresh, &RefreshParam);
   3119     if (OMX_ErrorNone != Err)
   3120     {
   3121         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3122                         (0, "PVMFOMXEncNode-%s::SetH264EncoderParameters Parameter Invalid", iNodeTypeId));
   3123     }
   3124 
   3125     // extra parameters - hardcoded based on PV defaults
   3126     RefreshParam.nPortIndex = iOutputPortIndex;
   3127     RefreshParam.eRefreshMode = OMX_VIDEO_IntraRefreshBoth;
   3128     RefreshParam.nCirMBs = iVideoEncodeParam.iNumIntraMBRefresh;
   3129 
   3130 
   3131     Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamVideoIntraRefresh, &RefreshParam);
   3132     if (OMX_ErrorNone != Err)
   3133     {
   3134         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3135                         (0, "PVMFOMXEncNode-%s::SetH264EncoderParameters Parameter Invalid", iNodeTypeId));
   3136     }
   3137 
   3138     CONFIG_SIZE_AND_VERSION(VbsmcType);
   3139     VbsmcType.nPortIndex = iOutputPortIndex;
   3140 
   3141     Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamVideoVBSMC, &VbsmcType);
   3142     if (OMX_ErrorNone != Err)
   3143     {
   3144         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3145                         (0, "PVMFOMXEncNode-%s::SetH264EncoderParameters Parameter Invalid", iNodeTypeId));
   3146     }
   3147 
   3148     VbsmcType.b16x16 = OMX_TRUE;
   3149     VbsmcType.b16x8 = VbsmcType.b8x16 = VbsmcType.b8x8 = VbsmcType.b8x4 = VbsmcType.b4x8 = VbsmcType.b4x4 = OMX_FALSE;
   3150 
   3151     Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamVideoVBSMC, &VbsmcType);
   3152     if (OMX_ErrorNone != Err)
   3153     {
   3154         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3155                         (0, "PVMFOMXEncNode-%s::SetH264EncoderParameters Parameter Invalid", iNodeTypeId));
   3156     }
   3157 
   3158     return true;
   3159 }
   3160 
   3161 ////////////////////////////////////////////////////////////////////////////////
   3162 bool PVMFOMXEncNode::NegotiateAudioComponentParameters()
   3163 {
   3164     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3165                     (0, "PVMFOMXEncNode-%s::NegotiateAudioParameters() In", iNodeTypeId));
   3166 
   3167     OMX_ERRORTYPE Err;
   3168 
   3169     // first get the number of ports and port indices
   3170     OMX_PORT_PARAM_TYPE AudioPortParameters;
   3171     uint32 NumPorts;
   3172     uint32 ii;
   3173 
   3174     // get starting number
   3175     CONFIG_SIZE_AND_VERSION(AudioPortParameters);
   3176 
   3177     Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamAudioInit, &AudioPortParameters);
   3178     NumPorts = AudioPortParameters.nPorts; // must be at least 2 of them (in&out)
   3179 
   3180     if (Err != OMX_ErrorNone || NumPorts < 2)
   3181     {
   3182         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3183                         (0, "PVMFOMXEncNode-%s::NegotiateAudioComponentParameters() There is insuffucient (%d) ports", iNodeTypeId, NumPorts));
   3184         return false;
   3185     }
   3186 
   3187 
   3188     // loop through ports starting from the starting index to find index of the first input port
   3189     for (ii = AudioPortParameters.nStartPortNumber ; ii < AudioPortParameters.nStartPortNumber + NumPorts; ii++)
   3190     {
   3191         // get port parameters, and determine if it is input or output
   3192         // if there are more than 2 ports, the first one we encounter that has input direction is picked
   3193 
   3194 
   3195         CONFIG_SIZE_AND_VERSION(iParamPort);
   3196         //port
   3197         iParamPort.nPortIndex = ii;
   3198         Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamPortDefinition, &iParamPort);
   3199 
   3200         if (Err != OMX_ErrorNone)
   3201         {
   3202             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3203                             (0, "PVMFOMXEncNode-%s::NegotiateAudioComponentParameters() Problem negotiating with port %d ", iNodeTypeId, ii));
   3204 
   3205             return false;
   3206         }
   3207 
   3208         if (iParamPort.eDir == OMX_DirInput)
   3209         {
   3210             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3211                             (0, "PVMFOMXEncNode-%s::NegotiateAudioComponentParameters() Found Input port index %d ", iNodeTypeId, ii));
   3212 
   3213             iInputPortIndex = ii;
   3214             break;
   3215         }
   3216     }
   3217     if (ii == AudioPortParameters.nStartPortNumber + NumPorts)
   3218     {
   3219         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3220                         (0, "PVMFOMXEncNode-%s::NegotiateAudioComponentParameters() Cannot find any input port ", iNodeTypeId));
   3221         return false;
   3222     }
   3223 
   3224 
   3225     // loop through ports starting from the starting index to find index of the first output port
   3226     for (ii = AudioPortParameters.nStartPortNumber ; ii < AudioPortParameters.nStartPortNumber + NumPorts; ii++)
   3227     {
   3228         // get port parameters, and determine if it is input or output
   3229         // if there are more than 2 ports, the first one we encounter that has output direction is picked
   3230 
   3231 
   3232         CONFIG_SIZE_AND_VERSION(iParamPort);
   3233         //port
   3234         iParamPort.nPortIndex = ii;
   3235         Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamPortDefinition, &iParamPort);
   3236 
   3237         if (Err != OMX_ErrorNone)
   3238         {
   3239             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3240                             (0, "PVMFOMXEncNode-%s::NegotiateAudioComponentParameters() Problem negotiating with port %d ", iNodeTypeId, ii));
   3241 
   3242             return false;
   3243         }
   3244 
   3245         if (iParamPort.eDir == OMX_DirOutput)
   3246         {
   3247             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3248                             (0, "PVMFOMXEncNode-%s::NegotiateAudioComponentParameters() Found Output port index %d ", iNodeTypeId, ii));
   3249 
   3250             iOutputPortIndex = ii;
   3251             break;
   3252         }
   3253     }
   3254     if (ii == AudioPortParameters.nStartPortNumber + NumPorts)
   3255     {
   3256         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3257                         (0, "PVMFOMXEncNode-%s::NegotiateAudioComponentParameters() Cannot find any output port ", iNodeTypeId));
   3258         return false;
   3259     }
   3260 
   3261 
   3262 
   3263     // now get input parameters
   3264 
   3265 
   3266     //INPUT PORT
   3267 
   3268     // first basic check if encode parameters have been set correctly
   3269     if ((0 == iAudioEncodeParam.iMaxNumOutputFramesPerBuffer) ||
   3270             (0 == iAudioEncodeParam.iAMRBitrate) ||
   3271             (0 == iAudioEncodeParam.iOutputNumChannels) ||
   3272             (2 < iAudioEncodeParam.iOutputNumChannels) ||
   3273             (0 == iAudioEncodeParam.iOutputSamplingRate) ||
   3274             (0 == iAudioInputFormat.iInputBitsPerSample) ||
   3275             (0 == iAudioInputFormat.iInputNumChannels) ||
   3276             (2 < iAudioInputFormat.iInputNumChannels) ||
   3277             (0 == iAudioInputFormat.iInputSamplingRate)
   3278        )
   3279     {
   3280         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3281                         (0, "PVMFOMXEncNode-%s::NegotiateAudioComponentParameters() Encode parameters not set correctly", iNodeTypeId));
   3282         return false;
   3283     }
   3284 
   3285     // first of all, check if the port supports the adequate port format
   3286     OMX_AUDIO_PARAM_PORTFORMATTYPE Audio_port_format;
   3287     OMX_AUDIO_CODINGTYPE DesiredPortFormat = OMX_AUDIO_CodingPCM;
   3288     CONFIG_SIZE_AND_VERSION(Audio_port_format);
   3289 
   3290     Audio_port_format.nPortIndex = iInputPortIndex; // set input port as target
   3291 
   3292     // loop over supported formats until we hit the one we want
   3293     // or until the component has no more supported formats (in which case it returns OMX_ErrorNoMore
   3294     Err = OMX_ErrorNone;
   3295     Audio_port_format.nIndex = 0; //init the format counter
   3296     while (OMX_ErrorNone == Err)
   3297     {
   3298 
   3299         Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamAudioPortFormat, &Audio_port_format);
   3300         if ((OMX_ErrorNone != Err))
   3301         {
   3302             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3303                             (0, "PVMFOMXEncNode-%s::NegotiateAudioComponentParameters() Problem getting port format for input port %d or no desired port format found", iNodeTypeId, iInputPortIndex));
   3304             return false;
   3305         }
   3306 
   3307         if (Audio_port_format.eEncoding == DesiredPortFormat)
   3308             break;
   3309 
   3310         Audio_port_format.nIndex ++;
   3311     }
   3312 
   3313     // OK, we've found the desired format, set it as the one used
   3314     Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamAudioPortFormat, &Audio_port_format);
   3315     if ((OMX_ErrorNone != Err))
   3316     {
   3317         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3318                         (0, "PVMFOMXEncNode-%s::NegotiateAudioComponentParameters() Problem setting port format for input port %d ", iNodeTypeId, iInputPortIndex));
   3319         return false;
   3320     }
   3321 
   3322 
   3323 
   3324 
   3325     CONFIG_SIZE_AND_VERSION(iParamPort);
   3326     iParamPort.nPortIndex = iInputPortIndex;
   3327     Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamPortDefinition, &iParamPort);
   3328     if (Err != OMX_ErrorNone)
   3329     {
   3330         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3331                         (0, "PVMFOMXEncNode-%s::NegotiateAudioComponentParameters() Problem negotiating with input port %d ", iNodeTypeId, iInputPortIndex));
   3332         return false;
   3333     }
   3334 
   3335     // TODO: FIX THIS - JUST READ THE BUFFER SIZE FROM COMPONENT PORT
   3336     if (iInFormat == PVMF_MIME_PCM16)
   3337     {
   3338         iOMXComponentInputBufferSize = MAX_NUM_AMR_FRAMES_PER_BUFFER * (PVMF_AMRENC_DEFAULT_FRAME_DURATION * PVMF_AMRENC_DEFAULT_SAMPLING_RATE * PVMF_AMRENC_DEFAULT_BITSPERSAMPLE) / (1000 * 8);
   3339 
   3340     }
   3341     else
   3342     {
   3343         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3344                         (0, "PVMFOMXEncNode-%s::NegotiateAudioComponentParameters() Problem with input port %d color format", iNodeTypeId, iInputPortIndex));
   3345         return false;
   3346     }
   3347 
   3348     // The buffer size is a read only parameter. If the requested size is larger than what we wish to allocate -
   3349     // we'll allocate what the component desires
   3350 
   3351     if (iParamPort.nBufferSize > iOMXComponentInputBufferSize)
   3352     {
   3353         iOMXComponentInputBufferSize = iParamPort.nBufferSize;
   3354     }
   3355 
   3356 
   3357     // set Encoding type
   3358 
   3359     //iParamPort.format.audio.bFlagErrorConcealment = OMX_TRUE;
   3360 
   3361     // indicate that input is uncompressed i.e. PCM
   3362     iParamPort.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
   3363 
   3364     // let the component decide about the number of input buffers
   3365     iNumInputBuffers = iParamPort.nBufferCountActual;
   3366 
   3367     // do we need to increase the number of buffers?
   3368     if (iNumInputBuffers < iParamPort.nBufferCountMin)
   3369         iNumInputBuffers = iParamPort.nBufferCountMin;
   3370 
   3371 
   3372     // if component allows us to allocate buffers, we'll decide how many to allocate
   3373     if (iOMXComponentSupportsExternalInputBufferAlloc && (iParamPort.nBufferCountMin < NUMBER_INPUT_BUFFER))
   3374     {
   3375         // preset the number of input buffers
   3376         iNumInputBuffers = NUMBER_INPUT_BUFFER;
   3377     }
   3378 
   3379     // set the number of input buffer
   3380     iParamPort.nBufferCountActual = iNumInputBuffers;
   3381 
   3382     // set the number of actual input buffers
   3383     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3384                     (0, "PVMFOMXEncNode-%s::NegotiateAudioComponentParameters() Inport buffers %d,size %d", iNodeTypeId, iNumInputBuffers, iOMXComponentInputBufferSize));
   3385 
   3386     // lock in the input port parameters
   3387     CONFIG_SIZE_AND_VERSION(iParamPort);
   3388     Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamPortDefinition, &iParamPort);
   3389     if (Err != OMX_ErrorNone)
   3390     {
   3391         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3392                         (0, "PVMFOMXEncNode-%s::NegotiateAudioComponentParameters() Problem setting parameters in input port %d ", iNodeTypeId, iInputPortIndex));
   3393         return false;
   3394     }
   3395 
   3396     // For INPUT, we also need to set the PCM parameters, such as sampling rate, etc.
   3397     // GET the output buffer params and sizes
   3398     OMX_AUDIO_PARAM_PCMMODETYPE Audio_Pcm_Param;
   3399     Audio_Pcm_Param.nPortIndex = iInputPortIndex;
   3400 
   3401     CONFIG_SIZE_AND_VERSION(Audio_Pcm_Param);
   3402 
   3403 
   3404     Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamAudioPcm, &Audio_Pcm_Param);
   3405     if (Err != OMX_ErrorNone)
   3406     {
   3407         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3408                         (0, "PVMFOMXEncNode-%s::NegotiateAudioComponentParameters() Problem getting PCM parameters with input port %d ", iNodeTypeId, iInputPortIndex));
   3409         return false;
   3410     }
   3411 
   3412 
   3413     Audio_Pcm_Param.nChannels       = (OMX_U32) iAudioInputFormat.iInputNumChannels;
   3414     Audio_Pcm_Param.eNumData        =   OMX_NumericalDataSigned; // signed
   3415     Audio_Pcm_Param.eEndian         =   OMX_EndianLittle; // little-endian
   3416     Audio_Pcm_Param.bInterleaved    = ((EINTERLEAVE_LR == iAudioInputFormat.iInputInterleaveMode) ? OMX_TRUE : OMX_FALSE);
   3417     Audio_Pcm_Param.nBitPerSample   = (OMX_U32) iAudioInputFormat.iInputBitsPerSample;
   3418     Audio_Pcm_Param.nSamplingRate   = (OMX_U32) iAudioInputFormat.iInputSamplingRate;
   3419     Audio_Pcm_Param.ePCMMode        =   OMX_AUDIO_PCMModeLinear;
   3420     // don't set - let use default Audio_Pcm_Param.eChannelMapping
   3421 
   3422 
   3423     CONFIG_SIZE_AND_VERSION(Audio_Pcm_Param);
   3424 
   3425     Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamAudioPcm, &Audio_Pcm_Param);
   3426     if (Err != OMX_ErrorNone)
   3427     {
   3428         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3429                         (0, "PVMFOMXEncNode-%s::NegotiateAudioComponentParameters() Problem setting PCM parameters with input port %d ", iNodeTypeId, iInputPortIndex));
   3430         return false;
   3431     }
   3432 
   3433     //////////////////////// OUTPUT PORT////////////////////////////////////////////////
   3434 
   3435     // first of all, check if the port supports the adequate port format
   3436     if ((iOutFormat == PVMF_MIME_AMR_IETF) ||
   3437             (iOutFormat == PVMF_MIME_AMRWB_IETF) ||
   3438             (iOutFormat == PVMF_MIME_AMR_IF2))
   3439     {
   3440         DesiredPortFormat = OMX_AUDIO_CodingAMR;
   3441     }
   3442     else if ((iOutFormat == PVMF_MIME_ADIF) ||
   3443              (iOutFormat == PVMF_MIME_ADTS) ||
   3444              (iOutFormat == PVMF_MIME_MPEG4_AUDIO))
   3445     {
   3446         DesiredPortFormat = OMX_AUDIO_CodingAAC;
   3447     }
   3448     else
   3449     {
   3450         DesiredPortFormat = OMX_AUDIO_CodingUnused;
   3451     }
   3452 
   3453     if (DesiredPortFormat == OMX_AUDIO_CodingUnused)
   3454     {
   3455         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3456                         (0, "PVMFOMXEncNode-%s::NegotiateAudioComponentParameters() Problem with output port %d format", iNodeTypeId, iOutputPortIndex));
   3457         return false;
   3458     }
   3459 
   3460     CONFIG_SIZE_AND_VERSION(Audio_port_format);
   3461 
   3462     Audio_port_format.nPortIndex = iOutputPortIndex; // set output port as target
   3463 
   3464     // loop over supported formats until we hit the one we want
   3465     // or until the component has no more supported formats (in which case it returns OMX_ErrorNoMore
   3466     Err = OMX_ErrorNone;
   3467     Audio_port_format.nIndex = 0; //init the format counter
   3468     while (OMX_ErrorNone == Err)
   3469     {
   3470 
   3471         Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamAudioPortFormat, &Audio_port_format);
   3472         if ((OMX_ErrorNone != Err))
   3473         {
   3474             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3475                             (0, "PVMFOMXEncNode-%s::NegotiateAudioComponentParameters() Problem getting port format for output port %d or no desired port format found", iNodeTypeId, iOutputPortIndex));
   3476             return false;
   3477         }
   3478 
   3479         if (Audio_port_format.eEncoding == DesiredPortFormat)
   3480             break;
   3481 
   3482         Audio_port_format.nIndex ++;
   3483     }
   3484 
   3485     // OK, we've found the desired format, set it as the one used
   3486     Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamAudioPortFormat, &Audio_port_format);
   3487     if ((OMX_ErrorNone != Err))
   3488     {
   3489         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3490                         (0, "PVMFOMXEncNode-%s::NegotiateAudioComponentParameters() Problem setting port format for output port %d ", iNodeTypeId, iOutputPortIndex));
   3491         return false;
   3492     }
   3493 
   3494 
   3495     //Port 1 for output port
   3496     CONFIG_SIZE_AND_VERSION(iParamPort);
   3497     iParamPort.nPortIndex = iOutputPortIndex;
   3498     Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamPortDefinition, &iParamPort);
   3499     if (Err != OMX_ErrorNone)
   3500     {
   3501         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3502                         (0, "PVMFOMXEncNode-%s::NegotiateAudioComponentParameters() Problem negotiating with output port %d ", iNodeTypeId, iOutputPortIndex));
   3503         return false;
   3504     }
   3505 
   3506     // let the component decide output buffer size
   3507     iOMXComponentOutputBufferSize = iParamPort.nBufferSize;
   3508 
   3509     // let the component decide num output buffers
   3510     iNumOutputBuffers = iParamPort.nBufferCountActual;
   3511 
   3512     //check the number
   3513     if (iNumOutputBuffers < iParamPort.nBufferCountMin)
   3514         iNumOutputBuffers = iParamPort.nBufferCountMin;
   3515 
   3516 
   3517     // set the number ourselves
   3518     if (iOMXComponentSupportsExternalOutputBufferAlloc && (iParamPort.nBufferCountMin < NUMBER_OUTPUT_BUFFER))
   3519     {
   3520         iNumOutputBuffers = NUMBER_OUTPUT_BUFFER;
   3521     }
   3522 
   3523     iParamPort.nBufferCountActual = iNumOutputBuffers;
   3524 
   3525 
   3526     // set the output (target) format, etc.
   3527     iParamPort.format.audio.bFlagErrorConcealment = OMX_TRUE;
   3528 
   3529 
   3530 
   3531     if ((iOutFormat == PVMF_MIME_AMR_IETF) ||
   3532             (iOutFormat == PVMF_MIME_AMRWB_IETF) ||
   3533             (iOutFormat == PVMF_MIME_AMR_IF2))
   3534     {
   3535         iParamPort.format.audio.eEncoding = OMX_AUDIO_CodingAMR;
   3536     }
   3537     else if ((iOutFormat == PVMF_MIME_ADTS) ||
   3538              (iOutFormat == PVMF_MIME_ADIF) ||
   3539              (iOutFormat == PVMF_MIME_MPEG4_AUDIO))
   3540     {
   3541         iParamPort.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
   3542     }
   3543 
   3544     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3545                     (0, "PVMFOMXEncNode-%s::NegotiateAudioComponentParameters() Outport buffers %d,size %d", iNodeTypeId, iNumOutputBuffers, iOMXComponentOutputBufferSize));
   3546 
   3547 
   3548     CONFIG_SIZE_AND_VERSION(iParamPort);
   3549     Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamPortDefinition, &iParamPort);
   3550     if (Err != OMX_ErrorNone)
   3551     {
   3552         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3553                         (0, "PVMFOMXEncNode-%s::NegotiateAudioComponentParameters() Problem setting parameters in output port %d ", iNodeTypeId, iOutputPortIndex));
   3554         return false;
   3555 
   3556     }
   3557 
   3558     // now call codec specific parameter setting
   3559     bool status = true;
   3560     if ((iOutFormat == PVMF_MIME_AMR_IETF) ||
   3561             (iOutFormat == PVMF_MIME_AMRWB_IETF) ||
   3562             (iOutFormat == PVMF_MIME_AMR_IF2))
   3563     {
   3564 
   3565         status = SetAMREncoderParameters();
   3566     }
   3567     else if ((iOutFormat == PVMF_MIME_ADTS) ||
   3568              (iOutFormat == PVMF_MIME_ADIF) ||
   3569              (iOutFormat == PVMF_MIME_MPEG4_AUDIO))
   3570     {
   3571         status = SetAACEncoderParameters();
   3572     }
   3573 
   3574 
   3575     return status;
   3576 }
   3577 
   3578 bool PVMFOMXEncNode::SetAMREncoderParameters()
   3579 {
   3580 
   3581     OMX_ERRORTYPE Err = OMX_ErrorNone;
   3582     OMX_AUDIO_PARAM_AMRTYPE AmrType;
   3583 
   3584     CONFIG_SIZE_AND_VERSION(AmrType);
   3585     AmrType.nPortIndex = iOutputPortIndex;
   3586 
   3587     Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamAudioAmr, &AmrType);
   3588     if (Err != OMX_ErrorNone)
   3589     {
   3590         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3591                         (0, "PVMFOMXEncNode-%s::SetAMREncoderParameters - Problem getting AMR parameters in output port %d ", iNodeTypeId, iOutputPortIndex));
   3592         return false;
   3593     }
   3594 
   3595     AmrType.nChannels = iAudioEncodeParam.iOutputNumChannels; // must be 1
   3596 
   3597     switch (iAudioEncodeParam.iAMRBitrate)
   3598     {
   3599         case GSM_AMR_4_75:  // AMR NB bitrates
   3600             AmrType.eAMRBandMode = OMX_AUDIO_AMRBandModeNB0;
   3601             break;
   3602         case GSM_AMR_5_15:
   3603             AmrType.eAMRBandMode = OMX_AUDIO_AMRBandModeNB1;
   3604             break;
   3605         case GSM_AMR_5_90:
   3606             AmrType.eAMRBandMode = OMX_AUDIO_AMRBandModeNB2;
   3607             break;
   3608         case GSM_AMR_6_70:
   3609             AmrType.eAMRBandMode = OMX_AUDIO_AMRBandModeNB3;
   3610             break;
   3611         case GSM_AMR_7_40:
   3612             AmrType.eAMRBandMode = OMX_AUDIO_AMRBandModeNB4;
   3613             break;
   3614         case GSM_AMR_7_95:
   3615             AmrType.eAMRBandMode = OMX_AUDIO_AMRBandModeNB5;
   3616             break;
   3617         case GSM_AMR_10_2:
   3618             AmrType.eAMRBandMode = OMX_AUDIO_AMRBandModeNB6;
   3619             break;
   3620         case GSM_AMR_12_2:
   3621             AmrType.eAMRBandMode = OMX_AUDIO_AMRBandModeNB7;
   3622             break;
   3623         case GSM_AMR_6_60: // AMR WB bitrates start here
   3624             AmrType.eAMRBandMode = OMX_AUDIO_AMRBandModeWB0;
   3625             break;
   3626         case GSM_AMR_8_85:
   3627             AmrType.eAMRBandMode = OMX_AUDIO_AMRBandModeWB1;
   3628             break;
   3629         case GSM_AMR_12_65:
   3630             AmrType.eAMRBandMode = OMX_AUDIO_AMRBandModeWB2;
   3631             break;
   3632         case GSM_AMR_14_25:
   3633             AmrType.eAMRBandMode = OMX_AUDIO_AMRBandModeWB3;
   3634             break;
   3635         case GSM_AMR_15_85:
   3636             AmrType.eAMRBandMode = OMX_AUDIO_AMRBandModeWB4;
   3637             break;
   3638         case GSM_AMR_18_25:
   3639             AmrType.eAMRBandMode = OMX_AUDIO_AMRBandModeWB5;
   3640             break;
   3641         case GSM_AMR_19_85:
   3642             AmrType.eAMRBandMode = OMX_AUDIO_AMRBandModeWB6;
   3643             break;
   3644         case GSM_AMR_23_05:
   3645             AmrType.eAMRBandMode = OMX_AUDIO_AMRBandModeWB7;
   3646             break;
   3647         case GSM_AMR_23_85:
   3648             AmrType.eAMRBandMode = OMX_AUDIO_AMRBandModeWB8;
   3649             break;
   3650         default:
   3651             return false;
   3652     }
   3653 
   3654     AmrType.eAMRDTXMode = OMX_AUDIO_AMRDTXModeOnAuto;
   3655 
   3656     if ((iOutFormat == PVMF_MIME_AMR_IETF) || (iOutFormat == PVMF_MIME_AMRWB_IETF))
   3657     {
   3658         AmrType.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
   3659     }
   3660     else if (iOutFormat == PVMF_MIME_AMR_IF2)
   3661     {
   3662         AmrType.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatIF2;
   3663     }
   3664 
   3665     CONFIG_SIZE_AND_VERSION(AmrType);
   3666     AmrType.nPortIndex = iOutputPortIndex;
   3667 
   3668     Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamAudioAmr, &AmrType);
   3669     if (Err != OMX_ErrorNone)
   3670     {
   3671         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3672                         (0, "PVMFOMXEncNode-%s::SetAMREncoderParameters - Problem setting AMR parameters in output port %d ", iNodeTypeId, iOutputPortIndex));
   3673         return false;
   3674     }
   3675 
   3676     return true;
   3677 }
   3678 
   3679 bool PVMFOMXEncNode::SetAACEncoderParameters()
   3680 {
   3681 
   3682     OMX_ERRORTYPE Err = OMX_ErrorNone;
   3683     OMX_AUDIO_PARAM_AACPROFILETYPE AacType;
   3684 
   3685 
   3686     CONFIG_SIZE_AND_VERSION(AacType);
   3687     AacType.nPortIndex = iOutputPortIndex;
   3688 
   3689     Err = OMX_GetParameter(iOMXEncoder, OMX_IndexParamAudioAac, &AacType);
   3690     if (Err != OMX_ErrorNone)
   3691     {
   3692         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3693                         (0, "PVMFOMXEncNode-%s::SetAACEncoderParameters - Problem getting AAC parameters in output port %d ", iNodeTypeId, iOutputPortIndex));
   3694         return false;
   3695     }
   3696 
   3697     AacType.nChannels = iAudioEncodeParam.iOutputNumChannels;
   3698     // The following parameter could be set to input sampling rate or 0 (i.e. unknown)
   3699     AacType.nSampleRate = iAudioEncodeParam.iOutputSamplingRate;
   3700     // The following parameter could be set to 0 (i.e. unknown)
   3701     AacType.nBitRate = iAudioEncodeParam.iOutputBitrate;
   3702 
   3703     // Let encoder decide the following parameters - i.e. set to 0
   3704     AacType.nAudioBandWidth =   0;
   3705     AacType.nFrameLength    =   0;
   3706     AacType.nAACtools =         OMX_AUDIO_AACToolAll; // this means all tools are allowed - let encoder decide
   3707     AacType.nAACERtools =       OMX_AUDIO_AACERNone;   // error resilience tools are not allowed
   3708 
   3709     // Set the AAC profile to use LC
   3710     AacType.eAACProfile = OMX_AUDIO_AACObjectLC;
   3711 
   3712     // Do set the stream format
   3713     if (iOutFormat == PVMF_MIME_ADTS)
   3714     {
   3715         AacType.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS;
   3716     }
   3717     else if (iOutFormat == PVMF_MIME_ADIF)
   3718     {
   3719         AacType.eAACStreamFormat = OMX_AUDIO_AACStreamFormatADIF;
   3720     }
   3721     else if (iOutFormat == PVMF_MIME_MPEG4_AUDIO)
   3722     {
   3723         AacType.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
   3724     }
   3725 
   3726     // Set the AAC channel mode - (stereo, or mono)
   3727     if (iAudioEncodeParam.iOutputNumChannels == 1)
   3728     {
   3729         AacType.eChannelMode = OMX_AUDIO_ChannelModeMono;
   3730     }
   3731     else if (iAudioEncodeParam.iOutputNumChannels == 2)
   3732     {
   3733         AacType.eChannelMode = OMX_AUDIO_ChannelModeStereo;
   3734     }
   3735 
   3736     CONFIG_SIZE_AND_VERSION(AacType);
   3737     AacType.nPortIndex = iOutputPortIndex;
   3738 
   3739     Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamAudioAac, &AacType);
   3740     if (Err != OMX_ErrorNone)
   3741     {
   3742         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3743                         (0, "PVMFOMXEncNode-%s::SetAACEncoderParameters - Problem setting AAC parameters in output port %d ", iNodeTypeId, iOutputPortIndex));
   3744         return false;
   3745     }
   3746 
   3747     return true;
   3748 }
   3749 
   3750 bool PVMFOMXEncNode::SetDefaultCapabilityFlags()
   3751 {
   3752 
   3753     iIsOMXComponentMultiThreaded = true;
   3754 
   3755     iOMXComponentSupportsExternalOutputBufferAlloc = false;
   3756     iOMXComponentSupportsExternalInputBufferAlloc = false;
   3757     iOMXComponentSupportsMovableInputBuffers = false;
   3758 
   3759     iOMXComponentUsesNALStartCodes = true;
   3760     iOMXComponentSupportsPartialFrames = false;
   3761     iOMXComponentCanHandleIncompleteFrames = false;
   3762     iOMXComponentUsesFullAVCFrames = false;
   3763 
   3764     return true;
   3765 }
   3766 
   3767 
   3768 
   3769 bool PVMFOMXEncNode::SendEOSBufferToOMXComponent()
   3770 {
   3771 
   3772     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3773                     (0, "PVMFOMXEncNode-%s::SendEOSBufferToOMXComponent() In", iNodeTypeId));
   3774 
   3775 
   3776     // first of all, check if the component is running. EOS could be sent prior to component/encoder
   3777     // even being initialized
   3778 
   3779     // returning false will ensure that the EOS will be sent downstream anyway without waiting for the
   3780     // Component to respond
   3781     if (iCurrentEncoderState != OMX_StateExecuting)
   3782         return false;
   3783 
   3784     // get an input buffer. Without a buffer, no point in proceeding
   3785     InputBufCtrlStruct *input_buf = NULL;
   3786     int32 errcode = 0;
   3787 
   3788     // we already checked that the number of buffers is OK, so we don't expect problems
   3789     // try to get input buffer header
   3790     OSCL_TRY(errcode, input_buf = (InputBufCtrlStruct *) iInBufMemoryPool->allocate(iInputAllocSize));
   3791     if (errcode != 0)
   3792     {
   3793         if (errcode == OsclErrNoResources)
   3794         {
   3795 
   3796             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger,
   3797                             PVLOGMSG_DEBUG, (0, "PVMFOMXEncNode-%s::SendEOSBufferToOMXComponent() No more buffers in the mempool - unexpected", iNodeTypeId));
   3798 
   3799             iInBufMemoryPool->notifyfreechunkavailable(*this, (OsclAny*) iInBufMemoryPool); // To signal when next deallocate() is called on mempool
   3800 
   3801             return false;
   3802         }
   3803         else
   3804         {
   3805             // Memory allocation for the pool failed
   3806             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   3807                             (0, "PVMFOMXEncNode-%s::SendEOSBufferToOMXComponent() Input mempool error", iNodeTypeId));
   3808 
   3809 
   3810             SetState(EPVMFNodeError);
   3811             ReportErrorEvent(PVMFErrNoMemory);
   3812             return false;
   3813         }
   3814 
   3815     }
   3816 
   3817     // keep track of buffers. When buffer is deallocated/released, the counter will be decremented
   3818     iInBufMemoryPool->notifyfreechunkavailable(*this, (OsclAny*) iInBufMemoryPool);
   3819     iNumOutstandingInputBuffers++;
   3820 
   3821     // in this case, no need to use input msg refcounter. Make sure its unbound
   3822     (input_buf->pMediaData).Unbind();
   3823 
   3824     // THIS IS AN EMPTY BUFFER. FLAGS ARE THE ONLY IMPORTANT THING
   3825     input_buf->pBufHdr->nFilledLen = 0;
   3826     input_buf->pBufHdr->nOffset = 0;
   3827 
   3828     iInputTimestampClock.update_clock(iEndOfDataTimestamp); // this will also take into consideration the rollover
   3829     // convert TS in input timescale into OMX_TICKS
   3830     iOMXTicksTimestamp = ConvertTimestampIntoOMXTicks(iInputTimestampClock);
   3831 
   3832     input_buf->pBufHdr->nTimeStamp = iOMXTicksTimestamp;
   3833 
   3834 
   3835     // set ptr to input_buf structure for Context (for when the buffer is returned)
   3836     input_buf->pBufHdr->pAppPrivate = (OMX_PTR) input_buf;
   3837 
   3838     // do not use Mark here (but init to NULL to prevent problems)
   3839     input_buf->pBufHdr->hMarkTargetComponent = NULL;
   3840     input_buf->pBufHdr->pMarkData = NULL;
   3841 
   3842 
   3843     // init buffer flags
   3844     input_buf->pBufHdr->nFlags = 0;
   3845 
   3846     input_buf->pBufHdr->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
   3847     // most importantly, set the EOS flag:
   3848     input_buf->pBufHdr->nFlags |= OMX_BUFFERFLAG_EOS;
   3849 
   3850     // send buffer to component
   3851     OMX_EmptyThisBuffer(iOMXEncoder, input_buf->pBufHdr);
   3852 
   3853     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3854                     (0, "PVMFOMXEncNode-%s::SendEOSBufferToOMXComponent() Out", iNodeTypeId));
   3855 
   3856     return true;
   3857 
   3858 }
   3859 
   3860 
   3861 bool PVMFOMXEncNode::SendInputBufferToOMXComponent()
   3862 {
   3863 
   3864     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3865                     (0, "PVMFOMXEncNode-%s::SendInputBufferToOMXComponent() In", iNodeTypeId));
   3866 
   3867     // first of all , get an input buffer. Without a buffer, no point in proceeding
   3868     InputBufCtrlStruct *input_buf = NULL;
   3869     int32 errcode = 0;
   3870     uint32 ii;
   3871 
   3872     do
   3873     {
   3874         // do loop to loop over all fragments
   3875 
   3876         // try to get input buffer header
   3877         InputBufCtrlStruct *temp = NULL;
   3878         OSCL_TRY(errcode, temp = (InputBufCtrlStruct *) iInBufMemoryPool->allocate(iInputAllocSize));
   3879         //input_buf = temp; //JJDBG
   3880         if (errcode != 0)
   3881         {
   3882             if (errcode == OsclErrNoResources)
   3883             {
   3884 
   3885                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger,
   3886                                 PVLOGMSG_DEBUG, (0, "PVMFOMXEncNode-%s::SendInputBufferToOMXComponent() No more buffers in the mempool", iNodeTypeId));
   3887 
   3888                 iInBufMemoryPool->notifyfreechunkavailable(*this, (OsclAny*) iInBufMemoryPool); // To signal when next deallocate() is called on mempool
   3889 
   3890                 return false;
   3891             }
   3892             else
   3893             {
   3894                 // Memory allocation for the pool failed
   3895                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   3896                                 (0, "PVMFOMXEncNode-%s::SendInputBufferToOMXComponent() Input mempool error", iNodeTypeId));
   3897 
   3898 
   3899                 SetState(EPVMFNodeError);
   3900                 ReportErrorEvent(PVMFErrNoMemory);
   3901                 return false;
   3902             }
   3903 
   3904         }
   3905         input_buf = new(temp)InputBufCtrlStruct ; //JJDBG
   3906 
   3907         // keep track of buffers. When buffer is deallocated/released, the counter will be decremented
   3908         iInBufMemoryPool->notifyfreechunkavailable(*this, (OsclAny*) iInBufMemoryPool);
   3909         iNumOutstandingInputBuffers++;
   3910 
   3911         for (ii = 0; ii < iNumInputBuffers; ii++)
   3912         {
   3913             if (input_buf == in_ctrl_struct_ptr[ii])
   3914             {
   3915                 break;
   3916             }
   3917         }
   3918 
   3919         if (ii == iNumInputBuffers)
   3920             return false;
   3921 
   3922         input_buf->pBufHdr = (OMX_BUFFERHEADERTYPE *)in_buff_hdr_ptr[ii];
   3923 
   3924         // Now we have the buffer header (i.e. a buffer) to send to component:
   3925         // Depending on OMX component capabilities, either pass the input msg fragment(s) directly
   3926         //  into OMX component without copying (and update the input msg refcount)
   3927         //  or memcopy the content of input msg memfrag(s) into OMX component allocated buffers
   3928 
   3929 
   3930         // if this is the first fragment in a new message, extract some info:
   3931         if (iCurrFragNum == 0)
   3932         {
   3933 
   3934             // NOTE: SeqNum differ in Codec and in Node because of the fact that
   3935             // one msg can contain multiple fragments that are sent to the codec as
   3936             // separate buffers. Node tracks msgs and codec tracks even separate fragments
   3937 
   3938             iCodecSeqNum += (iDataIn->getSeqNum() - iInPacketSeqNum); // increment the codec seq. # by the same
   3939             // amount that the input seq. number increased
   3940 
   3941             iInPacketSeqNum = iDataIn->getSeqNum(); // remember input sequence number
   3942             iInTimestamp = iDataIn->getTimestamp();
   3943             iInDuration = iDataIn->getDuration();
   3944             iInNumFrags = iDataIn->getNumFragments();
   3945 
   3946 
   3947 
   3948             iCurrentMsgMarkerBit = iDataIn->getMarkerInfo() & PVMF_MEDIA_DATA_MARKER_INFO_M_BIT;
   3949 
   3950 
   3951             // logging info:
   3952             if (iDataIn->getNumFragments() > 1)
   3953             {
   3954                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3955                                 (0, "PVMFOMXEncNode-%s::SendInputBufferToOMXComponent() - New msg has MULTI-FRAGMENTS", iNodeTypeId));
   3956             }
   3957 
   3958             if (!(iDataIn->getMarkerInfo() & PVMF_MEDIA_DATA_MARKER_INFO_M_BIT))
   3959             {
   3960 
   3961                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3962                                 (0, "PVMFOMXEncNode-%s::SendInputBufferToOMXComponent() - New msg has NO MARKER BIT", iNodeTypeId));
   3963             }
   3964         }
   3965 
   3966 
   3967         // get a memfrag from the message
   3968         OsclRefCounterMemFrag frag;
   3969         iDataIn->getMediaFragment(iCurrFragNum, frag);
   3970 
   3971 
   3972         if (iOMXComponentSupportsMovableInputBuffers)
   3973         {
   3974             // no copying required
   3975 
   3976             // increment the RefCounter of the message associated with the mem fragment/buffer
   3977             // when sending this buffer to OMX component. (When getting the buffer back, the refcounter
   3978             // will be decremented. Thus, when the last fragment is returned, the input mssage is finally released
   3979 
   3980             iDataIn.GetRefCounter()->addRef();
   3981 
   3982             // associate the buffer ctrl structure with the message ref counter and ptr
   3983             input_buf->pMediaData = PVMFSharedMediaDataPtr(iDataIn.GetRep(), iDataIn.GetRefCounter());
   3984 
   3985 
   3986             // set pointer to the data, length, offset
   3987             input_buf->pBufHdr->pBuffer = (uint8 *)frag.getMemFragPtr();
   3988             input_buf->pBufHdr->nFilledLen = frag.getMemFragSize();
   3989             {//TODO: check whether addRef() is needed for fsi
   3990                 OsclRefCounterMemFrag fsifrag;
   3991                 iDataIn->getFormatSpecificInfo(fsifrag);
   3992                 if(sizeof(OsclAny*) != fsifrag.getMemFrag().len )
   3993                 {
   3994                     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   3995                             (0, "PVMFOMXEncNode-%s::SendInputBufferToOMXComponent() - ERROR buffer size %d", iNodeTypeId, fsifrag.getMemFrag().len ));
   3996                     return false;
   3997                 }
   3998                 oscl_memcpy(&(input_buf->pBufHdr->pPlatformPrivate), fsifrag.getMemFragPtr(), sizeof(OsclAny*) ); // restore ptr data from fsi
   3999             }
   4000 
   4001             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   4002                             (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));
   4003 
   4004             iCurrFragNum++; // increment fragment number and move on to the next
   4005 
   4006 
   4007         }
   4008         else
   4009         {
   4010 
   4011             // in this case, no need to use input msg refcounter, each buffer fragment is copied over and treated separately
   4012             (input_buf->pMediaData).Unbind();
   4013 
   4014 
   4015             // init variables
   4016             iCopyPosition = 0;
   4017             iFragmentSizeRemainingToCopy  = frag.getMemFragSize();
   4018 
   4019 
   4020             // can the remaining fragment fit into the buffer?
   4021             if (iFragmentSizeRemainingToCopy <= (input_buf->pBufHdr->nAllocLen))
   4022             {
   4023 
   4024                 oscl_memcpy(input_buf->pBufHdr->pBuffer,
   4025                             (void *)((uint8 *)frag.getMemFragPtr() + iCopyPosition),
   4026                             iFragmentSizeRemainingToCopy);
   4027 
   4028                 input_buf->pBufHdr->nFilledLen = iFragmentSizeRemainingToCopy;
   4029 
   4030                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   4031                                 (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));
   4032 
   4033                 iCopyPosition += iFragmentSizeRemainingToCopy;
   4034                 iFragmentSizeRemainingToCopy = 0;
   4035 
   4036 
   4037 
   4038             }
   4039             else
   4040             {
   4041                 // copy as much as you can of the current fragment into the current buffer
   4042                 oscl_memcpy(input_buf->pBufHdr->pBuffer,
   4043                             (void *)((uint8 *)frag.getMemFragPtr() + iCopyPosition),
   4044                             input_buf->pBufHdr->nAllocLen);
   4045 
   4046                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   4047                                 (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));
   4048 
   4049                 input_buf->pBufHdr->nFilledLen = input_buf->pBufHdr->nAllocLen;
   4050                 iCopyPosition += input_buf->pBufHdr->nAllocLen; // move current position within fragment forward
   4051                 iFragmentSizeRemainingToCopy -= input_buf->pBufHdr->nAllocLen;
   4052 
   4053             }
   4054 
   4055             // proceed to the next fragment regardless of input buffer size
   4056             iCurrFragNum++;
   4057         }
   4058 
   4059 
   4060         // set buffer fields (this is the same regardless of whether the input is movable or not
   4061         input_buf->pBufHdr->nOffset = 0;
   4062 
   4063 
   4064         iInputTimestampClock.update_clock(iInTimestamp); // this will also take into consideration the timestamp rollover
   4065         // convert TS in input timescale into OMX_TICKS
   4066         iOMXTicksTimestamp = ConvertTimestampIntoOMXTicks(iInputTimestampClock);
   4067 
   4068 
   4069         input_buf->pBufHdr->nTimeStamp = iOMXTicksTimestamp;
   4070 
   4071 
   4072         // set ptr to input_buf structure for Context (for when the buffer is returned)
   4073         input_buf->pBufHdr->pAppPrivate = (OMX_PTR) input_buf;
   4074 
   4075         // do not use Mark here (but init to NULL to prevent problems)
   4076         input_buf->pBufHdr->hMarkTargetComponent = NULL;
   4077         input_buf->pBufHdr->pMarkData = NULL;
   4078 
   4079 
   4080         // init buffer flags
   4081         input_buf->pBufHdr->nFlags = 0;
   4082 
   4083 
   4084         // set the key frame flag if necessary (mark every fragment that belongs to it)
   4085         if (iDataIn->getMarkerInfo() & PVMF_MEDIA_DATA_MARKER_INFO_RANDOM_ACCESS_POINT_BIT)
   4086             input_buf->pBufHdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
   4087 
   4088 
   4089         // in case of encoder, all input frames should be marked
   4090         input_buf->pBufHdr->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
   4091         OMX_ERRORTYPE myret = OMX_EmptyThisBuffer(iOMXEncoder, input_buf->pBufHdr);
   4092         if(OMX_ErrorNone != myret )
   4093         {
   4094             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   4095                     (0, "PVMFOMXEncNode-%s::SendInputBufferToOMXComponent() OMX_EmptyThisBuffer ERROR %d", iNodeTypeId, myret));
   4096             return false;
   4097         }
   4098 
   4099         // if we sent all fragments to OMX component, decouple the input message from iDataIn
   4100         // Input message is "decoupled", so that we can get a new message for processing into iDataIn
   4101         //  However, the actual message is released completely to upstream mempool once all of its fragments
   4102         //  are returned by the OMX component
   4103 
   4104         if (iCurrFragNum == iDataIn->getNumFragments())
   4105         {
   4106             iDataIn.Unbind();
   4107 
   4108         }
   4109 
   4110 
   4111     }
   4112     while (iCurrFragNum < iInNumFrags); //iDataIn->getNumFragments());
   4113 
   4114 
   4115     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   4116                     (0, "PVMFOMXEncNode-%s::SendInputBufferToOMXComponent() Out", iNodeTypeId));
   4117 
   4118     return true;
   4119 
   4120 }
   4121 
   4122 
   4123 
   4124 /////////////////////////////////////////////////////////////////////////////
   4125 bool PVMFOMXEncNode::CreateOutMemPool(uint32 num_buffers)
   4126 {
   4127 
   4128     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   4129                     (0, "PVMFOMXEncNode-%s::CreateOutMemPool() start", iNodeTypeId));
   4130     // In the case OMX component wants to allocate its own buffers,
   4131     // mempool only contains OutputBufCtrlStructures (i.e. ptrs to buffer headers)
   4132     // In case OMX component uses pre-allocated buffers (here),
   4133     // mempool allocates OutputBufCtrlStructure (i.e. ptrs to buffer hdrs), followed by actual buffers
   4134 
   4135     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   4136                     (0, "PVMFOMXEncNode-%s::CreateOutMemPool() Allocating output buffer header pointers", iNodeTypeId));
   4137 
   4138     iOutputAllocSize = oscl_mem_aligned_size((uint32)sizeof(OutputBufCtrlStruct));
   4139 
   4140     if (iOMXComponentSupportsExternalOutputBufferAlloc)
   4141     {
   4142         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   4143                         (0, "PVMFOMXEncNode-%s::CreateOutMemPool() Allocating output buffers of size %d as well", iNodeTypeId, iOMXComponentOutputBufferSize));
   4144 
   4145         //pre-negotiated output buffer size
   4146         iOutputAllocSize += iOMXComponentOutputBufferSize;
   4147     }
   4148 
   4149     // ENCODER SPECIFIC FOR AVC RAW (BYTESTREAM) FORMAT
   4150     if ((iOutFormat == PVMF_MIME_H264_VIDEO_RAW) &&
   4151             (!iOMXComponentUsesFullAVCFrames) &&
   4152             (!iOMXComponentUsesNALStartCodes))
   4153     {
   4154         iOutputAllocSize += 4; // NAL SYNC WORD SIZE
   4155     }
   4156 
   4157     // for media data wrapper
   4158     if (iMediaDataMemPool)
   4159     {
   4160         iMediaDataMemPool->removeRef();
   4161         iMediaDataMemPool = NULL;
   4162     }
   4163 
   4164     if (iOutBufMemoryPool)
   4165     {
   4166         iOutBufMemoryPool->removeRef();
   4167         iOutBufMemoryPool = NULL;
   4168     }
   4169 
   4170     int32 leavecode = 0;
   4171     OSCL_TRY(leavecode, iOutBufMemoryPool = OSCL_NEW(OsclMemPoolFixedChunkAllocator, (num_buffers)););
   4172     if (leavecode || iOutBufMemoryPool == NULL)
   4173     {
   4174         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger,
   4175                         PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::CreateOutMemPool() Memory pool structure for output buffers failed to allocate", iNodeTypeId));
   4176         return false;
   4177     }
   4178 
   4179 
   4180 
   4181     // allocate a dummy buffer to actually create the mempool
   4182     OsclAny *dummy_alloc = NULL; // this dummy buffer will be released at end of scope
   4183     leavecode = 0;
   4184     OSCL_TRY(leavecode, dummy_alloc = iOutBufMemoryPool->allocate(iOutputAllocSize));
   4185     if (leavecode || dummy_alloc == NULL)
   4186     {
   4187 
   4188         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger,
   4189                         PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::CreateOutMemPool() Memory pool for output buffers failed to allocate", iNodeTypeId));
   4190         return false;
   4191     }
   4192     iOutBufMemoryPool->deallocate(dummy_alloc);
   4193     // init the counter
   4194     iNumOutstandingOutputBuffers = 0;
   4195 
   4196     // allocate mempool for media data message wrapper
   4197     leavecode = 0;
   4198     OSCL_TRY(leavecode, iMediaDataMemPool = OSCL_NEW(OsclMemPoolFixedChunkAllocator, (num_buffers, PVOMXENC_MEDIADATA_CHUNKSIZE)));
   4199     if (leavecode || iMediaDataMemPool == NULL)
   4200     {
   4201         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::CreateOutMemPool() Media Data Buffer pool for output buffers failed to allocate", iNodeTypeId));
   4202         return false;
   4203     }
   4204 
   4205     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::CreateOutMemPool() done", iNodeTypeId));
   4206     return true;
   4207 }
   4208 /////////////////////////////////////////////////////////////////////////////////////////////////////
   4209 ///////////////////////////// Creates memory pool for input buffer management ///////////////////////
   4210 /////////////////////////////////////////////////////////////////////////////////////////////////////
   4211 bool PVMFOMXEncNode::CreateInputMemPool(uint32 num_buffers)
   4212 {
   4213     // 3 cases in order of preference and simplicity
   4214 
   4215     // Case 1 (buffers allocated upstream - no memcpy needed):
   4216     //  PV OMX Component - We use buffers allocated outside the OMX node (i.e. allocated upstream)
   4217     // Mempool contains InputBufCtrlStructures (ptrs to buffer headers and PMVFMediaData ptrs - to keep track of when to unbind input msgs)
   4218 
   4219     // NOTE:    in this case, when providing input buffers to OMX component,
   4220     //          OMX_UseBuffer calls will provide some initial pointers and sizes of buffers, but these
   4221     //          are dummy values. Actual buffer pointers and filled sizes will be obtained from the input msg fragments.
   4222     //          The PV OMX component will use the buffers even if the ptrs differ from the ones during initialization
   4223     //          3rd party OMX components can also use this case if they are capable of ignoring the actual buffer pointers in
   4224     //          buffer header field (i.e. if after OMX_UseBuffer(...) call, they allow the ptr to actual buffer data to change at a later time
   4225 
   4226     // CASE 2 (buffers allocated in the node - memcpy needed)
   4227     //          If 3rd party OMX component can use buffers allocated outside the OMX component, but it cannot
   4228     //          change buffer ptr allocations dynamically (i.e. after initialization with OMX_UseBuffer call is complete)
   4229 
   4230     //      Mempool contains InputBufCtrlStructures (ptrs to buffer headers, PVMFMediaData ptrs to keep track of when to unbind input msgs) +
   4231     //              actual buffers.
   4232     //          NOTE: Data must be copied from input message into the local buffer before the buffer is given to the OMX component
   4233 
   4234     // CASE 3 (buffers allocated in the component - memcpy needed)
   4235     //          If 3rd party OMX component must allocate its own buffers
   4236     //          Mempool only contains InputBufCtrlStruct (ptrs to buffer headers + PMVFMediaData ptrs to keep track of when to unbind input msgs)
   4237     //          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)
   4238 
   4239     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   4240                     (0, "PVMFOMXEncNode-%s::CreateInputMemPool() start ", iNodeTypeId));
   4241 
   4242     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   4243                     (0, "PVMFOMXEncNode-%s::CreateInputMemPool() allocating buffer header pointers and shared media data ptrs ", iNodeTypeId));
   4244 
   4245 
   4246 
   4247     iInputAllocSize = oscl_mem_aligned_size((uint32) sizeof(InputBufCtrlStruct)); //aligned_size_buffer_header_ptr+aligned_size_media_data_ptr;
   4248 
   4249     // Need to allocate buffers in the node either if component supports external buffers buffers
   4250     // but they are not movable
   4251 
   4252     if ((iOMXComponentSupportsExternalInputBufferAlloc && !iOMXComponentSupportsMovableInputBuffers))
   4253     {
   4254         //pre-negotiated input buffer size
   4255         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   4256                         (0, "PVMFOMXEncNode-%s::CreateOutMemPool() Allocating input buffers of size %d as well", iNodeTypeId, iOMXComponentInputBufferSize));
   4257 
   4258         iInputAllocSize += iOMXComponentInputBufferSize;
   4259     }
   4260 
   4261     if (iInBufMemoryPool)
   4262     {
   4263         iInBufMemoryPool->removeRef();
   4264         iInBufMemoryPool = NULL;
   4265     }
   4266 
   4267     int32 leavecode = 0;
   4268     OSCL_TRY(leavecode, iInBufMemoryPool = OSCL_NEW(OsclMemPoolFixedChunkAllocator, (num_buffers)););
   4269     if (leavecode || iInBufMemoryPool == NULL)
   4270     {
   4271         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger,
   4272                         PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::CreateInputMemPool() Memory pool structure for input buffers failed to allocate", iNodeTypeId));
   4273         return false;
   4274     }
   4275     // try to allocate a dummy buffer to actually create the mempool and allocate the needed memory
   4276     // allocate a dummy buffer to actually create the mempool, this dummy buffer will be released at end of scope of this method
   4277     OsclAny *dummy_alloc = NULL;
   4278     leavecode = 0;
   4279     OSCL_TRY(leavecode, dummy_alloc = iInBufMemoryPool->allocate(iInputAllocSize));
   4280     if (leavecode || dummy_alloc == NULL)
   4281     {
   4282 
   4283         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger,
   4284                         PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::CreateInputMemPool() Memory pool for input buffers failed to allocate", iNodeTypeId));
   4285         return false;
   4286     }
   4287 
   4288     // init the counter
   4289     iNumOutstandingInputBuffers = 0;
   4290 
   4291 
   4292     iInputBufferToResendToComponent = NULL; // nothing to resend yet
   4293     iInBufMemoryPool->deallocate(dummy_alloc);
   4294 
   4295     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::CreateInputMemPool() done", iNodeTypeId));
   4296     return true;
   4297 }
   4298 ////////////////////////////////////////////////////////////////////////////
   4299 bool PVMFOMXEncNode::ProvideBuffersToComponent(OsclMemPoolFixedChunkAllocator *aMemPool, // allocator
   4300         uint32 aAllocSize,    // size to allocate from pool (hdr only or hdr+ buffer)
   4301         uint32 aNumBuffers,    // number of buffers
   4302         uint32 aActualBufferSize, // aactual buffer size
   4303         uint32 aPortIndex,      // port idx
   4304         bool aUseBufferOK,       // can component use OMX_UseBuffer or should it use OMX_AllocateBuffer
   4305         bool aIsThisInputBuffer      // is this input or output
   4306                                               )
   4307 {
   4308     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::ProvideBuffersToComponent() enter", iNodeTypeId));
   4309 
   4310     uint32 ii = 0;
   4311     OMX_ERRORTYPE err = OMX_ErrorNone;
   4312     OsclAny **ctrl_struct_ptr = aIsThisInputBuffer ? in_ctrl_struct_ptr : out_ctrl_struct_ptr;
   4313 
   4314     // Now, go through all buffers and tell component to
   4315     // either use a buffer, or to allocate its own buffer
   4316     for (ii = 0; ii < aNumBuffers; ii++)
   4317     {
   4318 
   4319         int32 errcode = 0;
   4320         // get the address where the buf hdr ptr will be stored
   4321         errcode = MemAllocate(ctrl_struct_ptr[ii], aMemPool, aAllocSize);
   4322         if ((errcode != OsclErrNone) || (ctrl_struct_ptr[ii] == NULL))
   4323         {
   4324             if (errcode == OsclErrNoResources)
   4325             {
   4326                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   4327                                 (0, "PVMFOMXEncNode-%s::ProvideBuffersToComponent ->allocate() failed for no mempool chunk available", iNodeTypeId));
   4328             }
   4329             else
   4330             {
   4331                 // General error
   4332                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   4333                                 (0, "PVMFOMXEncNode-%s::ProvideBuffersToComponent ->allocate() failed due to some general error", iNodeTypeId));
   4334 
   4335                 ReportErrorEvent(PVMFFailure);
   4336                 ChangeNodeState(EPVMFNodeError);
   4337             }
   4338 
   4339             return false;
   4340         }
   4341 
   4342         if (aUseBufferOK)
   4343         {
   4344             // Buffers are already allocated outside OMX component.
   4345             // In case of output buffers, the buffer itself is located
   4346             // just after the buffer header pointer.
   4347 
   4348             // In case of input buffers, the buffer header pointer is followed by a MediaDataSharedPtr
   4349             //  which is used to ensure proper unbinding of the input messages. The buffer itself is either:
   4350             //      a) allocated upstream (and the ptr to the buffer
   4351             //          is a dummy pointer to which the component does not pay attention - PV OMX component)
   4352             //      b) located just after the buffer header pointer and MediaDataSharedPtr
   4353 
   4354             uint8 *pB = ((uint8*) ctrl_struct_ptr[ii]);
   4355 
   4356 
   4357             // in case of input buffers, initialize also MediaDataSharedPtr structure
   4358             if (aIsThisInputBuffer)
   4359             {
   4360 
   4361                 InputBufCtrlStruct *temp = (InputBufCtrlStruct *) ctrl_struct_ptr[ii];
   4362                 oscl_memset(&(temp->pMediaData), 0, sizeof(PVMFSharedMediaDataPtr));
   4363                 temp->pMediaData = PVMFSharedMediaDataPtr(NULL, NULL);
   4364 
   4365                 // advance ptr to skip the structure
   4366                 pB += oscl_mem_aligned_size(sizeof(InputBufCtrlStruct));
   4367 
   4368                 err = OMX_UseBuffer(iOMXEncoder,    // hComponent
   4369                                     &(temp->pBufHdr),       // address where ptr to buffer header will be stored
   4370                                     aPortIndex,             // port index (for port for which buffer is provided)
   4371                                     ctrl_struct_ptr[ii],    // App. private data = pointer to beginning of allocated data
   4372                                     //              to have a context when component returns with a callback (i.e. to know
   4373                                     //              what to free etc.
   4374                                     (OMX_U32)aActualBufferSize,     // buffer size
   4375                                     pB);                        // buffer data ptr
   4376 
   4377                 in_buff_hdr_ptr[ii] = temp->pBufHdr;
   4378 
   4379             }
   4380             else
   4381             {
   4382                 OutputBufCtrlStruct *temp = (OutputBufCtrlStruct *) ctrl_struct_ptr[ii];
   4383                 // advance buffer ptr to skip the structure
   4384                 pB += oscl_mem_aligned_size(sizeof(OutputBufCtrlStruct));
   4385 
   4386                 if ((iOutFormat == PVMF_MIME_H264_VIDEO_RAW) &&
   4387                         !iOMXComponentUsesFullAVCFrames &&
   4388                         !iOMXComponentUsesNALStartCodes)
   4389                 {
   4390                     // write out NAL sync word at the beginning of the buffer
   4391                     pB[0] = 0;
   4392                     pB[1] = 0;
   4393                     pB[2] = 0;
   4394                     pB[3] = 1;
   4395                     pB += 4;
   4396 
   4397                     // THe buffer that the component knows is always the same
   4398                     // The node will move the ptr -4 when it needs teh sync word
   4399                 }
   4400 
   4401                 err = OMX_UseBuffer(iOMXEncoder,    // hComponent
   4402                                     &(temp->pBufHdr),       // address where ptr to buffer header will be stored
   4403                                     aPortIndex,             // port index (for port for which buffer is provided)
   4404                                     ctrl_struct_ptr[ii],    // App. private data = pointer to beginning of allocated data
   4405                                     //              to have a context when component returns with a callback (i.e. to know
   4406                                     //              what to free etc.
   4407                                     (OMX_U32)aActualBufferSize,     // buffer size
   4408                                     pB);                        // buffer data ptr
   4409 
   4410                 out_buff_hdr_ptr[ii] = temp->pBufHdr;
   4411 
   4412 
   4413             }
   4414 
   4415 
   4416         }
   4417         else
   4418         {
   4419             // the component must allocate its own buffers.
   4420             if (aIsThisInputBuffer)
   4421             {
   4422 
   4423                 InputBufCtrlStruct *temp = (InputBufCtrlStruct *) ctrl_struct_ptr[ii];
   4424                 // initialize the media data field to 0 //TODO cleanup work started in another record. JJ 05/12/09
   4425                 oscl_memset(&(temp->pMediaData), 0, sizeof(PVMFSharedMediaDataPtr));
   4426                 temp->pMediaData = PVMFSharedMediaDataPtr(NULL, NULL);
   4427 
   4428                 err = OMX_AllocateBuffer(iOMXEncoder,
   4429                                          &(temp->pBufHdr),
   4430                                          aPortIndex,
   4431                                          ctrl_struct_ptr[ii],
   4432                                          (OMX_U32)aActualBufferSize);
   4433 
   4434                 in_buff_hdr_ptr[ii] = temp->pBufHdr;
   4435             }
   4436             else
   4437             {
   4438                 OutputBufCtrlStruct *temp = (OutputBufCtrlStruct *) ctrl_struct_ptr[ii];
   4439                 err = OMX_AllocateBuffer(iOMXEncoder,
   4440                                          &(temp->pBufHdr),
   4441                                          aPortIndex,
   4442                                          ctrl_struct_ptr[ii],
   4443                                          (OMX_U32)aActualBufferSize);
   4444 
   4445                 out_buff_hdr_ptr[ii] = temp->pBufHdr;
   4446             }
   4447 
   4448         }
   4449 
   4450         if (err != OMX_ErrorNone)
   4451         {
   4452             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   4453                             (0, "PVMFOMXEncNode-%s::ProvideBuffersToComponent() Problem using/allocating a buffer", iNodeTypeId));
   4454 
   4455 
   4456             return false;
   4457         }
   4458 
   4459     }
   4460 
   4461     for (ii = 0; ii < aNumBuffers; ii++)
   4462     {
   4463         // after initializing the buffer hdr ptrs, return them
   4464         // to the mempool
   4465         aMemPool->deallocate((OsclAny*) ctrl_struct_ptr[ii]);
   4466     }
   4467 
   4468     // set the flags
   4469     if (aIsThisInputBuffer)
   4470     {
   4471         iInputBuffersFreed = false;
   4472     }
   4473     else
   4474     {
   4475         iOutputBuffersFreed = false;
   4476     }
   4477 
   4478     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::ProvideBuffersToComponent() done", iNodeTypeId));
   4479     return true;
   4480 }
   4481 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
   4482 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
   4483 bool PVMFOMXEncNode::FreeBuffersFromComponent(OsclMemPoolFixedChunkAllocator *aMemPool, // allocator
   4484         uint32 aAllocSize,     // size to allocate from pool (hdr only or hdr+ buffer)
   4485         uint32 aNumBuffers,    // number of buffers
   4486         uint32 aPortIndex,      // port idx
   4487         bool  aIsThisInputBuffer      // is this input or output
   4488                                              )
   4489 {
   4490     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::FreeBuffersToComponent() enter", iNodeTypeId));
   4491 
   4492     uint32 ii = 0;
   4493     OMX_ERRORTYPE err = OMX_ErrorNone;
   4494     OsclAny **ctrl_struct_ptr = aIsThisInputBuffer ? in_ctrl_struct_ptr : out_ctrl_struct_ptr;
   4495 
   4496     // Now, go through all buffers and tell component to free them
   4497     for (ii = 0; ii < aNumBuffers; ii++)
   4498     {
   4499 
   4500         int32 errcode = 0;
   4501         // get the address where the buf hdr ptr will be stored
   4502 
   4503         errcode = MemAllocate(ctrl_struct_ptr[ii], aMemPool, aAllocSize);
   4504         if ((errcode != OsclErrNone) || (ctrl_struct_ptr[ii] == NULL))
   4505         {
   4506             if (errcode == OsclErrNoResources)
   4507             {
   4508                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   4509                                 (0, "PVMFOMXEncNode-%s::FreeBuffersFromComponent ->allocate() failed for no mempool chunk available", iNodeTypeId));
   4510             }
   4511             else
   4512             {
   4513                 // General error
   4514                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   4515                                 (0, "PVMFOMXEncNode-%s::FreeBuffersFromComponent ->allocate() failed due to some general error", iNodeTypeId));
   4516 
   4517                 ReportErrorEvent(PVMFFailure);
   4518                 ChangeNodeState(EPVMFNodeError);
   4519             }
   4520 
   4521             return false;
   4522         }
   4523         // to maintain correct count
   4524         aMemPool->notifyfreechunkavailable((*this), (OsclAny*) aMemPool);
   4525 
   4526         if (aIsThisInputBuffer)
   4527         {
   4528 
   4529             iNumOutstandingInputBuffers++;
   4530             // get the buf hdr pointer
   4531             InputBufCtrlStruct *temp = (InputBufCtrlStruct *) ctrl_struct_ptr[ii];
   4532 
   4533             if(ipExternalInputBufferAllocatorInterface && ipFixedSizeBufferAlloc)
   4534             {
   4535                 ipFixedSizeBufferAlloc->deallocate((OsclAny*) temp->pBufHdr->pBuffer);
   4536             }
   4537             err = OMX_FreeBuffer(iOMXEncoder,
   4538                                  aPortIndex,
   4539                                  temp->pBufHdr);
   4540 
   4541         }
   4542         else
   4543         {
   4544             iNumOutstandingOutputBuffers++;
   4545             OutputBufCtrlStruct *temp = (OutputBufCtrlStruct *) ctrl_struct_ptr[ii];
   4546             err = OMX_FreeBuffer(iOMXEncoder,
   4547                                  aPortIndex,
   4548                                  temp->pBufHdr);
   4549 
   4550         }
   4551 
   4552         if (err != OMX_ErrorNone)
   4553         {
   4554             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   4555                             (0, "PVMFOMXEncNode-%s::FreeBuffersFromComponent() Problem freeing a buffer", iNodeTypeId));
   4556 
   4557             return false;
   4558         }
   4559 
   4560     }
   4561 
   4562     for (ii = 0; ii < aNumBuffers; ii++)
   4563     {
   4564         // after freeing the buffer hdr ptrs, return them
   4565         // to the mempool (which will itself then be deleted promptly)
   4566         aMemPool->deallocate((OsclAny*) ctrl_struct_ptr[ii]);
   4567     }
   4568 
   4569 
   4570     // mark buffers as freed (so as not to do it twice)
   4571     if (aIsThisInputBuffer)
   4572     {
   4573         oscl_free(in_ctrl_struct_ptr);
   4574         oscl_free(in_buff_hdr_ptr);
   4575 
   4576         in_ctrl_struct_ptr = NULL;
   4577         in_buff_hdr_ptr = NULL;
   4578         iInputBuffersFreed = true;
   4579 
   4580         if(ipExternalInputBufferAllocatorInterface)
   4581         {
   4582             ipExternalInputBufferAllocatorInterface->removeRef();
   4583             ipExternalInputBufferAllocatorInterface = NULL;
   4584         }
   4585     }
   4586     else
   4587     {
   4588         oscl_free(out_ctrl_struct_ptr);
   4589         oscl_free(out_buff_hdr_ptr);
   4590 
   4591         out_ctrl_struct_ptr = NULL;
   4592         out_buff_hdr_ptr = NULL;
   4593 
   4594         iOutputBuffersFreed = true;
   4595     }
   4596     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::FreeBuffersFromComponent() done", iNodeTypeId));
   4597     return true;
   4598 }
   4599 
   4600 
   4601 
   4602 /////////////////////////////////////////////////////////////////////////////
   4603 ////////////////////// CALLBACK PROCESSING FOR EVENT HANDLER
   4604 /////////////////////////////////////////////////////////////////////////////
   4605 OMX_ERRORTYPE PVMFOMXEncNode::EventHandlerProcessing(OMX_OUT OMX_HANDLETYPE aComponent,
   4606         OMX_OUT OMX_PTR aAppData,
   4607         OMX_OUT OMX_EVENTTYPE aEvent,
   4608         OMX_OUT OMX_U32 aData1,
   4609         OMX_OUT OMX_U32 aData2,
   4610         OMX_OUT OMX_PTR aEventData)
   4611 {
   4612     OSCL_UNUSED_ARG(aComponent);
   4613     OSCL_UNUSED_ARG(aAppData);
   4614     OSCL_UNUSED_ARG(aEventData);
   4615 
   4616     switch (aEvent)
   4617     {
   4618         case OMX_EventCmdComplete:
   4619         {
   4620 
   4621             switch (aData1)
   4622             {
   4623                 case OMX_CommandStateSet:
   4624                 {
   4625                     HandleComponentStateChange(aData2);
   4626                     break;
   4627                 }
   4628                 case OMX_CommandFlush:            //not supported
   4629                     // nothing to do here yet
   4630                     break;
   4631 
   4632                 case OMX_CommandPortDisable:
   4633                 {
   4634                     // if port disable command is done, we can re-allocate the buffers and re-enable the port
   4635 
   4636                     iProcessingState = EPVMFOMXEncNodeProcessingState_PortReEnable;
   4637                     iPortIndexForDynamicReconfig =  aData2;
   4638 
   4639                     RunIfNotReady();
   4640                     break;
   4641                 }
   4642                 case OMX_CommandPortEnable:
   4643                     // port enable command is done. Check if the other port also reported change.
   4644                     // If not, we can start data flow. Otherwise, must start dynamic reconfig procedure for
   4645                     // the other port as well.
   4646                 {
   4647                     if (iSecondPortReportedChange)
   4648                     {
   4649                         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   4650                                         (0, "PVMFOMXEncNode-%s::EventHandlerProcessing: OMX_CommandPortEnable - completed on port %d, dynamic reconfiguration needed on port %d", iNodeTypeId, aData2, iSecondPortToReconfig));
   4651 
   4652                         iProcessingState = EPVMFOMXEncNodeProcessingState_PortReconfig;
   4653                         iPortIndexForDynamicReconfig = iSecondPortToReconfig;
   4654                         iSecondPortReportedChange = false;
   4655                     }
   4656                     else
   4657                     {
   4658                         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   4659                                         (0, "PVMFOMXEncNode-%s::EventHandlerProcessing: OMX_CommandPortEnable - completed on port %d, resuming normal data flow", iNodeTypeId, aData2));
   4660                         iProcessingState = EPVMFOMXEncNodeProcessingState_ReadyToEncode;
   4661                         iDynamicReconfigInProgress = false;
   4662                     }
   4663                     RunIfNotReady();
   4664                     break;
   4665                 }
   4666 
   4667                 case OMX_CommandMarkBuffer:
   4668                     // nothing to do here yet;
   4669                     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   4670                                     (0, "PVMFOMXEncNode-%s::EventHandlerProcessing: OMX_CommandMarkBuffer - completed - no action taken", iNodeTypeId));
   4671 
   4672                     break;
   4673 
   4674                 default:
   4675                 {
   4676                     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   4677                                     (0, "PVMFOMXEncNode-%s::EventHandlerProcessing: Unsupported event", iNodeTypeId));
   4678                     break;
   4679                 }
   4680             }//end of switch (aData1)
   4681 
   4682             break;
   4683         }//end of case OMX_EventCmdComplete
   4684 
   4685         case OMX_EventError:
   4686         {
   4687             LOGE("Ln %d OMX_EventError nData1 %d nData2 %d", __LINE__, aData1, aData2);
   4688 
   4689             if (aData1 == (OMX_U32) OMX_ErrorStreamCorrupt)
   4690             {
   4691                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   4692                                 (0, "PVMFOMXEncNode-%s::EventHandlerProcessing: OMX_EventError - Bitstream corrupt error", iNodeTypeId));
   4693                 // Errors from corrupt bitstream are reported as info events
   4694                 ReportInfoEvent(PVMFInfoProcessingFailure, NULL);
   4695 
   4696             }
   4697             else if (aData1 == (OMX_U32) OMX_ErrorInvalidState)
   4698             {
   4699                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   4700                                 (0, "PVMFOMXEncNode-%s::EventHandlerProcessing: OMX_EventError - OMX_ErrorInvalidState", iNodeTypeId));
   4701                 HandleComponentStateChange(OMX_StateInvalid);
   4702             }
   4703             else
   4704             {
   4705                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   4706                                 (0, "PVMFOMXEncNode-%s::EventHandlerProcessing: OMX_EventError", iNodeTypeId));
   4707                 // for now, any error from the component will be reported as error
   4708                 ReportErrorEvent(PVMFErrProcessing, NULL, NULL);
   4709                 SetState(EPVMFNodeError);
   4710             }
   4711             break;
   4712 
   4713         }
   4714 
   4715         case OMX_EventBufferFlag:
   4716         {
   4717             // the component is reporting it encountered end of stream flag
   4718             // we'll send eos when we get the actual last buffer with marked eos
   4719 
   4720             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   4721                             (0, "PVMFOMXEncNode-%s::EventHandlerProcessing: OMX_EventBufferFlag (EOS) flag returned from OMX component", iNodeTypeId));
   4722 
   4723             RunIfNotReady();
   4724             break;
   4725         }//end of case OMX_EventBufferFlag
   4726 
   4727         case OMX_EventMark:
   4728         {
   4729 
   4730             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   4731                             (0, "PVMFOMXEncNode-%s::EventHandlerProcessing: OMX_EventMark returned from OMX component - no action taken", iNodeTypeId));
   4732 
   4733             RunIfNotReady();
   4734             break;
   4735         }//end of case OMX_EventMark
   4736 
   4737         case OMX_EventPortSettingsChanged:
   4738         {
   4739 
   4740             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   4741                             (0, "PVMFOMXEncNode-%s::EventHandlerProcessing: OMX_EventPortSettingsChanged returned from OMX component", iNodeTypeId));
   4742 
   4743             // first check if dynamic reconfiguration is already in progress,
   4744             // if so, wait until this is completed, and then initiate the 2nd reconfiguration
   4745             if (iDynamicReconfigInProgress)
   4746             {
   4747                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   4748                                 (0, "PVMFOMXEncNode-%s::EventHandlerProcessing: OMX_EventPortSettingsChanged returned for port %d, dynamic reconfig already in progress", iNodeTypeId, aData1));
   4749 
   4750                 iSecondPortToReconfig = aData1;
   4751                 iSecondPortReportedChange = true;
   4752             }
   4753             else
   4754             {
   4755                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   4756                                 (0, "PVMFOMXEncNode-%s::EventHandlerProcessing: OMX_EventPortSettingsChanged returned for port %d", iNodeTypeId, aData1));
   4757 
   4758                 iProcessingState = EPVMFOMXEncNodeProcessingState_PortReconfig;
   4759                 iPortIndexForDynamicReconfig = aData1;
   4760                 iDynamicReconfigInProgress = true;
   4761             }
   4762 
   4763             RunIfNotReady();
   4764             break;
   4765         }//end of case OMX_PortSettingsChanged
   4766 
   4767         case OMX_EventResourcesAcquired:        //not supported
   4768         {
   4769             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   4770                             (0, "PVMFOMXEncNode-%s::EventHandlerProcessing: OMX_EventResourcesAcquired returned from OMX component - no action taken", iNodeTypeId));
   4771 
   4772             RunIfNotReady();
   4773 
   4774             break;
   4775         }
   4776 
   4777         default:
   4778         {
   4779             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   4780                             (0, "PVMFOMXEncNode-%s::EventHandlerProcessing:  Unknown Event returned from OMX component - no action taken", iNodeTypeId));
   4781 
   4782             break;
   4783         }
   4784 
   4785     }//end of switch (eEvent)
   4786 
   4787 
   4788 
   4789     return OMX_ErrorNone;
   4790 }
   4791 
   4792 
   4793 
   4794 
   4795 /////////////////////////////////////////////////////////////////////////////
   4796 // This function handles the event of OMX component state change
   4797 /////////////////////////////////////////////////////////////////////////////
   4798 void PVMFOMXEncNode::HandleComponentStateChange(OMX_U32 encoder_state)
   4799 {
   4800     switch (encoder_state)
   4801     {
   4802         case OMX_StateIdle:
   4803         {
   4804             iCurrentEncoderState = OMX_StateIdle;
   4805 
   4806             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   4807                             (0, "PVMFOMXEncNode-%s::HandleComponentStateChange: OMX_StateIdle reached", iNodeTypeId));
   4808 
   4809             //  this state can be reached either going from OMX_Loaded->OMX_Idle (preparing)
   4810             //  or going from OMX_Executing->OMX_Idle (stopping)
   4811 
   4812 
   4813             if ((iCurrentCommand.size() > 0) &&
   4814                     (iCurrentCommand.front().iCmd == PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_PREPARE))
   4815             {
   4816                 iProcessingState = EPVMFOMXEncNodeProcessingState_ReadyToEncode;
   4817                 SetState(EPVMFNodePrepared);
   4818                 CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFSuccess);
   4819                 RunIfNotReady();
   4820             }
   4821             else if ((iCurrentCommand.size() > 0) &&
   4822                      (iCurrentCommand.front().iCmd == PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_STOP))
   4823             {
   4824                 // if we are stopped, we won't start until the node gets DoStart command.
   4825                 //  in this case, we are ready to start sending buffers
   4826                 if (iProcessingState == EPVMFOMXEncNodeProcessingState_Stopping)
   4827                     iProcessingState = EPVMFOMXEncNodeProcessingState_ReadyToEncode;
   4828                 // if the processing state was not stopping, leave the state as it was (continue port reconfiguration)
   4829                 SetState(EPVMFNodePrepared);
   4830                 CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFSuccess);
   4831 
   4832                 RunIfNotReady();
   4833             }
   4834             else if ((iCurrentCommand.size() > 0) &&
   4835                      (iCurrentCommand.front().iCmd == PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_FLUSH))
   4836             {
   4837                 // if there is a flush, similar to the case of stop, we won't start until the node gets
   4838                 // DoStart command. In this case, we'll be ready
   4839                 if (iProcessingState == EPVMFOMXEncNodeProcessingState_Stopping)
   4840                     iProcessingState = EPVMFOMXEncNodeProcessingState_ReadyToEncode;
   4841 
   4842 
   4843 
   4844                 //Flush is complete.  Go to prepared state.
   4845                 SetState(EPVMFNodePrepared);
   4846                 //resume port input (if possible) so the ports can be re-started.
   4847                 if (iInPort)
   4848                 {
   4849                     iInPort->ResumeInput();
   4850                 }
   4851                 if (iOutPort)
   4852                 {
   4853                     iOutPort->ResumeInput();
   4854                 }
   4855                 CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFSuccess);
   4856                 RunIfNotReady();
   4857 
   4858             }
   4859             else if ((iCurrentCommand.size() > 0) &&
   4860                      (iCurrentCommand.front().iCmd == PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_RESET))
   4861             {
   4862                 // State change to Idle was initiated due to Reset. First need to reach idle, and then loaded
   4863                 // Once Idle is reached, we need to initiate idle->loaded transition
   4864                 iStopInResetMsgSent = false;
   4865                 RunIfNotReady();
   4866             }
   4867             break;
   4868         }//end of case OMX_StateIdle
   4869 
   4870         case OMX_StateExecuting:
   4871         {
   4872             iCurrentEncoderState = OMX_StateExecuting;
   4873 
   4874             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   4875                             (0, "PVMFOMXEncNode-%s::HandleComponentStateChange: OMX_StateExecuting reached", iNodeTypeId));
   4876 
   4877             // this state can be reached going from OMX_Idle -> OMX_Executing (preparing)
   4878             //  or going from OMX_Pause -> OMX_Executing (coming from pause)
   4879             //  either way, this is a response to "DoStart" command
   4880 
   4881             if ((iCurrentCommand.size() > 0) &&
   4882                     (iCurrentCommand.front().iCmd == PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_START))
   4883             {
   4884                 SetState(EPVMFNodeStarted);
   4885                 CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFSuccess);
   4886 
   4887                 RunIfNotReady();
   4888             }
   4889 
   4890             break;
   4891         }//end of case OMX_StateExecuting
   4892 
   4893         case OMX_StatePause:
   4894         {
   4895             iCurrentEncoderState = OMX_StatePause;
   4896 
   4897             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   4898                             (0, "PVMFOMXEncNode-%s::HandleComponentStateChange: OMX_StatePause reached", iNodeTypeId));
   4899 
   4900 
   4901             //  This state can be reached going from OMX_Executing-> OMX_Pause
   4902             if ((iCurrentCommand.size() > 0) &&
   4903                     (iCurrentCommand.front().iCmd == PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_PAUSE))
   4904             {
   4905                 SetState(EPVMFNodePaused);
   4906                 CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFSuccess);
   4907                 RunIfNotReady();
   4908             }
   4909 
   4910             break;
   4911         }//end of case OMX_StatePause
   4912 
   4913         case OMX_StateLoaded:
   4914         {
   4915             iCurrentEncoderState = OMX_StateLoaded;
   4916 
   4917             //  this state can be reached only going from OMX_Idle ->OMX_Loaded (stopped to reset)
   4918             //
   4919 
   4920             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   4921                             (0, "PVMFOMXEncNode-%s::HandleComponentStateChange: OMX_StateLoaded reached", iNodeTypeId));
   4922             //Check if command's responce is pending
   4923             if ((iCurrentCommand.size() > 0) &&
   4924                     (iCurrentCommand.front().iCmd == PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_RESET))
   4925             {
   4926 
   4927                 // move this here
   4928                 if (iInPort)
   4929                 {
   4930                     OSCL_DELETE(((PVMFOMXEncPort*)iInPort));
   4931                     iInPort = NULL;
   4932                 }
   4933 
   4934                 if (iOutPort)
   4935                 {
   4936                     OSCL_DELETE(((PVMFOMXEncPort*)iOutPort));
   4937                     iOutPort = NULL;
   4938                 }
   4939 
   4940                 iDataIn.Unbind();
   4941 
   4942                 // Reset the metadata key list
   4943                 iAvailableMetadataKeys.clear();
   4944 
   4945 
   4946                 iProcessingState = EPVMFOMXEncNodeProcessingState_Idle;
   4947                 //logoff & go back to Created state.
   4948                 SetState(EPVMFNodeIdle);
   4949                 CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFSuccess);
   4950                 iResetInProgress = false;
   4951                 iResetMsgSent = false;
   4952             }
   4953 
   4954             break;
   4955         }//end of case OMX_StateLoaded
   4956 
   4957         case OMX_StateInvalid:
   4958         default:
   4959         {
   4960             iCurrentEncoderState = OMX_StateInvalid;
   4961 
   4962             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   4963                             (0, "PVMFOMXEncNode-%s::HandleComponentStateChange: OMX_StateInvalid reached", iNodeTypeId));
   4964             //Clearup encoder
   4965             DeleteOMXEncoder();
   4966 
   4967             if (iCurrentCommand.size() > 0)
   4968             {//can NOT be CANCEL or CANCEL_ALL. Just to cmd completion for the rest
   4969                 if (iCurrentCommand.front().iCmd == PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_RESET)
   4970                 {
   4971                     //delete all ports and notify observer.
   4972                     if (iInPort)
   4973                     {
   4974                         OSCL_DELETE(((PVMFOMXEncPort*)iInPort));
   4975                         iInPort = NULL;
   4976                     }
   4977 
   4978                     if (iOutPort)
   4979                     {
   4980                         OSCL_DELETE(((PVMFOMXEncPort*)iOutPort));
   4981                         iOutPort = NULL;
   4982                     }
   4983 
   4984                     iDataIn.Unbind();
   4985 
   4986                     // Reset the metadata key list
   4987                     iAvailableMetadataKeys.clear();
   4988 
   4989                     iEndOfDataReached = false;
   4990                     iIsEOSSentToComponent = false;
   4991                     iIsEOSReceivedFromComponent = false;
   4992 
   4993                     iProcessingState = EPVMFOMXEncNodeProcessingState_Idle;
   4994                     //logoff & go back to Created state.
   4995                     SetState(EPVMFNodeIdle);
   4996                     CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFSuccess);
   4997                 }
   4998                 else
   4999                 {
   5000                     SetState(EPVMFNodeError);
   5001                     CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFErrResource);
   5002                 }
   5003             }
   5004 
   5005             break;
   5006         }//end of case OMX_StateInvalid
   5007 
   5008     }//end of switch(encoder_state)
   5009 
   5010 }
   5011 
   5012 
   5013 
   5014 
   5015 
   5016 
   5017 /////////////////////////////////////////////////////////////////////////////
   5018 ////////////////////// CALLBACK PROCESSING FOR EMPTY BUFFER DONE - input buffer was consumed
   5019 /////////////////////////////////////////////////////////////////////////////
   5020 OMX_ERRORTYPE PVMFOMXEncNode::EmptyBufferDoneProcessing(OMX_OUT OMX_HANDLETYPE aComponent,
   5021         OMX_OUT OMX_PTR aAppData,
   5022         OMX_OUT OMX_BUFFERHEADERTYPE* aBuffer)
   5023 {
   5024 
   5025     OSCL_UNUSED_ARG(aComponent);
   5026     OSCL_UNUSED_ARG(aAppData);
   5027     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   5028                     (0, "PVMFOMXEncNode-%s::EmptyBufferDoneProcessing: In", iNodeTypeId));
   5029 
   5030     OSCL_ASSERT((void*) aComponent == (void*) iOMXEncoder); // component should match the component
   5031     OSCL_ASSERT(aAppData == (OMX_PTR)(this));       // AppData should represent this node ptr
   5032 
   5033     // first, get the buffer "context", i.e. pointer to application private data that contains the
   5034     // address of the mempool buffer (so that it can be released)
   5035     InputBufCtrlStruct *pContext = (InputBufCtrlStruct *)(aBuffer->pAppPrivate);
   5036 
   5037 
   5038 
   5039     // if a buffer is not empty, log a msg, but release anyway
   5040     if ((aBuffer->nFilledLen > 0) && (iDoNotSaveInputBuffersFlag == false))
   5041         // if dynamic port reconfig is in progress for input port, don't keep the buffer
   5042     {
   5043 
   5044         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   5045                         (0, "PVMFOMXEncNode-%s::EmptyBufferDoneProcessing: Input buffer returned non-empty with %d bytes still in it", iNodeTypeId, aBuffer->nFilledLen));
   5046 
   5047 
   5048     }
   5049 
   5050     iInputBufferToResendToComponent = NULL;
   5051 
   5052 
   5053     // input buffer is to be released,
   5054     // refcount needs to be decremented (possibly - the input msg associated with the buffer will be unbound)
   5055     // NOTE: in case of "moveable" input buffers (passed into component without copying), unbinding decrements a refcount which eventually results
   5056     //          in input message being released back to upstream mempool once all its fragments are returned
   5057     //      in case of input buffers passed into component by copying, unbinding has no effect
   5058     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   5059                     (0, "PVMFOMXEncNode-%s::EmptyBufferDoneProcessing: Release input buffer (with %d refcount remaining of input message)", iNodeTypeId, (pContext->pMediaData).get_count() - 1));
   5060 
   5061 
   5062     (pContext->pMediaData).Unbind();
   5063 
   5064 
   5065     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   5066                     (0, "PVMFOMXEncNode-%s::EmptyBufferDoneProcessing: Release input buffer %x back to mempool", iNodeTypeId, pContext));
   5067 
   5068     iInBufMemoryPool->deallocate((OsclAny *) pContext);
   5069 
   5070 
   5071     // the OMX spec says that no error is to be returned
   5072     return OMX_ErrorNone;
   5073 
   5074 }
   5075 
   5076 
   5077 
   5078 /////////////////////////////////////////////////////////////////////////////
   5079 ////////////////////// CALLBACK PROCESSING FOR FILL BUFFER DONE - output buffer is ready
   5080 /////////////////////////////////////////////////////////////////////////////
   5081 OMX_ERRORTYPE PVMFOMXEncNode::FillBufferDoneProcessing(OMX_OUT OMX_HANDLETYPE aComponent,
   5082         OMX_OUT OMX_PTR aAppData,
   5083         OMX_OUT OMX_BUFFERHEADERTYPE* aBuffer)
   5084 {
   5085 
   5086     OSCL_UNUSED_ARG(aComponent);
   5087     OSCL_UNUSED_ARG(aAppData);
   5088     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   5089                     (0, "PVMFOMXEncNode-%s::FillBufferDoneProcessing: In", iNodeTypeId));
   5090 
   5091     OSCL_ASSERT((void*) aComponent == (void*) iOMXEncoder); // component should match the component
   5092     OSCL_ASSERT(aAppData == (OMX_PTR)(this));       // AppData should represent this node ptr
   5093 
   5094     // first, get the buffer "context", i.e. pointer to application private data that contains the
   5095     // address of the mempool buffer (so that it can be released)
   5096     OsclAny *pContext = (OsclAny*) aBuffer->pAppPrivate;
   5097 
   5098 
   5099     // check for EOS flag
   5100     if ((aBuffer->nFlags & OMX_BUFFERFLAG_EOS))
   5101     {
   5102         // EOS received - enable sending EOS msg
   5103         iIsEOSReceivedFromComponent = true;
   5104 
   5105         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   5106                         (0, "PVMFOMXEncNode-%s::FillBufferDoneProcessing: Output buffer has EOS set", iNodeTypeId));
   5107 
   5108     }
   5109 
   5110     if (((iOutFormat == PVMF_MIME_H264_VIDEO_MP4) || (iOutFormat == PVMF_MIME_H264_VIDEO_RAW))
   5111             && (iOMXComponentUsesNALStartCodes))
   5112     {
   5113         // find size of first start code, since it can be either 3 or 4 bytes
   5114         uint8* pData = (uint8*)aBuffer->pBuffer + aBuffer->nOffset;
   5115         uint8* pTemp;
   5116         uint32 size = aBuffer->nFilledLen;
   5117         if (AVCAnnexBGetNALUnit(pData, &pTemp, (int32*)&size, true))
   5118         {
   5119             iFirstNALStartCodeSize = (uint32)pTemp - (uint32)pData;
   5120         }
   5121         else
   5122         {
   5123             iFirstNALStartCodeSize = 0;
   5124         }
   5125     }
   5126 
   5127     /* the case in which a buffer simply containing a start code is sent */
   5128     if (aBuffer->nFilledLen <= iFirstNALStartCodeSize && iOMXComponentUsesNALStartCodes)
   5129     {
   5130         aBuffer->nFilledLen = 0;
   5131     }
   5132 
   5133     // if a buffer is empty, or if it should not be sent downstream (say, due to state change)
   5134     // release the buffer back to the pool
   5135     if ((aBuffer->nFilledLen == 0) || (iDoNotSendOutputBuffersDownstreamFlag == true))
   5136     {
   5137         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   5138                         (0, "PVMFOMXEncNode-%s::FillBufferDoneProcessing: Release output buffer %x back to mempool - buffer empty or not to be sent downstream", iNodeTypeId, pContext));
   5139 
   5140         iOutBufMemoryPool->deallocate(pContext);
   5141 
   5142     }
   5143     else
   5144     {
   5145 
   5146         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   5147                         (0, "PVMFOMXEncNode-%s::FillBufferDoneProcessing: Output frame %d received", iNodeTypeId, iFrameCounter));
   5148 
   5149         iFrameCounter++;
   5150         // get pointer to actual buffer data
   5151         uint8 *pBufdata = ((uint8*) aBuffer->pBuffer);
   5152         // move the data pointer based on offset info
   5153         pBufdata += aBuffer->nOffset;
   5154 
   5155         uint32 bufLen = (uint32) aBuffer->nFilledLen;
   5156 
   5157         // in case of mp4 streaming and the very 1st buffer, save vol header separately
   5158         if ((iOutFormat == PVMF_MIME_M4V) && (iFrameCounter == 1))
   5159         {
   5160 
   5161             // save the first buffer since this is the VOL header
   5162             uint refCounterSize = oscl_mem_aligned_size(sizeof(OsclRefCounterDA));
   5163             OsclMemoryFragment volHeader;
   5164 
   5165             int vol_len = aBuffer->nFilledLen;
   5166             bool frameInVolHdr = CheckM4vVopStartCode(pBufdata, &vol_len);
   5167 
   5168             volHeader.ptr = NULL;
   5169             volHeader.len = vol_len;
   5170             uint8* memBuffer = (uint8*)iAlloc.allocate(refCounterSize + volHeader.len);
   5171             oscl_memset(memBuffer, 0, refCounterSize + volHeader.len);
   5172             OsclRefCounter* refCounter = OSCL_PLACEMENT_NEW(memBuffer, OsclRefCounterDA(memBuffer, (OsclDestructDealloc*) & iAlloc));
   5173             memBuffer += refCounterSize;
   5174             volHeader.ptr = (OsclAny*)memBuffer;
   5175 
   5176             // copy the vol header from OMX buffer
   5177             oscl_memcpy(volHeader.ptr, pBufdata, volHeader.len);
   5178 
   5179             // save in class variable
   5180             iVolHeader = OsclRefCounterMemFrag(volHeader, refCounter, volHeader.len);
   5181 
   5182             if (frameInVolHdr == false)
   5183             {
   5184                 // release the OMX buffer
   5185                 iOutBufMemoryPool->deallocate(pContext);
   5186                 return OMX_ErrorNone;
   5187             }
   5188             else  // there is a frame in this buffer, update the pointer and continue to process it.
   5189             {
   5190                 pBufdata += vol_len;
   5191                 bufLen -= vol_len;
   5192             }
   5193         }
   5194 
   5195         if (iFrameCounter == 1)
   5196         {
   5197             if ((iOutFormat == PVMF_MIME_ADTS)
   5198                     || (iOutFormat == PVMF_MIME_ADIF)
   5199                     || (iOutFormat == PVMF_MIME_MPEG4_AUDIO)
   5200                     || (iOutFormat == PVMF_MIME_WMA)
   5201                     || (iOutFormat == PVMF_MIME_WMV)
   5202                )
   5203             {
   5204 
   5205                 // save the first buffer since this is the config header and needs to be sent separately
   5206                 uint refCounterSize = oscl_mem_aligned_size(sizeof(OsclRefCounterDA));
   5207                 OsclMemoryFragment configHeader;
   5208                 configHeader.ptr = NULL;
   5209                 configHeader.len = aBuffer->nFilledLen;
   5210                 uint8* memBuffer = (uint8*)iAlloc.allocate(refCounterSize + configHeader.len);
   5211                 oscl_memset(memBuffer, 0, refCounterSize + configHeader.len);
   5212                 OsclRefCounter* refCounter = OSCL_PLACEMENT_NEW(memBuffer, OsclRefCounterDA(memBuffer, (OsclDestructDealloc*) & iAlloc));
   5213                 memBuffer += refCounterSize;
   5214                 configHeader.ptr = (OsclAny*)memBuffer;
   5215 
   5216                 // copy the vol header from OMX buffer
   5217                 oscl_memcpy(configHeader.ptr, pBufdata, configHeader.len);
   5218 
   5219                 // save in class variable
   5220                 iConfigHeader = OsclRefCounterMemFrag(configHeader, refCounter, configHeader.len);
   5221 
   5222                 // release the OMX buffer
   5223                 iOutBufMemoryPool->deallocate(pContext);
   5224                 return OMX_ErrorNone;
   5225             }
   5226         }
   5227 
   5228         // in case of avc mp4, need to save sps/pps sequences
   5229         if ((iOutFormat == PVMF_MIME_H264_VIDEO_MP4) && (!iSpsPpsSequenceOver))
   5230         {
   5231 
   5232             if (iOMXComponentUsesNALStartCodes)
   5233             {
   5234                 // remove the start code from these single NAL frames
   5235                 pBufdata += iFirstNALStartCodeSize;
   5236                 bufLen -= iFirstNALStartCodeSize;
   5237             }
   5238             // detect nal type
   5239             uint8 *bitstream = pBufdata;
   5240             int nal_type;
   5241 
   5242             // adjust the pointers in the iParamSet memfragment
   5243             uint8 *destptr = (uint8*) iParamSet.getMemFragPtr();
   5244             uint32 length = iParamSet.getMemFrag().len;
   5245             uint32 capacity = iParamSet.getCapacity();
   5246 
   5247             destptr += length;
   5248 
   5249 
   5250             nal_type = bitstream[0] & 0x1F;
   5251 
   5252             if (nal_type == 0x07) // SPS type NAL
   5253             {
   5254                 int32 nal_size = aBuffer->nFilledLen;
   5255                 AVCAnnexBGetNALUnit(aBuffer->pBuffer, &bitstream, (int32*)&nal_size, false);
   5256                 // can the SPS fit into the buffer
   5257                 if (aBuffer->nFilledLen <= (capacity - length))
   5258                 {
   5259                     iSPSs[iNumSPSs].ptr = destptr;
   5260                     iSPSs[iNumSPSs++].len = nal_size;
   5261 
   5262                     oscl_memcpy(destptr, pBufdata, nal_size); // copy SPS into iParamSet memfragment
   5263                     length += nal_size;
   5264                     iParamSet.getMemFrag().len = length; // update length
   5265                     destptr += nal_size;
   5266                     if (nal_size < aBuffer->nFilledLen) {
   5267                         LOGD("SPS and PPS are located within a single output buffer");
   5268                         uint8* pData = (uint8*)aBuffer->pBuffer + nal_size +iFirstNALStartCodeSize;
   5269                         uint32 size = aBuffer->nFilledLen -(nal_size +iFirstNALStartCodeSize);
   5270                         AVCAnnexBGetNALUnit(pData, &bitstream, (int32*)&size, false);
   5271                         nal_size = size;
   5272                         nal_type = bitstream[0] & 0x1F;
   5273                         if (nal_type == 0x08) // PPS type NAL
   5274                         {
   5275                             if (aBuffer->nFilledLen <= (capacity - length))
   5276                             {
   5277                                 iPPSs[iNumPPSs].ptr = destptr;
   5278                                 iPPSs[iNumPPSs++].len = nal_size;
   5279                                 oscl_memcpy(destptr, bitstream, nal_size); // copy PPS into iParamSet memfragment$
   5280                                 length += nal_size;
   5281                                 iParamSet.getMemFrag().len = length; // update length
   5282                             }
   5283                         }
   5284                     }
   5285                 }
   5286 
   5287                 // release the OMX buffer
   5288                 iOutBufMemoryPool->deallocate(pContext);
   5289                 return OMX_ErrorNone;
   5290             }
   5291             else if (nal_type == 0x08) // PPS type NAL
   5292             {
   5293                 LOGD("SPS and PPS are located in separate output buffers");
   5294                 // can the PPS fit into the buffer?
   5295                 if (aBuffer->nFilledLen <= (capacity - length))
   5296                 {
   5297 
   5298                     iPPSs[iNumPPSs].ptr = destptr;
   5299                     iPPSs[iNumPPSs++].len = aBuffer->nFilledLen;
   5300 
   5301                     oscl_memcpy(destptr, pBufdata, aBuffer->nFilledLen); // copy PPS into iParamSet memfragment
   5302                     length += aBuffer->nFilledLen;
   5303                     iParamSet.getMemFrag().len = length; // update length
   5304 
   5305 
   5306                 }
   5307 
   5308                 // release the OMX buffer
   5309                 iOutBufMemoryPool->deallocate(pContext);
   5310                 return OMX_ErrorNone;
   5311             }
   5312             else
   5313             {
   5314                 if (iOMXComponentUsesNALStartCodes)
   5315                 {
   5316                     // bring start code back since it's not a SPS or PPS
   5317                     pBufdata -= iFirstNALStartCodeSize;
   5318                     bufLen += iFirstNALStartCodeSize;
   5319                 }
   5320 
   5321                 // this is neither SPS nor PPS
   5322                 // stop recording SPS/PPS
   5323                 iSpsPpsSequenceOver = true;
   5324                 iFirstNAL = true; // set indicator of first NAL
   5325                 // send out SPS/PPS recorded so far
   5326                 if (((PVMFOMXEncPort*)iOutPort))
   5327                 {
   5328                     ((PVMFOMXEncPort*)iOutPort)->SendSPS_PPS(iSPSs, iNumSPSs, iPPSs, iNumPPSs);
   5329                 }
   5330             }
   5331 
   5332         }
   5333 
   5334         if (iOMXComponentUsesFullAVCFrames && iOutFormat == PVMF_MIME_H264_VIDEO_MP4)
   5335         {
   5336             // do not parse fo PVMF_MIME_H264_VIDEO_RAW, since this data is just written raw, and knowing
   5337             // the NAL boundaries isn't necessary
   5338 
   5339             if (!ParseFullAVCFramesIntoNALs(aBuffer))
   5340             {
   5341                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   5342                                 (0, "PVMFOMXEncNode-%s::FillBufferDoneProcessing: Problem parsing NALs in buffer %x of size %d - releasing the buffer", iNodeTypeId, pBufdata, aBuffer->nFilledLen));
   5343 
   5344                 iOutBufMemoryPool->deallocate(pContext);
   5345             }
   5346         }
   5347 
   5348         // adjust ptr to data to expose the NAL sync word if necessary
   5349         if ((iOutFormat == PVMF_MIME_H264_VIDEO_RAW) &&
   5350                 (iOMXComponentSupportsExternalOutputBufferAlloc) &&
   5351                 (!iOMXComponentUsesFullAVCFrames) &&
   5352                 (!iOMXComponentUsesNALStartCodes) &&
   5353                 ((iFirstNAL == true) || (iEndOfNALFlagPrevious != 0))
   5354            )
   5355         {
   5356             pBufdata -= 4;
   5357             bufLen += 4;
   5358         }
   5359 
   5360         // otherwise, queue output buffer
   5361         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   5362                         (0, "PVMFOMXEncNode-%s::FillBufferDoneProcessing: Wrapping buffer %x of size %d", iNodeTypeId, pBufdata, aBuffer->nFilledLen));
   5363         // wrap the buffer into the MediaDataImpl wrapper, and queue it for sending downstream
   5364         // wrapping will create a refcounter. When refcounter goes to 0 i.e. when media data
   5365         // is released in downstream components, the custom deallocator will automatically release the buffer back to the
   5366         //  mempool. To do that, the deallocator needs to have info about Context
   5367         // NOTE: we had to wait until now to wrap the buffer data because we only know
   5368         //          now where the actual data is located (based on buffer offset)
   5369         OsclSharedPtr<PVMFMediaDataImpl> MediaDataCurr = WrapOutputBuffer(pBufdata, bufLen, pContext);
   5370 
   5371         // if you can't get the MediaDataCurr, release the buffer back to the pool
   5372         if (MediaDataCurr.GetRep() == NULL)
   5373         {
   5374             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   5375                             (0, "PVMFOMXEncNode-%s::FillBufferDoneProcessing: Problem wrapping buffer %x of size %d - releasing the buffer", iNodeTypeId, pBufdata, aBuffer->nFilledLen));
   5376 
   5377             iOutBufMemoryPool->deallocate(pContext);
   5378         }
   5379         else
   5380         {
   5381             OsclSharedPtr<PVMFMediaDataImpl> MediaDataOut;
   5382 
   5383             //DV - NOTE:
   5384             //In case of AVC, OMX_EndOfFrameFlag is used to mark the end of NAL
   5385             //                End of frame is determined by comparing timestamps
   5386             //              As a consequence, there is a lag of one buffer
   5387             //              i.e. we send/queue the previous buffer and keep the current one so that
   5388             //              When the next buffer arrives, we can compare timestamps etc.
   5389 
   5390             // In case of MP4, OMX_EndOFFrameFlag is used to mark end of frame and there is no lag
   5391 
   5392             if ((iOutFormat == PVMF_MIME_H264_VIDEO_MP4) || (iOutFormat == PVMF_MIME_H264_VIDEO_RAW))
   5393             {
   5394 
   5395                 MediaDataOut = iPreviousMediaData; // send out previous media data
   5396 
   5397                 // copy data to be attached with outgoing media data from previous buffer
   5398                 iTimeStampOut = iTimeStampPrevious;
   5399                 iKeyFrameFlagOut = iKeyFrameFlagPrevious;
   5400                 iEndOfNALFlagOut = iEndOfNALFlagPrevious;
   5401                 // figure out if we need to set end of frame based on TS
   5402                 if (aBuffer->nTimeStamp != iTimeStampPrevious)
   5403                     iEndOfFrameFlagOut = 1;
   5404                 else
   5405                     iEndOfFrameFlagOut = 0;
   5406                 iBufferLenOut = iBufferLenPrevious;
   5407 
   5408                 // now read the info for the current data
   5409                 iPreviousMediaData = MediaDataCurr;
   5410                 // record timestamp, flags etc.
   5411                 iTimeStampPrevious = aBuffer->nTimeStamp;
   5412                 // check for Key Frame
   5413                 iKeyFrameFlagPrevious = (aBuffer->nFlags & OMX_BUFFERFLAG_SYNCFRAME);
   5414                 // for avc, ENDOFFRAMEFLAG is used to delimit NALs
   5415                 iEndOfNALFlagPrevious = (aBuffer->nFlags & OMX_BUFFERFLAG_ENDOFFRAME);
   5416                 iBufferLenPrevious = bufLen;
   5417 
   5418 
   5419             }
   5420             else // MP4 case
   5421             {
   5422 
   5423                 MediaDataOut = MediaDataCurr;
   5424                 // record timestamp, flags etc.
   5425                 iTimeStampOut = aBuffer->nTimeStamp;
   5426 
   5427                 // check for Key Frame
   5428                 iKeyFrameFlagOut = (aBuffer->nFlags & OMX_BUFFERFLAG_SYNCFRAME);
   5429                 iEndOfNALFlagOut = 0; // set this to 0 for mp4
   5430                 //check for END OF FRAME FLAG
   5431                 iEndOfFrameFlagOut = (aBuffer->nFlags & OMX_BUFFERFLAG_ENDOFFRAME);
   5432                 iBufferLenOut = aBuffer->nFilledLen;
   5433 
   5434 
   5435             }
   5436             // if there's a problem queuing output buffer, MediaDataCurr will expire at end of scope and
   5437             // release buffer back to the pool, (this should not be the case)
   5438 
   5439             // queue only if not the first NAL
   5440             if (!iFirstNAL)
   5441             {
   5442                 if (QueueOutputBuffer(MediaDataOut, iBufferLenOut))
   5443                 {
   5444                     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   5445                                     (0, "PVMFOMXEncNode-%s::FillBufferDoneProcessing: Buffer %x of size %d queued - reschedule the node to send out", iNodeTypeId, pBufdata, aBuffer->nFilledLen));
   5446 
   5447                     // if queing went OK,
   5448                     // re-schedule the node so that outgoing queue can be emptied (unless the outgoing port is busy)
   5449                     if ((iOutPort) && !(iOutPort->IsConnectedPortBusy()))
   5450                         RunIfNotReady();
   5451                 }
   5452                 else
   5453                 {
   5454                     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   5455                                     (0, "PVMFOMXEncNode-%s::FillBufferDoneProcessing: Problem queing buffer %x of size %d - releasing the buffer", iNodeTypeId, pBufdata, aBuffer->nFilledLen));
   5456                 }
   5457             }
   5458             else
   5459             {
   5460                 iFirstNAL = false;
   5461             }
   5462 
   5463             // if EOS and AVC (with a lag), queue also the last buffer
   5464             if ((aBuffer->nFlags & OMX_BUFFERFLAG_EOS) &&
   5465                     ((iOutFormat == PVMF_MIME_H264_VIDEO_MP4) || (iOutFormat == PVMF_MIME_H264_VIDEO_RAW))
   5466                )
   5467             {
   5468 
   5469                 MediaDataOut = iPreviousMediaData; // send out previous media data
   5470 
   5471                 // copy data to be attached with outgoing media data from previous buffer
   5472                 iTimeStampOut = iTimeStampPrevious;
   5473                 iKeyFrameFlagOut = iKeyFrameFlagPrevious;
   5474                 iEndOfNALFlagOut =   1;
   5475                 iEndOfFrameFlagOut = 1;
   5476 
   5477                 iBufferLenOut = iBufferLenPrevious;
   5478 
   5479                 if (QueueOutputBuffer(MediaDataOut, iBufferLenOut))
   5480                 {
   5481                     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   5482                                     (0, "PVMFOMXEncNode-%s::FillBufferDoneProcessing: Buffer %x of size %d queued - reschedule the node to send out", iNodeTypeId, pBufdata, aBuffer->nFilledLen));
   5483 
   5484                     // if queing went OK,
   5485                     // re-schedule the node so that outgoing queue can be emptied (unless the outgoing port is busy)
   5486                     if ((iOutPort) && !(iOutPort->IsConnectedPortBusy()))
   5487                         RunIfNotReady();
   5488                 }
   5489                 else
   5490                 {
   5491                     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   5492                                     (0, "PVMFOMXEncNode-%s::FillBufferDoneProcessing: Problem queing buffer %x of size %d - releasing the buffer", iNodeTypeId, pBufdata, aBuffer->nFilledLen));
   5493                 }
   5494 
   5495             }
   5496         }
   5497 
   5498     }
   5499     // the OMX spec says that no error is to be returned
   5500     return OMX_ErrorNone;
   5501 
   5502 }
   5503 ////////////////////////////////////////////////////////////////////////////////////////////////
   5504 ///////////////////////////// Put output buffer in outgoing queue //////////////////////////////
   5505 ////////////////////////////////////////////////////////////////////////////////////////////////
   5506 bool PVMFOMXEncNode::QueueOutputBuffer(OsclSharedPtr<PVMFMediaDataImpl> &mediadataimplout, uint32 aDataLen)
   5507 {
   5508 
   5509     bool status = true;
   5510     PVMFSharedMediaDataPtr mediaDataOut;
   5511     int32 leavecode = 0;
   5512 
   5513     // NOTE: ASSUMPTION IS THAT OUTGOING QUEUE IS BIG ENOUGH TO QUEUE ALL THE OUTPUT BUFFERS
   5514     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   5515                     (0, "PVMFOMXEncNode-%s::QueueOutputFrame: In", iNodeTypeId));
   5516 
   5517     // Check if the port is still connected
   5518     if (iOutPort == NULL)
   5519     {
   5520         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
   5521                         (0, "PVMFOMXEncNode-%s::QueueOutputFrame() OutgoingQueue Out Port is disconnected"));
   5522         return false;
   5523     }
   5524 
   5525     // First check if we can put outgoing msg. into the queue
   5526     if (iOutPort->IsOutgoingQueueBusy())
   5527     {
   5528         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
   5529                         (0, "PVMFOMXEncNode-%s::QueueOutputFrame() OutgoingQueue is busy", iNodeTypeId));
   5530         return false;
   5531     }
   5532 
   5533     OSCL_TRY(leavecode,
   5534              mediaDataOut = PVMFMediaData::createMediaData(mediadataimplout, iMediaDataMemPool););
   5535     if (leavecode == 0)
   5536     {
   5537 
   5538         uint32 marker_bits = mediaDataOut->getMarkerInfo();
   5539 
   5540         if (iEndOfFrameFlagOut != 0)
   5541         {
   5542             marker_bits |= PVMF_MEDIA_DATA_MARKER_INFO_M_BIT;
   5543         }
   5544 
   5545         if (iKeyFrameFlagOut != 0)
   5546         {
   5547             marker_bits |= PVMF_MEDIA_DATA_MARKER_INFO_RANDOM_ACCESS_POINT_BIT;
   5548         }
   5549 
   5550         if (iEndOfNALFlagOut != 0)
   5551         {
   5552             marker_bits |= PVMF_MEDIA_DATA_MARKER_INFO_END_OF_NAL_BIT;
   5553         }
   5554 
   5555         // attach marker bit
   5556         mediaDataOut->setMarkerInfo(marker_bits);
   5557 
   5558 
   5559         // Update the filled length of the fragment
   5560         mediaDataOut->setMediaFragFilledLen(0, aDataLen);
   5561 
   5562         // Set timestamp
   5563         // first convert OMX_TICKS into output timescale
   5564         uint32 output_timestamp = ConvertOMXTicksIntoTimestamp(iTimeStampOut);
   5565 
   5566         mediaDataOut->setTimestamp(output_timestamp);
   5567 
   5568         // Set Streamid
   5569         mediaDataOut->setStreamID(iStreamID);
   5570 
   5571         // Set sequence number
   5572         mediaDataOut->setSeqNum(iSeqNum++);
   5573 
   5574         PVLOGGER_LOGMSG(PVLOGMSG_INST_REL, iDataPathLogger, PVLOGMSG_INFO, (0, ":PVMFOMXEncNode-%s::QueueOutputFrame(): - SeqNum=%d, Ticks=%l TS=%d", iNodeTypeId, iSeqNum, iTimeStampOut, output_timestamp));
   5575 
   5576 
   5577         // Check if Fsi needs to be sent (VOL header)
   5578         if (sendYuvFsi)
   5579         {
   5580             if (iOutFormat == PVMF_MIME_M4V)
   5581             {
   5582                 mediaDataOut->setFormatSpecificInfo(iVolHeader);
   5583 
   5584             }
   5585             else if ((iOutFormat == PVMF_MIME_ADTS)
   5586                      || (iOutFormat == PVMF_MIME_ADIF)
   5587                      || (iOutFormat == PVMF_MIME_MPEG4_AUDIO)
   5588                      || (iOutFormat == PVMF_MIME_WMA)
   5589                      || (iOutFormat == PVMF_MIME_WMV))
   5590             {
   5591 
   5592                 mediaDataOut->setFormatSpecificInfo(iConfigHeader);
   5593 
   5594             }
   5595 
   5596             sendYuvFsi = false;
   5597         }
   5598 
   5599         // Send frame to downstream node
   5600         PVMFSharedMediaMsgPtr mediaMsgOut;
   5601         convertToPVMFMediaMsg(mediaMsgOut, mediaDataOut);
   5602 
   5603         if (iOutPort && (iOutPort->QueueOutgoingMsg(mediaMsgOut) == PVMFSuccess))
   5604         {
   5605             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO,
   5606                             (0, "PVMFOMXEncNode-%s::QueueOutputFrame(): Queued frame OK ", iNodeTypeId));
   5607 
   5608         }
   5609         else
   5610         {
   5611             // we should not get here because we always check for whether queue is busy or not
   5612             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   5613                             (0, "PVMFOMXEncNode-%s::QueueOutputFrame(): Send frame failed", iNodeTypeId));
   5614             return false;
   5615         }
   5616 
   5617 
   5618 
   5619 
   5620     }//end of if (leavecode==0)
   5621     else
   5622     {
   5623         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   5624                         (0, "PVMFOMXEncNode-%s::QueueOutputFrame() call PVMFMediaData::createMediaData is failed", iNodeTypeId));
   5625         return false;
   5626     }
   5627 
   5628     return status;
   5629 
   5630 }
   5631 
   5632 //////////////////////////////////////////////////////////////////////////////////////////////
   5633 ///////////////////////////// Attach a MediaDataImpl wrapper (refcount, deallocator etc.)
   5634 /////////////////////////////// to the output buffer /////////////////////////////////////////
   5635 OsclSharedPtr<PVMFMediaDataImpl> PVMFOMXEncNode::WrapOutputBuffer(uint8 *pData, uint32 aDataLen, OsclAny *pContext)
   5636 {
   5637     // wrap output buffer into a mediadataimpl
   5638     uint32 aligned_cleanup_size = oscl_mem_aligned_size(sizeof(PVOMXEncBufferSharedPtrWrapperCombinedCleanupDA));
   5639     uint32 aligned_refcnt_size = oscl_mem_aligned_size(sizeof(OsclRefCounterDA));
   5640     uint8 *my_ptr = (uint8*) oscl_malloc(aligned_cleanup_size + aligned_refcnt_size);
   5641 
   5642     if (my_ptr == NULL)
   5643     {
   5644         OsclSharedPtr<PVMFMediaDataImpl> null_buff(NULL, NULL);
   5645         return null_buff;
   5646     }
   5647 
   5648     // create a deallocator and pass the buffer_allocator to it as well as pointer to data that needs to be returned to the mempool
   5649     PVOMXEncBufferSharedPtrWrapperCombinedCleanupDA *cleanup_ptr =
   5650         OSCL_PLACEMENT_NEW(my_ptr + aligned_refcnt_size, PVOMXEncBufferSharedPtrWrapperCombinedCleanupDA(iOutBufMemoryPool, pContext));
   5651 
   5652     // create the ref counter after the cleanup object (refcount is set to 1 at creation)
   5653     OsclRefCounterDA *my_refcnt;
   5654     PVMFMediaDataImpl* media_data_ptr;
   5655 
   5656     if (iOMXComponentUsesFullAVCFrames && iNumNALs > 0)
   5657     {
   5658         uint32 ii;
   5659         media_data_ptr = OSCL_NEW(PVMFMediaFragGroup<OsclMemAllocator>, (iNumNALs));
   5660         my_refcnt = OSCL_PLACEMENT_NEW(my_ptr, OsclRefCounterDA(media_data_ptr, cleanup_ptr));
   5661 
   5662         // loop through and assign a create a media fragment for each NAL
   5663         for (ii = 0; ii < iNumNALs; ii++)
   5664         {
   5665             OsclMemoryFragment memFrag;
   5666 
   5667             if (iOMXComponentUsesNALStartCodes)
   5668             {
   5669                 // need to get NAL ptr from stored array, since start codes can be 3 or 4 bytes,
   5670                 // and the only way to know is by parsing the buffer (which we should have done by now and stored in the array)
   5671                 memFrag.ptr = iNALPtrArray[ii];
   5672             }
   5673             else
   5674             {
   5675                 memFrag.ptr = pData;
   5676                 pData += iNALSizeArray[ii];
   5677             }
   5678 
   5679             memFrag.len = iNALSizeArray[ii];
   5680 
   5681             OsclRefCounterMemFrag refCountMemFragOut(memFrag, my_refcnt, memFrag.len);
   5682             media_data_ptr->appendMediaFragment(refCountMemFragOut);
   5683         }
   5684 
   5685         oscl_memset((void *) iNALSizeArray, 0, sizeof(uint32) * iNumNALs);
   5686         iNumNALs = 0;
   5687     }
   5688     else
   5689     {
   5690         media_data_ptr = OSCL_NEW(PVMFMediaFragGroup<OsclMemAllocator>, (1));
   5691         my_refcnt = OSCL_PLACEMENT_NEW(my_ptr, OsclRefCounterDA(media_data_ptr, cleanup_ptr));
   5692 
   5693         OsclMemoryFragment memFrag;
   5694 
   5695         if (iOMXComponentUsesNALStartCodes && (iOutFormat != PVMF_MIME_H264_VIDEO_RAW))
   5696         {
   5697             // skip start code
   5698             pData += iFirstNALStartCodeSize;
   5699             aDataLen -= iFirstNALStartCodeSize;
   5700         }
   5701 
   5702         memFrag.ptr = pData;
   5703         memFrag.len = aDataLen;
   5704 
   5705         OsclRefCounterMemFrag refCountMemFragOut(memFrag, my_refcnt, memFrag.len);
   5706         media_data_ptr->appendMediaFragment(refCountMemFragOut);
   5707     }
   5708 
   5709     OsclSharedPtr<PVMFMediaDataImpl> MediaDataImplOut(media_data_ptr, my_refcnt);
   5710 
   5711     return MediaDataImplOut;
   5712 }
   5713 //////////////////////////////////////////////////////////////////////////////
   5714 bool PVMFOMXEncNode::SendBeginOfMediaStreamCommand()
   5715 {
   5716     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   5717                     (0, "PVMFOMXEncNode-%s::SendBeginOfMediaStreamCommand() In", iNodeTypeId));
   5718 
   5719     PVMFSharedMediaCmdPtr sharedMediaCmdPtr = PVMFMediaCmd::createMediaCmd();
   5720     // Set the formatID, timestamp, sequenceNumber and streamID for the media message
   5721     sharedMediaCmdPtr->setFormatID(PVMF_MEDIA_CMD_BOS_FORMAT_ID);
   5722     sharedMediaCmdPtr->setTimestamp(iBOSTimestamp);
   5723     //reset the sequence number
   5724     uint32 seqNum = 0;
   5725     sharedMediaCmdPtr->setSeqNum(seqNum);
   5726     sharedMediaCmdPtr->setStreamID(iStreamID);
   5727 
   5728     PVMFSharedMediaMsgPtr mediaMsgOut;
   5729     convertToPVMFMediaCmdMsg(mediaMsgOut, sharedMediaCmdPtr);
   5730     if (iOutPort->QueueOutgoingMsg(mediaMsgOut) != PVMFSuccess)
   5731     {
   5732         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   5733                         (0, "PVMFOMXEncNode-%s::SendBeginOfMediaStreamCommand() Outgoing queue busy", iNodeTypeId));
   5734         return false;
   5735     }
   5736 
   5737     iSendBOS = false;
   5738 
   5739     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   5740                     (0, "PVMFOMXEncNode-%s::SendBeginOfMediaStreamCommand() BOS Sent StreamID %d", iNodeTypeId, iStreamID));
   5741     return true;
   5742 }
   5743 ////////////////////////////////////
   5744 bool PVMFOMXEncNode::SendEndOfTrackCommand(void)
   5745 {
   5746     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   5747                     (0, "PVMFOMXEncNode-%s::SendEndOfTrackCommand() In", iNodeTypeId));
   5748 
   5749     PVMFSharedMediaCmdPtr sharedMediaCmdPtr = PVMFMediaCmd::createMediaCmd();
   5750 
   5751     sharedMediaCmdPtr->setFormatID(PVMF_MEDIA_CMD_EOS_FORMAT_ID);
   5752 
   5753     // Set the timestamp
   5754     sharedMediaCmdPtr->setTimestamp(iEndOfDataTimestamp);
   5755 
   5756     // Set Streamid
   5757     sharedMediaCmdPtr->setStreamID(iStreamID);
   5758 
   5759     // Set the sequence number
   5760     sharedMediaCmdPtr->setSeqNum(iSeqNum++);
   5761 
   5762     PVMFSharedMediaMsgPtr mediaMsgOut;
   5763     convertToPVMFMediaCmdMsg(mediaMsgOut, sharedMediaCmdPtr);
   5764     if (iOutPort->QueueOutgoingMsg(mediaMsgOut) != PVMFSuccess)
   5765     {
   5766         // this should not happen because we check for queue busy before calling this function
   5767         return false;
   5768     }
   5769 
   5770     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   5771                     (0, "PVMFOMXEncNode-%s::SendEndOfTrackCommand() Out", iNodeTypeId));
   5772     return true;
   5773 }
   5774 
   5775 /////////////////////////////////////////////////////////////////////////////
   5776 //The various command handlers call this routine when a command is complete.
   5777 /////////////////////////////////////////////////////////////////////////////
   5778 void PVMFOMXEncNode::CommandComplete(PVMFOMXEncNodeCmdQ& aCmdQ, PVMFOMXEncNodeCommand& aCmd, PVMFStatus aStatus, OsclAny* aEventData)
   5779 {
   5780     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::CommandComplete Id %d Cmd %d Status %d Context %d Data %d", iNodeTypeId
   5781                     , aCmd.iId, aCmd.iCmd, aStatus, aCmd.iContext, aEventData));
   5782 
   5783     //create response
   5784     PVMFCmdResp resp(aCmd.iId, aCmd.iContext, aStatus, aEventData);
   5785     PVMFSessionId session = aCmd.iSession;
   5786 
   5787     //Erase the command from the queue.
   5788     aCmdQ.Erase(&aCmd);
   5789 
   5790     //Report completion to the session observer.
   5791     ReportCmdCompleteEvent(session, resp);
   5792 }
   5793 
   5794 /////////////////////////////////////////////////////////////////////////////
   5795 void PVMFOMXEncNode::DoInit(PVMFOMXEncNodeCommand& aCmd)
   5796 {
   5797     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::DoInit() In", iNodeTypeId));
   5798     switch (iInterfaceState)
   5799     {
   5800         case EPVMFNodeIdle:
   5801         {
   5802             SetState(EPVMFNodeInitialized);
   5803             CommandComplete(iInputCommands, aCmd, PVMFSuccess);
   5804             break;
   5805         }
   5806 
   5807         default:
   5808             CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
   5809             break;
   5810     }
   5811 }
   5812 
   5813 /////////////////////////////////////////////////////////////////////////////
   5814 void PVMFOMXEncNode::DoPrepare(PVMFOMXEncNodeCommand& aCmd)
   5815 {
   5816     OMX_ERRORTYPE err = OMX_ErrorNone;
   5817     OMX_STRING Role = NULL;
   5818 
   5819     switch (iInterfaceState)
   5820     {
   5821         case EPVMFNodeInitialized:
   5822         {
   5823             if (NULL == iInPort)
   5824             {
   5825                 CommandComplete(iInputCommands, aCmd, PVMFFailure);
   5826             }
   5827 
   5828 
   5829             // by now the encode parameters have been set
   5830 
   5831             if (iOutFormat == PVMF_MIME_H2631998 ||
   5832                     iOutFormat == PVMF_MIME_H2632000)
   5833             {
   5834                 Role = (OMX_STRING)"video_encoder.h263";
   5835                 iNodeTypeId = LOG_ID_VIDEO_H263;
   5836             }
   5837             else if (iOutFormat == PVMF_MIME_M4V)
   5838             {
   5839                 Role = (OMX_STRING)"video_encoder.mpeg4";
   5840                 iNodeTypeId = LOG_ID_VIDEO_M4V;
   5841             }
   5842             else if (iOutFormat == PVMF_MIME_H264_VIDEO_RAW ||
   5843                      iOutFormat == PVMF_MIME_H264_VIDEO_MP4)
   5844             {
   5845                 Role = (OMX_STRING)"video_encoder.avc";
   5846                 iNodeTypeId = LOG_ID_VIDEO_AVC;
   5847                 iFirstNAL = true; // set this flag to prevent node from queueing the first
   5848                 // buffer
   5849             }
   5850             else if ((iOutFormat == PVMF_MIME_AMR_IETF) ||
   5851                      (iOutFormat == PVMF_MIME_AMR_IF2))
   5852             {
   5853                 Role = (OMX_STRING)"audio_encoder.amrnb";
   5854                 iNodeTypeId = LOG_ID_AUDIO_AMRNB;
   5855             }
   5856             else if (iOutFormat == PVMF_MIME_AMRWB_IETF)
   5857             {
   5858                 Role = (OMX_STRING)"audio_encoder.amrwb";
   5859                 iNodeTypeId = LOG_ID_AUDIO_AMRWB;
   5860             }
   5861             else if (iOutFormat == PVMF_MIME_ADTS ||
   5862                      iOutFormat == PVMF_MIME_ADIF ||
   5863                      iOutFormat == PVMF_MIME_MPEG4_AUDIO)
   5864             {
   5865                 Role = (OMX_STRING)"audio_encoder.aac";
   5866                 iNodeTypeId = LOG_ID_AUDIO_AAC;
   5867             }
   5868             else
   5869             {
   5870                 // Illegal codec specified.
   5871                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::DoPrepare() Input port format other then codec type", iNodeTypeId));
   5872                 CommandComplete(iInputCommands, aCmd, PVMFErrArgument);
   5873                 return;
   5874             }
   5875 
   5876 
   5877             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_DEBUG,
   5878                             (0, "PVMFOMXEncNode-%s::Initializing OMX component and encoder for role %s", iNodeTypeId, Role));
   5879 
   5880             /* Set callback structure */
   5881             iCallbacks.EventHandler    = CallbackEventHandlerEnc; //event_handler;
   5882             iCallbacks.EmptyBufferDone = CallbackEmptyBufferDoneEnc; //empty_buffer_done;
   5883             iCallbacks.FillBufferDone  = CallbackFillBufferDoneEnc; //fill_buffer_done;
   5884 
   5885 
   5886             // determine components which can fit the role
   5887             // then, create the component. If multiple components fit the role,
   5888             // the first one registered will be selected. If that one fails to
   5889             // be created, the second one in the list is selected etc.
   5890             OMX_U32 num_comps = 0;
   5891             OMX_STRING *CompOfRole;
   5892             OMX_S8 CompName[PV_OMX_MAX_COMPONENT_NAME_LENGTH];
   5893             // call once to find out the number of components that can fit the role
   5894             OMX_MasterGetComponentsOfRole(Role, &num_comps, NULL);
   5895             uint32 ii;
   5896 
   5897             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
   5898                             (0, "PVMFOMXEncNode-%s::DoPrepare(): There are %d components of role %s ", iNodeTypeId, num_comps, Role));
   5899 
   5900             if (num_comps > 0)
   5901             {
   5902                 CompOfRole = (OMX_STRING *)oscl_malloc(num_comps * sizeof(OMX_STRING));
   5903 
   5904                 for (ii = 0; ii < num_comps; ii++)
   5905                     CompOfRole[ii] = (OMX_STRING) oscl_malloc(PV_OMX_MAX_COMPONENT_NAME_LENGTH * sizeof(OMX_U8));
   5906 
   5907                 // call 2nd time to get the component names
   5908                 OMX_MasterGetComponentsOfRole(Role, &num_comps, (OMX_U8 **)CompOfRole);
   5909 
   5910                 for (ii = 0; ii < num_comps; ii++)
   5911                 {
   5912                     // try to create component
   5913                     err = OMX_MasterGetHandle(&iOMXEncoder, (OMX_STRING) CompOfRole[ii], (OMX_PTR) this, (OMX_CALLBACKTYPE *) & iCallbacks);
   5914 
   5915                     if ((err == OMX_ErrorNone) && (iOMXEncoder != NULL))
   5916                     {
   5917                         oscl_strncpy((OMX_STRING)CompName, (OMX_STRING) CompOfRole[ii], PV_OMX_MAX_COMPONENT_NAME_LENGTH);
   5918 
   5919                         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
   5920                                         (0, "PVMFOMXEncNode-%s::DoPrepare(): Got Component %s handle ", iNodeTypeId, CompOfRole[ii]));
   5921                         LOGE("PVMFOMXEncNode-%s::DoPrepare(): Got Component %s handle ", iNodeTypeId, CompOfRole[ii]);
   5922 
   5923                         if ((CheckComponentForMultRoles((OMX_STRING)CompName, (OMX_STRING)CompOfRole[ii])) &&
   5924                             (CheckComponentCapabilities(&iOutFormat)))
   5925                         {
   5926                             // Found a component and it passed all tests.   Break out of the loop
   5927                             break;
   5928                         }
   5929                     }
   5930 
   5931                     // Component failed negotiations
   5932                     if (iOMXEncoder != NULL)
   5933                     {
   5934                         OMX_MasterFreeHandle(iOMXEncoder);
   5935                         iOMXEncoder = NULL;
   5936                     }
   5937                 }
   5938 
   5939                 // whether successful or not, need to free CompOfRoles
   5940                 for (ii = 0; ii < num_comps; ii++)
   5941                 {
   5942                     oscl_free(CompOfRole[ii]);
   5943                     CompOfRole[ii] = NULL;
   5944                 }
   5945 
   5946                 oscl_free(CompOfRole);
   5947                 // check if there was a problem
   5948                 if ((err != OMX_ErrorNone) || (iOMXEncoder == NULL))
   5949                 {
   5950                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   5951                                     (0, "PVMFOMXEncNode-%s::Can't get handle for encoder!", iNodeTypeId));
   5952                     iOMXEncoder = NULL;
   5953                     CommandComplete(iInputCommands, aCmd, PVMFErrResource);
   5954                     return;
   5955                 }
   5956             }
   5957             else
   5958             {
   5959                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   5960                                 (0, "PVMFOMXEncNode-%s::No component can handle role %s !", iNodeTypeId, Role));
   5961                 iOMXEncoder = NULL;
   5962                 CommandComplete(iInputCommands, aCmd, PVMFErrResource);
   5963                 return;
   5964             }
   5965 
   5966             if (!iOMXEncoder)
   5967             {
   5968                 CommandComplete(iInputCommands, aCmd, PVMFErrNoResources);
   5969                 return;
   5970             }
   5971 
   5972             // create active objects to handle callbacks in case of multithreaded implementation
   5973 
   5974             // NOTE: CREATE THE THREADSAFE CALLBACK AOs REGARDLESS OF WHETHER MULTITHREADED COMPONENT OR NOT
   5975             //      If it is not multithreaded, we won't use them
   5976             //      The Flag iIsComponentMultiThreaded decides which mechanism is used for callbacks.
   5977             //      This flag is set by looking at component capabilities (or to true by default)
   5978 
   5979             if (iThreadSafeHandlerEventHandler)
   5980             {
   5981                 OSCL_DELETE(iThreadSafeHandlerEventHandler);
   5982                 iThreadSafeHandlerEventHandler = NULL;
   5983             }
   5984             // substitute default parameters: observer(this node),queuedepth(3),nameAO for logging
   5985             // Get the priority of the encoder node, and set the threadsafe callback AO priority to 1 higher
   5986 
   5987             iThreadSafeHandlerEventHandler = OSCL_NEW(EventHandlerThreadSafeCallbackAOEnc, (this, 10, "EventHandlerAO", Priority() + 2));
   5988 
   5989             if (iThreadSafeHandlerEmptyBufferDone)
   5990             {
   5991                 OSCL_DELETE(iThreadSafeHandlerEmptyBufferDone);
   5992                 iThreadSafeHandlerEmptyBufferDone = NULL;
   5993             }
   5994             // use queue depth of iNumInputBuffers to prevent deadlock
   5995             iThreadSafeHandlerEmptyBufferDone = OSCL_NEW(EmptyBufferDoneThreadSafeCallbackAOEnc, (this, iNumInputBuffers, "EmptyBufferDoneAO", Priority() + 1));
   5996 
   5997             if (iThreadSafeHandlerFillBufferDone)
   5998             {
   5999                 OSCL_DELETE(iThreadSafeHandlerFillBufferDone);
   6000                 iThreadSafeHandlerFillBufferDone = NULL;
   6001             }
   6002             // use queue depth of iNumOutputBuffers to prevent deadlock
   6003             iThreadSafeHandlerFillBufferDone = OSCL_NEW(FillBufferDoneThreadSafeCallbackAOEnc, (this, iNumOutputBuffers, "FillBufferDoneAO", Priority() + 1));
   6004 
   6005             if ((iThreadSafeHandlerEventHandler == NULL) ||
   6006                     (iThreadSafeHandlerEmptyBufferDone == NULL) ||
   6007                     (iThreadSafeHandlerFillBufferDone == NULL)
   6008                )
   6009             {
   6010                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   6011                                 (0, "PVMFOMXEncNode-%s::Can't get threadsafe callbacks for encoder!", iNodeTypeId));
   6012                 iOMXEncoder = NULL;
   6013             }
   6014 
   6015 
   6016             // Init Encoder
   6017             iCurrentEncoderState = OMX_StateLoaded;
   6018 
   6019             /* Change state to OMX_StateIdle from OMX_StateLoaded. */
   6020             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
   6021                             (0, "PVMFOMXEncNode-%s::DoPrepare(): Changing Component state Loaded -> Idle ", iNodeTypeId));
   6022 
   6023             err = OMX_SendCommand(iOMXEncoder, OMX_CommandStateSet, OMX_StateIdle, NULL);
   6024             if (err != OMX_ErrorNone)
   6025             {
   6026                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   6027                                 (0, "PVMFOMXEncNode-%s::DoPrepare() Can't send StateSet command!", iNodeTypeId));
   6028 
   6029                 CommandComplete(iInputCommands, aCmd, PVMFErrNoResources);
   6030                 return;
   6031             }
   6032 
   6033 
   6034             /* Allocate input buffers */
   6035             if (!CreateInputMemPool(iNumInputBuffers))
   6036             {
   6037                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   6038                                 (0, "PVMFOMXEncNode-%s::DoPrepare() Can't allocate mempool for input buffers!", iNodeTypeId));
   6039 
   6040                 CommandComplete(iInputCommands, aCmd, PVMFErrNoResources);
   6041                 return;
   6042             }
   6043 
   6044             if (in_ctrl_struct_ptr)
   6045             {
   6046                 oscl_free(in_ctrl_struct_ptr);
   6047                 in_ctrl_struct_ptr = NULL;
   6048             }
   6049             if (in_buff_hdr_ptr)
   6050             {
   6051                 oscl_free(in_buff_hdr_ptr);
   6052                 in_buff_hdr_ptr = NULL;
   6053             }
   6054 
   6055             in_ctrl_struct_ptr = (OsclAny **) oscl_malloc(iNumInputBuffers * sizeof(OsclAny *));
   6056 
   6057             if (in_ctrl_struct_ptr == NULL)
   6058             {
   6059                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   6060                                 (0, "PVMFOMXEncNode-%s::DoPreapare in_ctrl_struct_ptr == NULL", iNodeTypeId));
   6061 
   6062                 CommandComplete(iInputCommands, aCmd, PVMFErrNoResources);
   6063                 return ;
   6064             }
   6065 
   6066             in_buff_hdr_ptr = (OsclAny **) oscl_malloc(iNumInputBuffers * sizeof(OsclAny *));
   6067 
   6068             if (in_buff_hdr_ptr == NULL)
   6069             {
   6070                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   6071                                 (0, "PVMFOMXEncNode-%s::DoPreapare in_buff_hdr_ptr == NULL", iNodeTypeId));
   6072 
   6073                 CommandComplete(iInputCommands, aCmd, PVMFErrNoResources);
   6074                 return ;
   6075             }
   6076 
   6077 
   6078             if (!ProvideBuffersToComponent(iInBufMemoryPool, // allocator
   6079                                            iInputAllocSize,  // size to allocate from pool (hdr only or hdr+ buffer)
   6080                                            iNumInputBuffers, // number of buffers
   6081                                            iOMXComponentInputBufferSize, // actual buffer size
   6082                                            iInputPortIndex, // port idx
   6083                                            iOMXComponentSupportsExternalInputBufferAlloc, // can component use OMX_UseBuffer
   6084                                            true // this is input
   6085                                           ))
   6086             {
   6087                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   6088                                 (0, "PVMFOMXEncNode-%s::DoPrepare() Component can't use input buffers!", iNodeTypeId));
   6089 
   6090                 CommandComplete(iInputCommands, aCmd, PVMFErrNoResources);
   6091                 return;
   6092             }
   6093 
   6094 
   6095             /* Allocate output buffers */
   6096             if (!CreateOutMemPool(iNumOutputBuffers))
   6097             {
   6098                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   6099                                 (0, "PVMFOMXEncNode-%s::DoPrepare() Can't allocate mempool for output buffers!", iNodeTypeId));
   6100 
   6101                 CommandComplete(iInputCommands, aCmd, PVMFErrNoResources);
   6102                 return;
   6103             }
   6104 
   6105             if (out_ctrl_struct_ptr)
   6106             {
   6107                 oscl_free(out_ctrl_struct_ptr);
   6108                 out_ctrl_struct_ptr = NULL;
   6109             }
   6110             if (out_buff_hdr_ptr)
   6111             {
   6112                 oscl_free(out_buff_hdr_ptr);
   6113                 out_buff_hdr_ptr = NULL;
   6114             }
   6115 
   6116             out_ctrl_struct_ptr = (OsclAny **) oscl_malloc(iNumOutputBuffers * sizeof(OsclAny *));
   6117 
   6118             if (out_ctrl_struct_ptr == NULL)
   6119             {
   6120                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   6121                                 (0, "PVMFOMXEncNode-%s::DoPreapare out_ctrl_struct_ptr == NULL", iNodeTypeId));
   6122 
   6123                 CommandComplete(iInputCommands, aCmd, PVMFErrNoResources);
   6124                 return ;
   6125             }
   6126 
   6127             out_buff_hdr_ptr = (OsclAny **) oscl_malloc(iNumOutputBuffers * sizeof(OsclAny *));
   6128 
   6129             if (out_buff_hdr_ptr == NULL)
   6130             {
   6131                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   6132                                 (0, "PVMFOMXEncNode-%s::DoPreapare out_buff_hdr_ptr == NULL", iNodeTypeId));
   6133 
   6134                 CommandComplete(iInputCommands, aCmd, PVMFErrNoResources);
   6135                 return ;
   6136             }
   6137 
   6138 
   6139             if (!ProvideBuffersToComponent(iOutBufMemoryPool, // allocator
   6140                                            iOutputAllocSize,     // size to allocate from pool (hdr only or hdr+ buffer)
   6141                                            iNumOutputBuffers, // number of buffers
   6142                                            iOMXComponentOutputBufferSize, // actual buffer size
   6143                                            iOutputPortIndex, // port idx
   6144                                            iOMXComponentSupportsExternalOutputBufferAlloc, // can component use OMX_UseBuffer
   6145                                            false // this is not input
   6146                                           ))
   6147             {
   6148                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   6149                                 (0, "PVMFOMXEncNode-%s::DoPrepare() Component can't use output buffers!", iNodeTypeId));
   6150 
   6151                 CommandComplete(iInputCommands, aCmd, PVMFErrNoResources);
   6152                 return;
   6153             }
   6154 
   6155 
   6156             //this command is asynchronous.  move the command from
   6157             //the input command queue to the current command, where
   6158             //it will remain until it completes. We have to wait for
   6159             // OMX component state transition to complete
   6160 
   6161             int32 err;
   6162             OSCL_TRY(err, iCurrentCommand.StoreL(aCmd););
   6163             if (err != OsclErrNone)
   6164             {
   6165                 CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
   6166                 return;
   6167             }
   6168             iInputCommands.Erase(&aCmd);
   6169 
   6170         }
   6171         break;
   6172         case EPVMFNodePrepared:
   6173             CommandComplete(iInputCommands, aCmd, PVMFSuccess);
   6174             break;
   6175         default:
   6176             CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
   6177             break;
   6178     }
   6179 
   6180 }
   6181 
   6182 /////////////////////////////////////////////////////////////////////////////
   6183 void PVMFOMXEncNode::DoStart(PVMFOMXEncNodeCommand& aCmd)
   6184 {
   6185     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::DoStart() In", iNodeTypeId));
   6186 
   6187     iDiagnosticsLogged = false;
   6188 
   6189     PVMFStatus status = PVMFSuccess;
   6190 
   6191     OMX_ERRORTYPE  err;
   6192     OMX_STATETYPE sState;
   6193 
   6194 #ifdef _TEST_AE_ERROR_HANDLING
   6195     if (FAIL_NODE_CMD_START == iErrorNodeCmd)
   6196     {
   6197         iInterfaceState = EPVMFNodeError;
   6198     }
   6199 #endif
   6200 
   6201 
   6202 
   6203     switch (iInterfaceState)
   6204     {
   6205         case EPVMFNodePrepared:
   6206         case EPVMFNodePaused:
   6207         {
   6208             //Get state of OpenMAX encoder
   6209             err = OMX_GetState(iOMXEncoder, &sState);
   6210             if (err != OMX_ErrorNone)
   6211             {
   6212                 //Error condition report
   6213                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   6214                                 (0, "PVMFOMXEncNode-%s::DoStart(): Can't get State of encoder!", iNodeTypeId));
   6215 
   6216                 sState = OMX_StateInvalid;
   6217             }
   6218 #ifdef _TEST_AE_ERROR_HANDLING
   6219             if (iErrorHandlingInit)
   6220             {
   6221                 //some random state ,we want Init to fail
   6222 
   6223                 sState = OMX_StateInvalid;
   6224             }
   6225 #endif
   6226             if ((sState == OMX_StateIdle) || (sState == OMX_StatePause))
   6227             {
   6228                 /* Change state to OMX_StateExecuting form OMX_StateIdle. */
   6229                 // init the flag
   6230                 iDoNotSendOutputBuffersDownstreamFlag = false; // or if output was not being sent downstream due to state changes
   6231                 // re-anable sending output
   6232 
   6233                 iDoNotSaveInputBuffersFlag = false;
   6234 
   6235 
   6236                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   6237                                 (0, "PVMFOMXEncNode-%s::DoStart() Changing Component state Idle->Executing", iNodeTypeId));
   6238 
   6239                 err = OMX_SendCommand(iOMXEncoder, OMX_CommandStateSet, OMX_StateExecuting, NULL);
   6240                 if (err != OMX_ErrorNone)
   6241                 {
   6242                     //Error condition report
   6243                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   6244                                     (0, "PVMFOMXEncNode-%s::DoStart(): Can't send StateSet command to encoder!", iNodeTypeId));
   6245 
   6246                     status = PVMFErrInvalidState;
   6247                 }
   6248 
   6249             }
   6250             else
   6251             {
   6252                 //Error condition report
   6253                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   6254                                 (0, "PVMFOMXEncNode-%s::DoStart(): Encoder is not in the Idle or Pause state!", iNodeTypeId));
   6255 
   6256                 status = PVMFErrInvalidState;
   6257             }
   6258 
   6259 
   6260         }
   6261         break;
   6262 
   6263         default:
   6264             status = PVMFErrInvalidState;
   6265             break;
   6266     }
   6267 
   6268     if (status == PVMFErrInvalidState)
   6269     {
   6270         CommandComplete(iInputCommands, aCmd, status);
   6271     }
   6272     else
   6273     {
   6274         //this command is asynchronous.  move the command from
   6275         //the input command queue to the current command, where
   6276         //it will remain until it completes.
   6277         int32 err;
   6278         OSCL_TRY(err, iCurrentCommand.StoreL(aCmd););
   6279         if (err != OsclErrNone)
   6280         {
   6281             CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
   6282         }
   6283         iInputCommands.Erase(&aCmd);
   6284     }
   6285 }
   6286 
   6287 /////////////////////////////////////////////////////////////////////////////
   6288 void PVMFOMXEncNode::DoStop(PVMFOMXEncNodeCommand& aCmd)
   6289 {
   6290     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::DoStop() In", iNodeTypeId));
   6291 
   6292     LogDiagnostics();
   6293 
   6294     OMX_ERRORTYPE  err;
   6295     OMX_STATETYPE sState;
   6296 #ifdef _TEST_AE_ERROR_HANDLING
   6297     if (FAIL_NODE_CMD_STOP == iErrorNodeCmd)
   6298     {
   6299         iInterfaceState = EPVMFNodeError;
   6300     }
   6301 #endif
   6302     switch (iInterfaceState)
   6303     {
   6304         case EPVMFNodeStarted:
   6305         case EPVMFNodePaused:
   6306         case EPVMFNodePrepared:
   6307             // Stop data source
   6308             // This will also prevent execution of HandleProcessingState
   6309 
   6310             iDataIn.Unbind();
   6311             iPreviousMediaData.Unbind();
   6312             if ((iOutFormat == PVMF_MIME_H264_VIDEO_MP4) || (iOutFormat == PVMF_MIME_H264_VIDEO_RAW))
   6313             {
   6314                 // prepare for next start (if it comes)
   6315                 iFirstNAL = true;
   6316             }
   6317             // Clear queued messages in ports
   6318             if (iInPort)
   6319             {
   6320                 iInPort->ClearMsgQueues();
   6321             }
   6322 
   6323             if (iOutPort)
   6324             {
   6325                 iOutPort->ClearMsgQueues();
   6326             }
   6327 
   6328             // Clear the data flags
   6329 
   6330             iEndOfDataReached = false;
   6331             iIsEOSSentToComponent = false;
   6332             iIsEOSReceivedFromComponent = false;
   6333 
   6334 
   6335             iDoNotSendOutputBuffersDownstreamFlag = true; // stop sending output buffers downstream
   6336             iDoNotSaveInputBuffersFlag = true;
   6337 
   6338 
   6339             //Get state of OpenMAX encoder
   6340             err = OMX_GetState(iOMXEncoder, &sState);
   6341             if (err != OMX_ErrorNone)
   6342             {
   6343                 //Error condition report
   6344                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   6345                                 (0, "PVMFOMXEncNode-%s::DoStop(): Can't get State of encoder!", iNodeTypeId));
   6346 
   6347                 sState = OMX_StateInvalid;
   6348             }
   6349 
   6350             if ((sState == OMX_StateExecuting) || (sState == OMX_StatePause))
   6351             {
   6352                 /* Change state to OMX_StateIdle from OMX_StateExecuting or OMX_StatePause. */
   6353 
   6354                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   6355                                 (0, "PVMFOMXEncNode-%s::DoStop() Changing Component State Executing->Idle or Pause->Idle", iNodeTypeId));
   6356 
   6357                 err = OMX_SendCommand(iOMXEncoder, OMX_CommandStateSet, OMX_StateIdle, NULL);
   6358                 if (err != OMX_ErrorNone)
   6359                 {
   6360                     //Error condition report
   6361                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   6362                                     (0, "PVMFOMXEncNode-%s::DoStop(): Can't send StateSet command to encoder!", iNodeTypeId));
   6363 
   6364                     CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
   6365                     break;
   6366                 }
   6367 
   6368                 // prevent the node from sending more buffers etc.
   6369                 // if port reconfiguration is in process, let the state remain one of the port config states
   6370                 //  if there is a start command, we can do it seemlessly (by continuing the port reconfig)
   6371                 if (iProcessingState == EPVMFOMXEncNodeProcessingState_ReadyToEncode)
   6372                     iProcessingState = EPVMFOMXEncNodeProcessingState_Stopping;
   6373 
   6374             }
   6375             else
   6376             {
   6377                 //Error condition report
   6378                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   6379                                 (0, "PVMFOMXEncNode-%s::DoStop(): Encoder is not in the Executing or Pause state!", iNodeTypeId));
   6380 
   6381                 CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
   6382                 break;
   6383             }
   6384 
   6385             //this command is asynchronous.  move the command from
   6386             //the input command queue to the current command, where
   6387             //it will remain until it completes.
   6388             int32 err;
   6389             OSCL_TRY(err, iCurrentCommand.StoreL(aCmd););
   6390             if (err != OsclErrNone)
   6391             {
   6392                 CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
   6393                 return;
   6394             }
   6395             iInputCommands.Erase(&aCmd);
   6396 
   6397             break;
   6398 
   6399         default:
   6400             CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
   6401             break;
   6402     }
   6403 }
   6404 
   6405 /////////////////////////////////////////////////////////////////////////////
   6406 void PVMFOMXEncNode::DoFlush(PVMFOMXEncNodeCommand& aCmd)
   6407 {
   6408 #ifdef _TEST_AE_ERROR_HANDLING
   6409     if (FAIL_NODE_CMD_FLUSH == iErrorNodeCmd)
   6410     {
   6411         iInterfaceState = EPVMFNodeError;
   6412     }
   6413 #endif
   6414     switch (iInterfaceState)
   6415     {
   6416         case EPVMFNodeStarted:
   6417         case EPVMFNodePaused:
   6418             //the flush is asynchronous.  move the command from
   6419             //the input command queue to the current command, where
   6420             //it will remain until the flush completes.
   6421             int32 err;
   6422             OSCL_TRY(err, iCurrentCommand.StoreL(aCmd););
   6423             if (err != OsclErrNone)
   6424             {
   6425                 CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
   6426                 return;
   6427             }
   6428             iInputCommands.Erase(&aCmd);
   6429 
   6430             //Notify all ports to suspend their input
   6431             if (iInPort)
   6432             {
   6433                 iInPort->SuspendInput();
   6434             }
   6435             RunIfNotReady();
   6436             if (iOutPort)
   6437             {
   6438                 iOutPort->SuspendInput();
   6439             }
   6440             // Stop data source
   6441 
   6442             // DV: Sending "OMX_CommandFlush" to the encoder;
   6443             // Not used because PV Flush command expects data to be processed before getting out
   6444             iDoNotSendOutputBuffersDownstreamFlag = true; // collect output buffers
   6445 
   6446             break;
   6447 
   6448         default:
   6449             CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
   6450             break;
   6451     }
   6452 }
   6453 
   6454 /////////////////////////////////////////////////////////////////////////////
   6455 void PVMFOMXEncNode::DoPause(PVMFOMXEncNodeCommand& aCmd)
   6456 {
   6457     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::DoPause() In", iNodeTypeId));
   6458 
   6459     OMX_ERRORTYPE  err;
   6460     OMX_STATETYPE sState;
   6461 #ifdef _TEST_AE_ERROR_HANDLING
   6462     if (FAIL_NODE_CMD_PAUSE == iErrorNodeCmd)
   6463     {
   6464         iInterfaceState = EPVMFNodeError;
   6465     }
   6466 #endif
   6467 
   6468     switch (iInterfaceState)
   6469     {
   6470         case EPVMFNodeStarted:
   6471 
   6472 
   6473             //Get state of OpenMAX encoder
   6474             err = OMX_GetState(iOMXEncoder, &sState);
   6475             if (err != OMX_ErrorNone)
   6476             {
   6477                 //Error condition report
   6478                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   6479                                 (0, "PVMFOMXEncNode-%s::DoPause(): Can't get State of encoder!", iNodeTypeId));
   6480 
   6481                 sState = OMX_StateInvalid;
   6482             }
   6483 
   6484             if (sState == OMX_StateExecuting)
   6485             {
   6486                 /* Change state to OMX_StatePause from OMX_StateExecuting. */
   6487                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   6488                                 (0, "PVMFOMXEncNode-%s::DoPause() Changing Component State Executing->Idle", iNodeTypeId));
   6489 
   6490                 err = OMX_SendCommand(iOMXEncoder, OMX_CommandStateSet, OMX_StatePause, NULL);
   6491                 if (err != OMX_ErrorNone)
   6492                 {
   6493                     //Error condition report
   6494                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   6495                                     (0, "PVMFOMXEncNode-%s::DoPause(): Can't send StateSet command to encoder!", iNodeTypeId));
   6496 
   6497                     CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
   6498                     break;
   6499                 }
   6500 
   6501             }
   6502             else
   6503             {
   6504                 //Error condition report
   6505                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   6506                                 (0, "PVMFOMXEncNode-%s::DoPause(): Encoder is not in the Executing state!", iNodeTypeId));
   6507                 CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
   6508                 break;
   6509             }
   6510 
   6511             //this command is asynchronous.  move the command from
   6512             //the input command queue to the current command, where
   6513             //it will remain until it completes.
   6514             int32 err;
   6515             OSCL_TRY(err, iCurrentCommand.StoreL(aCmd););
   6516             if (err != OsclErrNone)
   6517             {
   6518                 CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
   6519                 return;
   6520             }
   6521             iInputCommands.Erase(&aCmd);
   6522 
   6523             break;
   6524         default:
   6525             CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
   6526             break;
   6527     }
   6528 }
   6529 
   6530 /////////////////////////////////////////////////////////////////////////////
   6531 void PVMFOMXEncNode::DoReset(PVMFOMXEncNodeCommand& aCmd)
   6532 {
   6533 
   6534     OMX_ERRORTYPE  err;
   6535     OMX_STATETYPE sState;
   6536 
   6537     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   6538                     (0, "PVMFOMXEncNode-%s::DoReset() In", iNodeTypeId));
   6539 
   6540     LogDiagnostics();
   6541 
   6542     switch (iInterfaceState)
   6543     {
   6544         case EPVMFNodeIdle:
   6545         case EPVMFNodeInitialized:
   6546         case EPVMFNodePrepared:
   6547         case EPVMFNodeStarted:
   6548         case EPVMFNodePaused:
   6549         case EPVMFNodeError:
   6550         {
   6551             //Check if encoder is initilized
   6552             if (iOMXEncoder != NULL)
   6553             {
   6554                 //Get state of OpenMAX encoder
   6555                 err = OMX_GetState(iOMXEncoder, &sState);
   6556                 if (err != OMX_ErrorNone)
   6557                 {
   6558                     sState = OMX_StateInvalid;
   6559                 }
   6560 
   6561                 if (sState == OMX_StateLoaded)
   6562                 {
   6563                     // this is a value obtained by synchronous call to component. Either the component was
   6564                     // already in this state without node issuing any commands,
   6565                     // or perhaps we started the Reset, but the callback notification has not yet arrived.
   6566                     if (iResetInProgress)
   6567                     {
   6568                         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   6569                                         (0, "PVMFOMXEncNode-%s::DoReset() OMX comp is in loaded state. Wait for official callback to change variables etc.", iNodeTypeId));
   6570                         return;
   6571                     }
   6572                 }
   6573                 else if (sState == OMX_StateIdle)
   6574                 {
   6575                     //this command is asynchronous.  move the command from
   6576                     //the input command queue to the current command, where
   6577                     //it will remain until it is completed.
   6578                     if (!iResetInProgress)
   6579                     {
   6580                         int32 err;
   6581                         OSCL_TRY(err, iCurrentCommand.StoreL(aCmd););
   6582                         if (err != OsclErrNone)
   6583                         {
   6584                             CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
   6585                             return;
   6586                         }
   6587                         iInputCommands.Erase(&aCmd);
   6588 
   6589                         iResetInProgress = true;
   6590                     }
   6591 
   6592                     // if buffers aren't all back (due to timing issues with different callback AOs
   6593                     //      state change can be reported before all buffers are returned)
   6594                     if (iNumOutstandingInputBuffers > 0 || iNumOutstandingOutputBuffers > 0)
   6595                     {
   6596                         LOGE("PVMFOMXEncNode-%s::DoReset() Waiting for %d input and-or %d output buffers", iNodeTypeId, iNumOutstandingInputBuffers, iNumOutstandingOutputBuffers);
   6597 
   6598                         return;
   6599                     }
   6600 
   6601                     if (!iResetMsgSent)
   6602                     {
   6603                         // We can come here only if all buffers are already back
   6604                         // Don't repeat any of this twice.
   6605                         /* Change state to OMX_StateLoaded form OMX_StateIdle. */
   6606                         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   6607                                         (0, "PVMFOMXEncNode-%s::DoReset() Changing Component State Idle->Loaded", iNodeTypeId));
   6608 
   6609                         err = OMX_SendCommand(iOMXEncoder, OMX_CommandStateSet, OMX_StateLoaded, NULL);
   6610                         if (err != OMX_ErrorNone)
   6611                         {
   6612                             //Error condition report
   6613                             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   6614                                             (0, "PVMFOMXEncNode-%s::DoReset(): Can't send StateSet command to encoder!", iNodeTypeId));
   6615                         }
   6616 
   6617                         iResetMsgSent = true;
   6618 
   6619 
   6620                         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   6621                                         (0, "PVMFOMXEncNode-%s::DoReset() freeing output buffers", iNodeTypeId));
   6622 
   6623                         if (false == iOutputBuffersFreed)
   6624                         {
   6625                             if (!FreeBuffersFromComponent(iOutBufMemoryPool, // allocator
   6626                                                           iOutputAllocSize,  // size to allocate from pool (hdr only or hdr+ buffer)
   6627                                                           iNumOutputBuffers, // number of buffers
   6628                                                           iOutputPortIndex, // port idx
   6629                                                           false // this is not input
   6630                                                          ))
   6631                             {
   6632                                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   6633                                                 (0, "PVMFOMXEncNode-%s::DoReset() Cannot free output buffers ", iNodeTypeId));
   6634 
   6635                                 if (iResetInProgress)
   6636                                 {
   6637                                     iResetInProgress = false;
   6638                                     if ((iCurrentCommand.size() > 0) &&
   6639                                             (iCurrentCommand.front().iCmd == PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_RESET)
   6640                                        )
   6641                                     {
   6642                                         CommandComplete(iCurrentCommand, iCurrentCommand.front() , PVMFErrResource);
   6643                                     }
   6644                                 }
   6645 
   6646                             }
   6647 
   6648                         }
   6649                         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   6650                                         (0, "PVMFOMXEncNode-%s::DoReset() freeing input buffers ", iNodeTypeId));
   6651                         if (false == iInputBuffersFreed)
   6652                         {
   6653                             if (!FreeBuffersFromComponent(iInBufMemoryPool, // allocator
   6654                                                           iInputAllocSize,   // size to allocate from pool (hdr only or hdr+ buffer)
   6655                                                           iNumInputBuffers, // number of buffers
   6656                                                           iInputPortIndex, // port idx
   6657                                                           true // this is input
   6658                                                          ))
   6659                             {
   6660                                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   6661                                                 (0, "PVMFOMXEncNode-%s::DoReset() Cannot free input buffers ", iNodeTypeId));
   6662 
   6663                                 if (iResetInProgress)
   6664                                 {
   6665                                     iResetInProgress = false;
   6666                                     if ((iCurrentCommand.size() > 0) &&
   6667                                             (iCurrentCommand.front().iCmd == PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_RESET)
   6668                                        )
   6669                                     {
   6670                                         CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFErrResource);
   6671                                     }
   6672                                 }
   6673 
   6674 
   6675                             }
   6676                         }
   6677 
   6678 
   6679 
   6680                         iEndOfDataReached = false;
   6681                         iIsEOSSentToComponent = false;
   6682                         iIsEOSReceivedFromComponent = false;
   6683 
   6684 
   6685 
   6686                         // also, perform Port deletion when the component replies with the command
   6687                         // complete, not right here
   6688                     } // end of if(iResetMsgSent)
   6689 
   6690 
   6691                     return;
   6692 
   6693                 }
   6694                 else if ((sState == OMX_StateExecuting) || (sState == OMX_StatePause))
   6695                 {
   6696                     //this command is asynchronous.  move the command from
   6697                     //the input command queue to the current command, where
   6698                     //it will remain until it is completed.
   6699                     if (!iResetInProgress)
   6700                     {
   6701                         int32 err;
   6702                         OSCL_TRY(err, iCurrentCommand.StoreL(aCmd););
   6703                         if (err != OsclErrNone)
   6704                         {
   6705                             CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
   6706                             return;
   6707                         }
   6708                         iInputCommands.Erase(&aCmd);
   6709 
   6710                         iResetInProgress = true;
   6711                     }
   6712 
   6713                     /* Change state to OMX_StateIdle from OMX_StateExecuting or OMX_StatePause. */
   6714 
   6715                     if (!iStopInResetMsgSent)
   6716                     {
   6717 
   6718                         // don't send twice in a row
   6719 
   6720                         iDataIn.Unbind();
   6721                         iPreviousMediaData.Unbind();
   6722                         if ((iOutFormat == PVMF_MIME_H264_VIDEO_MP4) || (iOutFormat == PVMF_MIME_H264_VIDEO_RAW))
   6723                         {
   6724                             // prepare for next start (if it comes)
   6725                             iFirstNAL = true;
   6726                         }
   6727                         // Clear queued messages in ports
   6728                         if (iInPort)
   6729                         {
   6730                             iInPort->ClearMsgQueues();
   6731                         }
   6732 
   6733                         if (iOutPort)
   6734                         {
   6735                             iOutPort->ClearMsgQueues();
   6736                         }
   6737 
   6738                         // Clear the data flags
   6739 
   6740                         iEndOfDataReached = false;
   6741                         iIsEOSSentToComponent = false;
   6742                         iIsEOSReceivedFromComponent = false;
   6743 
   6744 
   6745                         iDoNotSendOutputBuffersDownstreamFlag = true; // stop sending output buffers downstream
   6746                         iDoNotSaveInputBuffersFlag = true;
   6747 
   6748                         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   6749                                         (0, "PVMFOMXEncNode-%s::DoReset() Changing Component State Executing->Idle or Pause->Idle", iNodeTypeId));
   6750 
   6751                         err = OMX_SendCommand(iOMXEncoder, OMX_CommandStateSet, OMX_StateIdle, NULL);
   6752                         if (err != OMX_ErrorNone)
   6753                         {
   6754                             //Error condition report
   6755                             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   6756                                             (0, "PVMFOMXEncNode-%s::DoReset(): Can't send StateSet command to Encoder!", iNodeTypeId));
   6757 
   6758                             CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
   6759                             break;
   6760                         }
   6761 
   6762                         iStopInResetMsgSent = true;
   6763 
   6764                         // prevent the node from sending more buffers etc.
   6765                         // if port reconfiguration is in process, let the state remain one of the port config states
   6766                         //  if there is a start command, we can do it seemlessly (by continuing the port reconfig)
   6767                         if (iProcessingState == EPVMFOMXEncNodeProcessingState_ReadyToEncode)
   6768                             iProcessingState = EPVMFOMXEncNodeProcessingState_Stopping;
   6769                     }
   6770                     return;
   6771                 }
   6772                 else
   6773                 {
   6774                     //Error condition report
   6775                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   6776                                     (0, "PVMFOMXEncNode-%s::DoReset(): Encoder is not in the Idle state! %d", iNodeTypeId, sState ));
   6777                     //do it here rather than relying on DTOR to avoid node reinit problems.
   6778                     DeleteOMXEncoder();
   6779                     //still return success.
   6780                 }//end of if (sState == OMX_StateLoaded)
   6781             }//end of if (iOMXEncoder != NULL)
   6782 
   6783             //delete all ports and notify observer.
   6784             if (iInPort)
   6785             {
   6786                 OSCL_DELETE(((PVMFOMXEncPort*)iInPort));
   6787                 iInPort = NULL;
   6788             }
   6789 
   6790             if (iOutPort)
   6791             {
   6792                 OSCL_DELETE(((PVMFOMXEncPort*)iOutPort));
   6793                 iOutPort = NULL;
   6794             }
   6795 
   6796             iDataIn.Unbind();
   6797 
   6798 
   6799             // Reset the metadata key list
   6800             iAvailableMetadataKeys.clear();
   6801 
   6802             iEndOfDataReached = false;
   6803             iIsEOSSentToComponent = false;
   6804             iIsEOSReceivedFromComponent = false;
   6805 
   6806 
   6807             iProcessingState = EPVMFOMXEncNodeProcessingState_Idle;
   6808             //logoff & go back to Created state.
   6809             SetState(EPVMFNodeIdle);
   6810 
   6811 
   6812             if (iResetInProgress)
   6813             {
   6814                 iResetInProgress = false;
   6815                 if ((iCurrentCommand.size() > 0) &&
   6816                         (iCurrentCommand.front().iCmd == PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_RESET)
   6817                    )
   6818                 {
   6819                     CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFSuccess);
   6820                 }
   6821             }
   6822             else
   6823             {
   6824                 CommandComplete(iInputCommands, aCmd, PVMFSuccess);
   6825             }
   6826 
   6827         }
   6828         break;
   6829 
   6830         default:
   6831             CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
   6832             break;
   6833     }
   6834 }
   6835 
   6836 /////////////////////////////////////////////////////////////////////////////
   6837 void PVMFOMXEncNode::DoRequestPort(PVMFOMXEncNodeCommand& aCmd)
   6838 {
   6839     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   6840                     (0, "PVMFOMXEncNode-%s::DoRequestPort() In", iNodeTypeId));
   6841     //This node supports port request from any state
   6842 
   6843     //retrieve port tag.
   6844     int32 tag;
   6845     OSCL_String* portconfig;
   6846 
   6847     aCmd.PVMFOMXEncNodeCommandBase::Parse(tag, portconfig);
   6848 
   6849     PVMFPortInterface* port = NULL;
   6850 
   6851 
   6852     int32 leavecode = 0;
   6853     //validate the tag...
   6854 
   6855     switch (tag)
   6856     {
   6857         case PVMF_OMX_ENC_NODE_PORT_TYPE_INPUT:
   6858             if (iInPort)
   6859             {
   6860                 CommandComplete(iInputCommands, aCmd, PVMFFailure);
   6861                 break;
   6862             }
   6863             OSCL_TRY(leavecode, iInPort = OSCL_NEW(PVMFOMXEncPort, ((int32)tag, this, "OMXEncIn")););
   6864             if (leavecode || iInPort == NULL)
   6865             {
   6866                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   6867                                 (0, "PVMFOMXEncNode-%s::DoRequestPort: Error - Input port instantiation failed", iNodeTypeId));
   6868                 CommandComplete(iInputCommands, aCmd, PVMFErrArgument);
   6869                 return;
   6870             }
   6871 
   6872             // if format was provided in mimestring, set it now.
   6873             if (portconfig)
   6874             {
   6875                 PVMFFormatType format = portconfig->get_str();
   6876                 if (((PVMFOMXEncPort*)iInPort)->IsFormatSupported(format))
   6877                 {
   6878                     ((PVMFOMXEncPort*)iInPort)->iFormat = format;
   6879                 }
   6880                 else
   6881                 {
   6882 
   6883                     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   6884                                     (0, "PVMFOMXEncNode-%s::DoRequestPort: Error - Input port does not support format %s", iNodeTypeId, format.getMIMEStrPtr()));
   6885                     OSCL_DELETE(((PVMFOMXEncPort*)iInPort));
   6886                     iInPort = NULL;
   6887                     CommandComplete(iInputCommands, aCmd, PVMFErrArgument);
   6888                     return;
   6889                 }
   6890 
   6891             }
   6892 
   6893 
   6894             port = iInPort;
   6895             break;
   6896 
   6897         case PVMF_OMX_ENC_NODE_PORT_TYPE_OUTPUT:
   6898             if (iOutPort)
   6899             {
   6900                 CommandComplete(iInputCommands, aCmd, PVMFFailure);
   6901                 break;
   6902             }
   6903             OSCL_TRY(leavecode, iOutPort = OSCL_NEW(PVMFOMXEncPort, ((int32)tag, this, "OMXEncOut")));
   6904             if (leavecode || iOutPort == NULL)
   6905             {
   6906                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   6907                                 (0, "PVMFOMXEncNode-%s::DoRequestPort: Error - Output port instantiation failed", iNodeTypeId));
   6908                 CommandComplete(iInputCommands, aCmd, PVMFErrArgument);
   6909                 return;
   6910             }
   6911 
   6912             // if format was provided in mimestring, set it now.
   6913             if (portconfig)
   6914             {
   6915                 PVMFFormatType format = portconfig->get_str();
   6916                 if (((PVMFOMXEncPort*)iOutPort)->IsFormatSupported(format) && (SetCodecType(format) == PVMFSuccess))
   6917                 {
   6918                     ((PVMFOMXEncPort*)iOutPort)->iFormat = format;
   6919                 }
   6920                 else
   6921                 {
   6922 
   6923                     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   6924                                     (0, "PVMFOMXEncNode-%s::DoRequestPort: Error - Output port does not support format %s", iNodeTypeId, format.getMIMEStrPtr()));
   6925                     OSCL_DELETE(((PVMFOMXEncPort*)iOutPort));
   6926                     iOutPort = NULL;
   6927                     CommandComplete(iInputCommands, aCmd, PVMFErrArgument);
   6928                     return;
   6929                 }
   6930 
   6931 
   6932             }
   6933 
   6934             port = iOutPort;
   6935             break;
   6936 
   6937         default:
   6938             //bad port tag
   6939             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   6940                             (0, "PVMFOMXEncNode-%s::DoRequestPort: Error - Invalid port tag", iNodeTypeId));
   6941             CommandComplete(iInputCommands, aCmd, PVMFErrArgument);
   6942             return;
   6943     }
   6944 
   6945     //Return the port pointer to the caller.
   6946     CommandComplete(iInputCommands, aCmd, PVMFSuccess, (OsclAny*)port);
   6947 }
   6948 
   6949 /////////////////////////////////////////////////////////////////////////////
   6950 void PVMFOMXEncNode::DoReleasePort(PVMFOMXEncNodeCommand& aCmd)
   6951 {
   6952     PVMFPortInterface* temp;
   6953     aCmd.PVMFOMXEncNodeCommandBase::Parse(temp);
   6954     PVMFOMXEncPort* port = (PVMFOMXEncPort*) temp;
   6955 #ifdef _TEST_AE_ERROR_HANDLING
   6956     if (FAIL_NODE_CMD_RELEASE_PORT == iErrorNodeCmd)
   6957     {
   6958         port = NULL;
   6959     }
   6960 #endif
   6961 
   6962     if (port != NULL && (port == iInPort || port == iOutPort))
   6963     {
   6964         if (port == iInPort)
   6965         {
   6966             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   6967                             (0, "PVMFOMXEncNode-%s::DoReleasePort Input port released", iNodeTypeId));
   6968 
   6969             OSCL_DELETE(((PVMFOMXEncPort*)iInPort));
   6970             iInPort = NULL;
   6971         }
   6972         else
   6973         {
   6974             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   6975                             (0, "PVMFOMXEncNode-%s::DoReleasePort Output port released", iNodeTypeId));
   6976 
   6977             OSCL_DELETE(((PVMFOMXEncPort*)iOutPort));
   6978             iOutPort = NULL;
   6979         }
   6980         //delete the port.
   6981         CommandComplete(iInputCommands, aCmd, PVMFSuccess);
   6982     }
   6983     else
   6984     {
   6985         //port not found.
   6986         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   6987                         (0, "PVMFOMXEncNode-%s::DoReleasePort ERROR unknown port cannot be released", iNodeTypeId));
   6988 
   6989         CommandComplete(iInputCommands, aCmd, PVMFFailure);
   6990     }
   6991 }
   6992 
   6993 /////////////////////////////////////////////////////////////////////////////
   6994 PVMFStatus PVMFOMXEncNode::DoGetNodeMetadataKey(PVMFOMXEncNodeCommand& aCmd)
   6995 {
   6996     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   6997                     (0, "PVMFOMXEncNode-%s::DoGetNodeMetadataKey() In", iNodeTypeId));
   6998 
   6999     PVMFMetadataList* keylistptr = NULL;
   7000     uint32 starting_index;
   7001     int32 max_entries;
   7002     char* query_key;
   7003 
   7004     aCmd.PVMFOMXEncNodeCommand::Parse(keylistptr, starting_index, max_entries, query_key);
   7005 
   7006     // Check parameters
   7007     if (keylistptr == NULL)
   7008     {
   7009         // The list pointer is invalid
   7010         return PVMFErrArgument;
   7011     }
   7012 
   7013     // Update the available metadata keys
   7014     iAvailableMetadataKeys.clear();
   7015     int32 leavecode = 0;
   7016     leavecode = Push_Back_MetadataKeys(PVOMXENCMETADATA_CODECINFO_VIDEO_FORMAT_KEY);
   7017 
   7018     if (iYUVWidth > 0 && iYUVHeight > 0)
   7019     {
   7020         leavecode = 0;
   7021         leavecode = Push_Back_MetadataKeys(PVOMXENCMETADATA_CODECINFO_VIDEO_WIDTH_KEY);
   7022         if (0 == leavecode)
   7023             leavecode = Push_Back_MetadataKeys(PVOMXENCMETADATA_CODECINFO_VIDEO_HEIGHT_KEY);
   7024     }
   7025     // add the profile, level and avgbitrate
   7026     PVMF_MPEGVideoProfileType aProfile;
   7027     PVMF_MPEGVideoLevelType aLevel;
   7028     if (GetProfileAndLevel(aProfile, aLevel) == PVMFSuccess)
   7029     {
   7030         // For H263 this metadata will be available only after first frame decoding
   7031         leavecode = 0;
   7032         leavecode = Push_Back_MetadataKeys(PVOMXENCMETADATA_CODECINFO_VIDEO_PROFILE_KEY);
   7033         if (0 == leavecode)
   7034             leavecode = Push_Back_MetadataKeys(PVOMXENCMETADATA_CODECINFO_VIDEO_LEVEL_KEY);
   7035     }
   7036     if (0 == leavecode)
   7037         leavecode = Push_Back_MetadataKeys(PVOMXENCMETADATA_CODECINFO_VIDEO_AVGBITRATE_KEY);
   7038 
   7039     if ((starting_index > (iAvailableMetadataKeys.size() - 1)) || max_entries == 0)
   7040     {
   7041         // Invalid starting index and/or max entries
   7042         return PVMFErrArgument;
   7043     }
   7044 
   7045     // Copy the requested keys
   7046     uint32 num_entries = 0;
   7047     int32 num_added = 0;
   7048     for (uint32 lcv = 0; lcv < iAvailableMetadataKeys.size(); lcv++)
   7049     {
   7050         if (query_key == NULL)
   7051         {
   7052             // No query key so this key is counted
   7053             ++num_entries;
   7054             if (num_entries > starting_index)
   7055             {
   7056                 // Past the starting index so copy the key
   7057                 leavecode = 0;
   7058                 leavecode = Push_Back_MetadataKeys(keylistptr, lcv);
   7059                 OSCL_FIRST_CATCH_ANY(leavecode,
   7060                                      PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   7061                                                      (0, "PVMFOMXEncNode-%s::DoGetNodeMetadataKey() Memory allocation failure when copying metadata key", iNodeTypeId));
   7062                                      return PVMFErrNoMemory);
   7063                 num_added++;
   7064             }
   7065         }
   7066         else
   7067         {
   7068             // Check if the key matche the query key
   7069             if (pv_mime_strcmp(iAvailableMetadataKeys[lcv].get_cstr(), query_key) >= 0)
   7070             {
   7071                 // This key is counted
   7072                 ++num_entries;
   7073                 if (num_entries > starting_index)
   7074                 {
   7075                     // Past the starting index so copy the key
   7076                     leavecode = 0;
   7077                     leavecode = Push_Back_MetadataKeys(keylistptr, lcv);
   7078                     OSCL_FIRST_CATCH_ANY(leavecode,
   7079                                          PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::DoGetNodeMetadataKey() Memory allocation failure when copying metadata key", iNodeTypeId));
   7080                                          return PVMFErrNoMemory);
   7081                     num_added++;
   7082                 }
   7083             }
   7084         }
   7085 
   7086         // Check if max number of entries have been copied
   7087         if (max_entries > 0 && num_added >= max_entries)
   7088         {
   7089             break;
   7090         }
   7091     }
   7092 
   7093     return PVMFSuccess;
   7094 }
   7095 
   7096 /////////////////////////////////////////////////////////////////////////////
   7097 PVMFStatus PVMFOMXEncNode::DoGetNodeMetadataValue(PVMFOMXEncNodeCommand& aCmd)
   7098 {
   7099     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::DoGetNodeMetadataValue() In", iNodeTypeId));
   7100 
   7101     PVMFMetadataList* keylistptr = NULL;
   7102     Oscl_Vector<PvmiKvp, OsclMemAllocator>* valuelistptr = NULL;
   7103     uint32 starting_index;
   7104     int32 max_entries;
   7105 
   7106     aCmd.PVMFOMXEncNodeCommand::Parse(keylistptr, valuelistptr, starting_index, max_entries);
   7107 
   7108     // Check the parameters
   7109     if (keylistptr == NULL || valuelistptr == NULL)
   7110     {
   7111         return PVMFErrArgument;
   7112     }
   7113 
   7114     uint32 numkeys = keylistptr->size();
   7115 
   7116     if (starting_index > (numkeys - 1) || numkeys <= 0 || max_entries == 0)
   7117     {
   7118         // Don't do anything
   7119         return PVMFErrArgument;
   7120     }
   7121 
   7122     uint32 numvalentries = 0;
   7123     int32 numentriesadded = 0;
   7124     for (uint32 lcv = 0; lcv < numkeys; lcv++)
   7125     {
   7126         int32 leavecode = 0;
   7127         PvmiKvp KeyVal;
   7128         KeyVal.key = NULL;
   7129         uint32 KeyLen = 0;
   7130 
   7131         if ((oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVOMXENCMETADATA_CODECINFO_VIDEO_WIDTH_KEY) == 0) &&
   7132                 iYUVWidth > 0)
   7133         {
   7134             // Video width
   7135             // Increment the counter for the number of values found so far
   7136             ++numvalentries;
   7137 
   7138             // Create a value entry if past the starting index
   7139             if (numvalentries > starting_index)
   7140             {
   7141                 KeyLen = oscl_strlen(PVOMXENCMETADATA_CODECINFO_VIDEO_WIDTH_KEY) + 1; // for "codec-info/video/width;"
   7142                 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
   7143                 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR) + 1; // for "uint32" and NULL terminator
   7144 
   7145                 // Allocate memory for the string
   7146                 leavecode = 0;
   7147                 leavecode = CreateNewArray(KeyVal.key, KeyLen);
   7148 
   7149 
   7150 
   7151                 if (leavecode == 0)
   7152                 {
   7153                     // Copy the key string
   7154                     oscl_strncpy(KeyVal.key, PVOMXENCMETADATA_CODECINFO_VIDEO_WIDTH_KEY, oscl_strlen(PVOMXENCMETADATA_CODECINFO_VIDEO_WIDTH_KEY) + 1);
   7155                     oscl_strncat(KeyVal.key, PVOMXENCMETADATA_SEMICOLON, oscl_strlen(PVOMXENCMETADATA_SEMICOLON));
   7156                     oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
   7157                     oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR));
   7158                     KeyVal.key[KeyLen-1] = NULL_TERM_CHAR;
   7159                     // Copy the value
   7160                     KeyVal.value.uint32_value = iYUVWidth;
   7161                     // Set the length and capacity
   7162                     KeyVal.length = 1;
   7163                     KeyVal.capacity = 1;
   7164                 }
   7165                 else
   7166                 {
   7167                     // Memory allocation failed
   7168                     KeyVal.key = NULL;
   7169                     break;
   7170                 }
   7171             }
   7172         }
   7173         else if ((oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVOMXENCMETADATA_CODECINFO_VIDEO_HEIGHT_KEY) == 0) &&
   7174                  iYUVHeight > 0)
   7175         {
   7176             // Video height
   7177             // Increment the counter for the number of values found so far
   7178             ++numvalentries;
   7179 
   7180             // Create a value entry if past the starting index
   7181             if (numvalentries > starting_index)
   7182             {
   7183                 KeyLen = oscl_strlen(PVOMXENCMETADATA_CODECINFO_VIDEO_HEIGHT_KEY) + 1; // for "codec-info/video/height;"
   7184                 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
   7185                 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR) + 1; // for "uint32" and NULL terminator
   7186 
   7187                 // Allocate memory for the string
   7188                 leavecode = 0;
   7189                 leavecode = CreateNewArray(KeyVal.key, KeyLen);
   7190 
   7191 
   7192 
   7193                 if (leavecode == 0)
   7194                 {
   7195                     // Copy the key string
   7196                     oscl_strncpy(KeyVal.key, PVOMXENCMETADATA_CODECINFO_VIDEO_HEIGHT_KEY, oscl_strlen(PVOMXENCMETADATA_CODECINFO_VIDEO_HEIGHT_KEY) + 1);
   7197                     oscl_strncat(KeyVal.key, PVOMXENCMETADATA_SEMICOLON, oscl_strlen(PVOMXENCMETADATA_SEMICOLON));
   7198                     oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
   7199                     oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR));
   7200                     KeyVal.key[KeyLen-1] = NULL_TERM_CHAR;
   7201                     // Copy the value
   7202                     KeyVal.value.uint32_value = iYUVHeight;
   7203                     // Set the length and capacity
   7204                     KeyVal.length = 1;
   7205                     KeyVal.capacity = 1;
   7206                 }
   7207                 else
   7208                 {
   7209                     // Memory allocation failed
   7210                     KeyVal.key = NULL;
   7211                     break;
   7212                 }
   7213             }
   7214         }
   7215         else if ((oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVOMXENCMETADATA_CODECINFO_VIDEO_PROFILE_KEY) == 0))
   7216         {
   7217             // Video profile
   7218             // Increment the counter for the number of values found so far
   7219             ++numvalentries;
   7220 
   7221             // Create a value entry if past the starting index
   7222             if (numvalentries > starting_index)
   7223             {
   7224                 KeyLen = oscl_strlen(PVOMXENCMETADATA_CODECINFO_VIDEO_PROFILE_KEY) + 1; // for "codec-info/video/profile;"
   7225                 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
   7226                 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR) + 1; // for "uint32" and NULL terminator
   7227 
   7228                 // Allocate memory for the string
   7229                 leavecode = 0;
   7230                 leavecode = CreateNewArray(KeyVal.key, KeyLen);
   7231 
   7232 
   7233 
   7234                 if (leavecode == 0)
   7235                 {
   7236                     PVMF_MPEGVideoProfileType aProfile;
   7237                     PVMF_MPEGVideoLevelType aLevel;
   7238                     if (GetProfileAndLevel(aProfile, aLevel) == PVMFSuccess)
   7239                     {
   7240                         // Copy the key string
   7241                         oscl_strncpy(KeyVal.key, PVOMXENCMETADATA_CODECINFO_VIDEO_PROFILE_KEY, oscl_strlen(PVOMXENCMETADATA_CODECINFO_VIDEO_PROFILE_KEY) + 1);
   7242                         oscl_strncat(KeyVal.key, PVOMXENCMETADATA_SEMICOLON, oscl_strlen(PVOMXENCMETADATA_SEMICOLON));
   7243                         oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
   7244                         oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR));
   7245                         KeyVal.key[KeyLen-1] = NULL_TERM_CHAR;
   7246                         // Copy the value
   7247                         KeyVal.value.uint32_value = (uint32)aProfile; // This is to be decided, who will interpret these value
   7248                         // Set the length and capacity
   7249                         KeyVal.length = 1;
   7250                         KeyVal.capacity = 1;
   7251                     }
   7252                     else
   7253                     {
   7254                         // Memory allocation failed
   7255                         KeyVal.key = NULL;
   7256                         break;
   7257                     }
   7258                 }
   7259                 else
   7260                 {
   7261                     // Memory allocation failed
   7262                     KeyVal.key = NULL;
   7263                     break;
   7264                 }
   7265             }
   7266         }
   7267         else if ((oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVOMXENCMETADATA_CODECINFO_VIDEO_LEVEL_KEY) == 0))
   7268         {
   7269             // Video level
   7270             // Increment the counter for the number of values found so far
   7271             ++numvalentries;
   7272 
   7273             // Create a value entry if past the starting index
   7274             if (numvalentries > starting_index)
   7275             {
   7276                 KeyLen = oscl_strlen(PVOMXENCMETADATA_CODECINFO_VIDEO_LEVEL_KEY) + 1; // for "codec-info/video/level;"
   7277                 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
   7278                 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR) + 1; // for "uint32" and NULL terminator
   7279 
   7280                 // Allocate memory for the string
   7281                 leavecode = 0;
   7282                 leavecode = CreateNewArray(KeyVal.key, KeyLen);
   7283 
   7284 
   7285 
   7286                 if (leavecode == 0)
   7287                 {
   7288                     PVMF_MPEGVideoProfileType aProfile;
   7289                     PVMF_MPEGVideoLevelType aLevel;
   7290                     if (GetProfileAndLevel(aProfile, aLevel) == PVMFSuccess)
   7291                     {
   7292                         // Copy the key string
   7293                         oscl_strncpy(KeyVal.key, PVOMXENCMETADATA_CODECINFO_VIDEO_LEVEL_KEY, oscl_strlen(PVOMXENCMETADATA_CODECINFO_VIDEO_LEVEL_KEY) + 1);
   7294                         oscl_strncat(KeyVal.key, PVOMXENCMETADATA_SEMICOLON, oscl_strlen(PVOMXENCMETADATA_SEMICOLON));
   7295                         oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
   7296                         oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR));
   7297                         KeyVal.key[KeyLen-1] = NULL_TERM_CHAR;
   7298                         // Copy the value
   7299                         KeyVal.value.uint32_value = (uint32)aLevel; // This is to be decided, who will interpret these value
   7300                         // Set the length and capacity
   7301                         KeyVal.length = 1;
   7302                         KeyVal.capacity = 1;
   7303                     }
   7304                     else
   7305                     {
   7306                         // Memory allocation failed
   7307                         KeyVal.key = NULL;
   7308                         break;
   7309                     }
   7310                 }
   7311                 else
   7312                 {
   7313                     // Memory allocation failed
   7314                     KeyVal.key = NULL;
   7315                     break;
   7316                 }
   7317             }
   7318         }
   7319         else if ((oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVOMXENCMETADATA_CODECINFO_VIDEO_AVGBITRATE_KEY) == 0) &&
   7320                  (iAvgBitrateValue > 0))
   7321         {
   7322             // Video average bitrate
   7323             // Increment the counter for the number of values found so far
   7324             ++numvalentries;
   7325 
   7326             // Create a value entry if past the starting index
   7327             if (numvalentries > starting_index)
   7328             {
   7329                 KeyLen = oscl_strlen(PVOMXENCMETADATA_CODECINFO_VIDEO_AVGBITRATE_KEY) + 1; // for "codec-info/video/avgbitrate;"
   7330                 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
   7331                 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR) + 1; // for "uint32" and NULL terminator
   7332 
   7333                 // Allocate memory for the string
   7334                 leavecode = 0;
   7335                 leavecode = CreateNewArray(KeyVal.key, KeyLen);
   7336 
   7337 
   7338 
   7339                 if (leavecode == 0)
   7340                 {
   7341                     // Copy the key string
   7342                     oscl_strncpy(KeyVal.key, PVOMXENCMETADATA_CODECINFO_VIDEO_AVGBITRATE_KEY, oscl_strlen(PVOMXENCMETADATA_CODECINFO_VIDEO_AVGBITRATE_KEY) + 1);
   7343                     oscl_strncat(KeyVal.key, PVOMXENCMETADATA_SEMICOLON, oscl_strlen(PVOMXENCMETADATA_SEMICOLON));
   7344                     oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
   7345                     oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR));
   7346                     KeyVal.key[KeyLen-1] = NULL_TERM_CHAR;
   7347                     // Copy the value
   7348                     KeyVal.value.uint32_value = iAvgBitrateValue;
   7349                     // Set the length and capacity
   7350                     KeyVal.length = 1;
   7351                     KeyVal.capacity = 1;
   7352 
   7353                 }
   7354                 else
   7355                 {
   7356                     // Memory allocation failed
   7357                     KeyVal.key = NULL;
   7358                     break;
   7359                 }
   7360             }
   7361         }
   7362         else if ((oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVOMXENCMETADATA_CODECINFO_VIDEO_FORMAT_KEY) == 0) &&
   7363                  (((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_H2631998 || ((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_H2632000 || ((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_M4V ||
   7364                   ((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO || ((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO_MP4 ||
   7365                   ((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO_RAW  || ((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_WMV))
   7366         {
   7367             // Format
   7368             // Increment the counter for the number of values found so far
   7369             ++numvalentries;
   7370 
   7371             // Create a value entry if past the starting index
   7372             if (numvalentries > starting_index)
   7373             {
   7374                 KeyLen = oscl_strlen(PVOMXENCMETADATA_CODECINFO_VIDEO_FORMAT_KEY) + 1; // for "codec-info/video/format;"
   7375                 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
   7376                 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_CHARPTR_STRING_CONSTCHAR) + 1; // for "char*" and NULL terminator
   7377 
   7378                 uint32 valuelen = 0;
   7379                 if (((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO)
   7380                 {
   7381                     valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_H264_VIDEO)) + 1; // Value string plus one for NULL terminator
   7382                 }
   7383                 else if (((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO_MP4)
   7384                 {
   7385                     valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_H264_VIDEO_MP4)) + 1; // Value string plus one for NULL terminator
   7386                 }
   7387                 else if (((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO_RAW)
   7388                 {
   7389                     valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_H264_VIDEO_RAW)) + 1; // Value string plus one for NULL terminator
   7390                 }
   7391                 else if (((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_M4V)
   7392                 {
   7393                     valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_M4V)) + 1; // Value string plus one for NULL terminator
   7394                 }
   7395                 else if (((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_H2631998)
   7396                 {
   7397                     valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_H2631998)) + 1; // Value string plus one for NULL terminator
   7398                 }
   7399                 else if (((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_H2632000)
   7400                 {
   7401                     oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_H2632000), valuelen);
   7402                 }
   7403                 else if (((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_WMV)
   7404                 {
   7405                     valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_WMV)) + 1; // Value string plus one for NULL terminator
   7406                 }
   7407                 else
   7408                 {
   7409                     // Should not enter here
   7410                     OSCL_ASSERT(false);
   7411                     valuelen = 1;
   7412                 }
   7413 
   7414                 // Allocate memory for the strings
   7415                 leavecode = 0;
   7416                 leavecode = CreateNewArray(KeyVal.key, KeyLen);
   7417                 if (0 == leavecode)
   7418                 {
   7419                     leavecode = CreateNewArray(KeyVal.value.pChar_value , valuelen);
   7420                 }
   7421 
   7422                 if (leavecode == 0)
   7423                 {
   7424                     // Copy the key string
   7425                     oscl_strncpy(KeyVal.key, PVOMXENCMETADATA_CODECINFO_VIDEO_FORMAT_KEY, oscl_strlen(PVOMXENCMETADATA_CODECINFO_VIDEO_FORMAT_KEY) + 1);
   7426                     oscl_strncat(KeyVal.key, PVOMXENCMETADATA_SEMICOLON, oscl_strlen(PVOMXENCMETADATA_SEMICOLON));
   7427                     oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
   7428                     oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_CHARPTR_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_CHARPTR_STRING_CONSTCHAR));
   7429                     KeyVal.key[KeyLen-1] = NULL_TERM_CHAR;
   7430                     // Copy the value
   7431                     if (((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO)
   7432                     {
   7433                         oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_H264_VIDEO), valuelen);
   7434                     }
   7435                     else if (((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO_MP4)
   7436                     {
   7437                         oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_H264_VIDEO_MP4), valuelen);
   7438                     }
   7439                     else if (((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO_RAW)
   7440                     {
   7441                         oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_H264_VIDEO_RAW), valuelen);
   7442                     }
   7443                     else if (((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_M4V)
   7444                     {
   7445                         oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_M4V), valuelen);
   7446                     }
   7447                     else if (((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_H2631998)
   7448                     {
   7449                         oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_H2631998), valuelen);
   7450                     }
   7451                     else if (((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_H2632000)
   7452                     {
   7453                         oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_H2632000), valuelen);
   7454                     }
   7455                     else if (((PVMFOMXEncPort*)iInPort)->iFormat == PVMF_MIME_WMV)
   7456                     {
   7457                         oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_WMV), valuelen);
   7458                     }
   7459                     else
   7460                     {
   7461                         // Should not enter here
   7462                         OSCL_ASSERT(false);
   7463                         valuelen = 1;
   7464                     }
   7465 
   7466                     KeyVal.value.pChar_value[valuelen-1] = NULL_TERM_CHAR;
   7467                     // Set the length and capacity
   7468                     KeyVal.length = valuelen;
   7469                     KeyVal.capacity = valuelen;
   7470                 }
   7471                 else
   7472                 {
   7473                     // Memory allocation failed so clean up
   7474                     if (KeyVal.key)
   7475                     {
   7476                         OSCL_ARRAY_DELETE(KeyVal.key);
   7477                         KeyVal.key = NULL;
   7478                     }
   7479                     if (KeyVal.value.pChar_value)
   7480                     {
   7481                         OSCL_ARRAY_DELETE(KeyVal.value.pChar_value);
   7482                     }
   7483                     break;
   7484                 }
   7485             }
   7486         }
   7487 
   7488         if (KeyVal.key != NULL)
   7489         {
   7490             leavecode = 0;
   7491             leavecode = PushBackKeyVal(valuelistptr, KeyVal);
   7492             if (leavecode != 0)
   7493             {
   7494                 switch (GetValTypeFromKeyString(KeyVal.key))
   7495                 {
   7496                     case PVMI_KVPVALTYPE_CHARPTR:
   7497                         if (KeyVal.value.pChar_value != NULL)
   7498                         {
   7499                             OSCL_ARRAY_DELETE(KeyVal.value.pChar_value);
   7500                             KeyVal.value.pChar_value = NULL;
   7501                         }
   7502                         break;
   7503 
   7504                     default:
   7505                         // Add more case statements if other value types are returned
   7506                         break;
   7507                 }
   7508 
   7509                 OSCL_ARRAY_DELETE(KeyVal.key);
   7510                 KeyVal.key = NULL;
   7511             }
   7512             else
   7513             {
   7514                 // Increment the counter for number of value entries added to the list
   7515                 ++numentriesadded;
   7516             }
   7517 
   7518             // Check if the max number of value entries were added
   7519             if (max_entries > 0 && numentriesadded >= max_entries)
   7520             {
   7521                 break;
   7522             }
   7523         }
   7524     }
   7525 
   7526     return PVMFSuccess;
   7527 }
   7528 
   7529 /////////////////////////////////////////////////////////////////////////////
   7530 bool PVMFOMXEncNode::ReleaseAllPorts()
   7531 {
   7532     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::ReleaseAllPorts() In", iNodeTypeId));
   7533 
   7534     if (iInPort)
   7535     {
   7536         iInPort->ClearMsgQueues();
   7537         iInPort->Disconnect();
   7538         OSCL_DELETE(((PVMFOMXEncPort*)iInPort));
   7539         iInPort = NULL;
   7540     }
   7541 
   7542     if (iOutPort)
   7543     {
   7544         iOutPort->ClearMsgQueues();
   7545         iOutPort->Disconnect();
   7546         OSCL_DELETE(((PVMFOMXEncPort*)iOutPort));
   7547         iOutPort = NULL;
   7548     }
   7549 
   7550     return true;
   7551 }
   7552 
   7553 /////////////////////////////////////////////////////////////////////////////
   7554 // Clean Up Encoder
   7555 /////////////////////////////////////////////////////////////////////////////
   7556 bool PVMFOMXEncNode::DeleteOMXEncoder()
   7557 {
   7558     OMX_ERRORTYPE  err;
   7559 
   7560     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   7561                     (0, "PVMFOMXEncNode-%s::DeleteOMXEncoder() In", iNodeTypeId));
   7562 
   7563     if (iOMXEncoder != NULL)
   7564     {
   7565         /* Free Component handle. */
   7566         err = OMX_MasterFreeHandle(iOMXEncoder);
   7567         if (err != OMX_ErrorNone)
   7568         {
   7569             //Error condition report
   7570             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   7571                             (0, "PVMFOMXEncNode-%s::DeleteOMXEncoder(): Can't free encoder's handle!", iNodeTypeId));
   7572         }
   7573         iOMXEncoder = NULL;
   7574 
   7575     }//end of if (iOMXEncoder != NULL)
   7576 
   7577 
   7578     return true;
   7579 }
   7580 
   7581 /////////////////////////////////////////////////////////////////////////////
   7582 void PVMFOMXEncNode::ChangeNodeState(TPVMFNodeInterfaceState aNewState)
   7583 {
   7584     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::ChangeNodeState() Changing state from %d to %d", iNodeTypeId, iInterfaceState, aNewState));
   7585     iInterfaceState = aNewState;
   7586 }
   7587 
   7588 /////////////////////////////////////////////////////////////////////////////
   7589 void PVMFOMXEncNode::freechunkavailable(OsclAny *aContext)
   7590 {
   7591 
   7592     // check context to see whether input or output buffer was returned to the mempool
   7593     if (aContext == (OsclAny *) iInBufMemoryPool)
   7594     {
   7595 
   7596         iNumOutstandingInputBuffers--;
   7597 
   7598         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   7599                         (0, "PVMFOMXEncNode-%s::freechunkavailable() Memory chunk in INPUT mempool was deallocated, %d out of %d now available", iNodeTypeId, iNumInputBuffers - iNumOutstandingInputBuffers, iNumInputBuffers));
   7600 
   7601         // notification only works once.
   7602         // If there are multiple buffers coming back in a row, make sure to set the notification
   7603         // flag in the mempool again, so that next buffer also causes notification
   7604         iInBufMemoryPool->notifyfreechunkavailable(*this, aContext);
   7605 
   7606     }
   7607     else if (aContext == (OsclAny *) iOutBufMemoryPool)
   7608     {
   7609 
   7610         iNumOutstandingOutputBuffers--;
   7611         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   7612                         (0, "PVMFOMXEncNode-%s::freechunkavailable() Memory chunk in OUTPUT mempool was deallocated, %d out of %d now available", iNodeTypeId, iNumOutputBuffers - iNumOutstandingOutputBuffers, iNumOutputBuffers));
   7613 
   7614         // notification only works once.
   7615         // If there are multiple buffers coming back in a row, make sure to set the notification
   7616         // flag in the mempool again, so that next buffer also causes notification
   7617         iOutBufMemoryPool->notifyfreechunkavailable(*this, aContext);
   7618 
   7619     }
   7620     else
   7621     {
   7622         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   7623                         (0, "PVMFOMXEncNode-%s::freechunkavailable() UNKNOWN mempool ", iNodeTypeId));
   7624 
   7625     }
   7626 
   7627     // reschedule
   7628     if (IsAdded())
   7629         RunIfNotReady();
   7630 
   7631 
   7632 }
   7633 
   7634 /////////////////////////////////////////////////////////////////////////////
   7635 void PVMFOMXEncNode::HandlePortActivity(const PVMFPortActivity &aActivity)
   7636 {
   7637     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   7638                     (0, "0x%x PVMFOMXEncNode-%s::PortActivity: port=0x%x, type=%d",
   7639                      this, iNodeTypeId, aActivity.iPort, aActivity.iType));
   7640 
   7641     switch (aActivity.iType)
   7642     {
   7643         case PVMF_PORT_ACTIVITY_OUTGOING_MSG:
   7644             //An outgoing message was queued on this port.
   7645             //We only need to queue a port activity event on the
   7646             //first message.  Additional events will be queued during
   7647             //the port processing as needed.
   7648             if (aActivity.iPort->OutgoingMsgQueueSize() == 1)
   7649             {
   7650                 //wake up the AO to process the port activity event.
   7651                 RunIfNotReady();
   7652             }
   7653             break;
   7654 
   7655         case PVMF_PORT_ACTIVITY_INCOMING_MSG:
   7656             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
   7657                             (0, "PVMFOMXEncNode-%s::PortActivity: IncomingMsgQueueSize=%d", iNodeTypeId, aActivity.iPort->IncomingMsgQueueSize()));
   7658             if (aActivity.iPort->IncomingMsgQueueSize() == 1)
   7659             {
   7660                 //wake up the AO to process the port activity event.
   7661                 RunIfNotReady();
   7662             }
   7663             break;
   7664 
   7665         case PVMF_PORT_ACTIVITY_OUTGOING_QUEUE_READY:
   7666             if (iProcessingState == EPVMFOMXEncNodeProcessingState_WaitForOutgoingQueue)
   7667             {
   7668                 iProcessingState = EPVMFOMXEncNodeProcessingState_ReadyToEncode;
   7669                 RunIfNotReady();
   7670             }
   7671             break;
   7672 
   7673         case PVMF_PORT_ACTIVITY_CONNECT:
   7674             //nothing needed.
   7675             break;
   7676 
   7677         case PVMF_PORT_ACTIVITY_DISCONNECT:
   7678             //clear the node input data when either port is disconnected.
   7679 
   7680             iDataIn.Unbind();
   7681             break;
   7682 
   7683         case PVMF_PORT_ACTIVITY_CONNECTED_PORT_BUSY:
   7684             // The connected port has become busy (its incoming queue is
   7685             // busy).
   7686             // No action is needed here-- the port processing code
   7687             // checks for connected port busy during data processing.
   7688             break;
   7689 
   7690         case PVMF_PORT_ACTIVITY_CONNECTED_PORT_READY:
   7691             // The connected port has transitioned from Busy to Ready to Receive.
   7692             // It's time to start processing outgoing messages again.
   7693 
   7694             //iProcessingState should transition from WaitForOutputPort to ReadyToEncode
   7695             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   7696                             (0, "0x%x PVMFOMXEncNode-%s::PortActivity: Connected port is now ready", this, iNodeTypeId));
   7697             RunIfNotReady();
   7698             break;
   7699 
   7700         default:
   7701             break;
   7702     }
   7703 }
   7704 
   7705 /////////////////////////////////////////////////////////////////////////////
   7706 void PVMFOMXEncNode::DoCancelAllCommands(PVMFOMXEncNodeCommand& aCmd)
   7707 {
   7708     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   7709                     (0, "PVMFOMXEncNode-%s::DoCancelAllCommands", iNodeTypeId));
   7710 
   7711     //first cancel the current command if any
   7712     {
   7713         while (!iCurrentCommand.empty())
   7714         {
   7715             CommandComplete(iCurrentCommand, iCurrentCommand[0], PVMFErrCancelled);
   7716         }
   7717 
   7718     }
   7719 
   7720     //next cancel all queued commands
   7721     {
   7722         //start at element 1 since this cancel command is element 0.
   7723         while (iInputCommands.size() > 1)
   7724         {
   7725             CommandComplete(iInputCommands, iInputCommands[1], PVMFErrCancelled);
   7726         }
   7727     }
   7728 
   7729     if (iResetInProgress && !iResetMsgSent)
   7730     {
   7731         // if reset is started but reset msg has not been sent, we can cancel reset
   7732         // as if nothing happened. Otherwise, the callback will set the flag back to false
   7733         iResetInProgress = false;
   7734     }
   7735     //finally, report cancel complete.
   7736     CommandComplete(iInputCommands, aCmd, PVMFSuccess);
   7737 }
   7738 
   7739 /////////////////////////////////////////////////////////////////////////////
   7740 void PVMFOMXEncNode::DoCancelCommand(PVMFOMXEncNodeCommand& aCmd)
   7741 {
   7742     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   7743                     (0, "PVMFOMXEncNode-%s::DoCancelCommand", iNodeTypeId));
   7744 
   7745     //extract the command ID from the parameters.
   7746     PVMFCommandId id;
   7747     aCmd.PVMFOMXEncNodeCommandBase::Parse(id);
   7748 
   7749     //first check "current" command if any
   7750     {
   7751         PVMFOMXEncNodeCommand* cmd = iCurrentCommand.FindById(id);
   7752         if (cmd)
   7753         {
   7754 
   7755             // if reset is being canceled:
   7756             if (cmd->iCmd == PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_RESET)
   7757             {
   7758                 if (iResetInProgress && !iResetMsgSent)
   7759                 {
   7760                     // if reset is started but reset msg has not been sent, we can cancel reset
   7761                     // as if nothing happened. Otherwise, the callback will set the flag back to false
   7762                     iResetInProgress = false;
   7763                 }
   7764             }
   7765             //cancel the queued command
   7766             CommandComplete(iCurrentCommand, *cmd, PVMFErrCancelled);
   7767             //report cancel success
   7768             CommandComplete(iInputCommands, aCmd, PVMFSuccess);
   7769             return;
   7770         }
   7771     }
   7772 
   7773     //next check input queue.
   7774     {
   7775         //start at element 1 since this cancel command is element 0.
   7776         PVMFOMXEncNodeCommand* cmd = iInputCommands.FindById(id, 1);
   7777         if (cmd)
   7778         {
   7779             //cancel the queued command
   7780             CommandComplete(iInputCommands, *cmd, PVMFErrCancelled);
   7781             //report cancel success
   7782             CommandComplete(iInputCommands, aCmd, PVMFSuccess);
   7783             return;
   7784         }
   7785     }
   7786     //if we get here the command isn't queued so the cancel fails.
   7787     CommandComplete(iInputCommands, aCmd, PVMFErrArgument);
   7788 }
   7789 
   7790 /////////////////////////////////////////////////////////////////////////////
   7791 void PVMFOMXEncNode::DoQueryUuid(PVMFOMXEncNodeCommand& aCmd)
   7792 {
   7793     //This node supports Query UUID from any state
   7794 
   7795     OSCL_String* mimetype;
   7796     Oscl_Vector<PVUuid, OsclMemAllocator> *uuidvec;
   7797     bool exactmatch;
   7798     aCmd.PVMFOMXEncNodeCommandBase::Parse(mimetype, uuidvec, exactmatch);
   7799 
   7800     //Try to match the input mimetype against any of
   7801     //the custom interfaces for this node
   7802 
   7803     //Match against custom interface1...
   7804     if (*mimetype == PVMF_OMX_ENC_NODE_CUSTOM1_MIMETYPE
   7805             //also match against base mimetypes for custom interface1,
   7806             //unless exactmatch is set.
   7807             || (!exactmatch && *mimetype == PVMF_OMX_ENC_NODE_MIMETYPE)
   7808             || (!exactmatch && *mimetype == PVMF_BASEMIMETYPE))
   7809     {
   7810 
   7811         PVUuid uuid(PVMF_OMX_ENC_NODE_CUSTOM1_UUID);
   7812         uuidvec->push_back(uuid);
   7813     }
   7814     CommandComplete(iInputCommands, aCmd, PVMFSuccess);
   7815 }
   7816 
   7817 /////////////////////////////////////////////////////////////////////////////
   7818 void PVMFOMXEncNode::DoQueryInterface(PVMFOMXEncNodeCommand&  aCmd)
   7819 {
   7820     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   7821                     (0, "PVMFOMXEncNode-%s::DoQueryInterface", iNodeTypeId));
   7822     PVUuid* uuid;
   7823     PVInterface** ptr;
   7824     aCmd.PVMFOMXEncNodeCommandBase::Parse(uuid, ptr);
   7825 
   7826     if (*uuid == PVUuid(PVMF_OMX_ENC_NODE_CUSTOM1_UUID))
   7827     {
   7828         addRef();
   7829         *ptr = (PVMFOMXEncNodeExtensionInterface*)this;
   7830         CommandComplete(iInputCommands, aCmd, PVMFSuccess);
   7831     }
   7832     else if (*uuid == PVUuid(KPVMFMetadataExtensionUuid))
   7833     {
   7834         addRef();
   7835         *ptr = (PVMFMetadataExtensionInterface*)this;
   7836         CommandComplete(iInputCommands, aCmd, PVMFSuccess);
   7837     }
   7838     else if (*uuid == PVUuid(PVMI_CAPABILITY_AND_CONFIG_PVUUID))
   7839     {
   7840         addRef();
   7841         *ptr = (PvmiCapabilityAndConfig*)this;
   7842         CommandComplete(iInputCommands, aCmd, PVMFSuccess);
   7843     }
   7844     else if (*uuid == PVMp4H263EncExtensionUUID)
   7845     {
   7846         addRef();
   7847         *ptr = OSCL_STATIC_CAST(PVMp4H263EncExtensionInterface*, this);
   7848         CommandComplete(iInputCommands, aCmd, PVMFSuccess);
   7849         //iface = OSCL_STATIC_CAST(PVInterface*, myInterface);
   7850 
   7851     }
   7852     else if (*uuid == PVAudioEncExtensionUUID)
   7853     {
   7854         addRef();
   7855         *ptr = OSCL_STATIC_CAST(PVAudioEncExtensionInterface*, this);
   7856         //iface = OSCL_STATIC_CAST(PVInterface*, myInterface);
   7857         CommandComplete(iInputCommands, aCmd, PVMFSuccess);
   7858 
   7859     }
   7860     else
   7861     {
   7862         //not supported
   7863         *ptr = NULL;
   7864         CommandComplete(iInputCommands, aCmd, PVMFFailure);
   7865     }
   7866 }
   7867 
   7868 /////////////////////////////////////////////////////////////////////////////
   7869 void PVMFOMXEncNode::addRef()
   7870 {
   7871     ++iExtensionRefCount;
   7872 }
   7873 
   7874 /////////////////////////////////////////////////////////////////////////////
   7875 void PVMFOMXEncNode::removeRef()
   7876 {
   7877     --iExtensionRefCount;
   7878 }
   7879 
   7880 /////////////////////////////////////////////////////////////////////////////
   7881 bool PVMFOMXEncNode::queryInterface(const PVUuid& uuid, PVInterface*& iface)
   7882 {
   7883     PVUuid my_uuid(PVMF_OMX_ENC_NODE_CUSTOM1_UUID);
   7884     if (uuid == my_uuid)
   7885     {
   7886         PVMFOMXEncNodeExtensionInterface* myInterface = OSCL_STATIC_CAST(PVMFOMXEncNodeExtensionInterface*, this);
   7887         iface = OSCL_STATIC_CAST(PVInterface*, myInterface);
   7888         ++iExtensionRefCount;
   7889         return true;
   7890     }
   7891     else if (uuid == KPVMFMetadataExtensionUuid)
   7892     {
   7893         PVMFMetadataExtensionInterface* myInterface = OSCL_STATIC_CAST(PVMFMetadataExtensionInterface*, this);
   7894         iface = OSCL_STATIC_CAST(PVInterface*, myInterface);
   7895         ++iExtensionRefCount;
   7896         return true;
   7897     }
   7898     return false;
   7899 }
   7900 
   7901 /////////////////////////////////////////////////////////////////////////////
   7902 uint32 PVMFOMXEncNode::GetNumMetadataKeys(char* aQueryKeyString)
   7903 {
   7904     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::GetNumMetadataKeys() called", iNodeTypeId));
   7905 
   7906     // Update the available metadata keys
   7907     iAvailableMetadataKeys.clear();
   7908     int32 errcode = 0;
   7909     OSCL_TRY(errcode, iAvailableMetadataKeys.push_back(PVOMXENCMETADATA_CODECINFO_VIDEO_FORMAT_KEY));
   7910 
   7911     if (iYUVWidth > 0 && iYUVHeight > 0)
   7912     {
   7913         errcode = 0;
   7914         OSCL_TRY(errcode,
   7915                  iAvailableMetadataKeys.push_back(PVOMXENCMETADATA_CODECINFO_VIDEO_WIDTH_KEY);
   7916                  iAvailableMetadataKeys.push_back(PVOMXENCMETADATA_CODECINFO_VIDEO_HEIGHT_KEY));
   7917     }
   7918     // add the profile, level and avgbitrate
   7919     PVMF_MPEGVideoProfileType aProfile;
   7920     PVMF_MPEGVideoLevelType aLevel;
   7921     if (GetProfileAndLevel(aProfile, aLevel) == PVMFSuccess)
   7922     {
   7923         // For H263 this metadata will be available only after first frame decoding
   7924         errcode = 0;
   7925         OSCL_TRY(errcode, iAvailableMetadataKeys.push_back(PVOMXENCMETADATA_CODECINFO_VIDEO_PROFILE_KEY));
   7926         errcode = 0;
   7927         OSCL_TRY(errcode, iAvailableMetadataKeys.push_back(PVOMXENCMETADATA_CODECINFO_VIDEO_LEVEL_KEY));
   7928     }
   7929     errcode = 0;
   7930     OSCL_TRY(errcode, iAvailableMetadataKeys.push_back(PVOMXENCMETADATA_CODECINFO_VIDEO_AVGBITRATE_KEY));
   7931 
   7932 
   7933 
   7934     uint32 num_entries = 0;
   7935 
   7936     if (aQueryKeyString == NULL)
   7937     {
   7938         num_entries = iAvailableMetadataKeys.size();
   7939     }
   7940     else
   7941     {
   7942         for (uint32 i = 0; i < iAvailableMetadataKeys.size(); i++)
   7943         {
   7944             if (pv_mime_strcmp(iAvailableMetadataKeys[i].get_cstr(), aQueryKeyString) >= 0)
   7945             {
   7946                 num_entries++;
   7947             }
   7948         }
   7949     }
   7950     return num_entries; // Number of elements
   7951 }
   7952 
   7953 ///////////////////////////////////////////////////////////////////////////////////////
   7954 void PVMFOMXEncNode::setObserver(PvmiConfigAndCapabilityCmdObserver* aObserver)
   7955 {
   7956     OSCL_UNUSED_ARG(aObserver);
   7957     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::setObserver()", iNodeTypeId));
   7958     // This method is not supported so leave
   7959     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::setObserver() is not supported!", iNodeTypeId));
   7960     OSCL_LEAVE(PVMFErrNotSupported);
   7961 }
   7962 
   7963 
   7964 PVMFStatus PVMFOMXEncNode::getParametersSync(PvmiMIOSession aSession, PvmiKeyType aIdentifier, PvmiKvp*& aParameters, int& aNumParamElements, PvmiCapabilityContext aContext)
   7965 {
   7966     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::getParametersSync()", iNodeTypeId));
   7967     OSCL_UNUSED_ARG(aSession);
   7968 
   7969     return DoCapConfigGetParametersSync(aIdentifier, aParameters, aNumParamElements, aContext);
   7970 }
   7971 
   7972 
   7973 PVMFStatus PVMFOMXEncNode::releaseParameters(PvmiMIOSession aSession, PvmiKvp* aParameters, int aNumElements)
   7974 {
   7975     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::releaseParameters()", iNodeTypeId));
   7976     OSCL_UNUSED_ARG(aSession);
   7977 
   7978     return DoCapConfigReleaseParameters(aParameters, aNumElements);
   7979 }
   7980 
   7981 
   7982 void PVMFOMXEncNode::createContext(PvmiMIOSession aSession, PvmiCapabilityContext& aContext)
   7983 {
   7984     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::createContext()", iNodeTypeId));
   7985     OSCL_UNUSED_ARG(aSession);
   7986     OSCL_UNUSED_ARG(aContext);
   7987     // This method is not supported so leave
   7988     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::createContext() is not supported!", iNodeTypeId));
   7989     OSCL_LEAVE(PVMFErrNotSupported);
   7990 }
   7991 
   7992 
   7993 void PVMFOMXEncNode::setContextParameters(PvmiMIOSession aSession, PvmiCapabilityContext& aContext, PvmiKvp* aParameters, int aNumParamElements)
   7994 {
   7995     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::setContextParameters()", iNodeTypeId));
   7996     OSCL_UNUSED_ARG(aSession);
   7997     OSCL_UNUSED_ARG(aContext);
   7998     OSCL_UNUSED_ARG(aParameters);
   7999     OSCL_UNUSED_ARG(aNumParamElements);
   8000     // This method is not supported so leave
   8001     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::setContextParameters() is not supported!", iNodeTypeId));
   8002     OSCL_LEAVE(PVMFErrNotSupported);
   8003 }
   8004 
   8005 
   8006 void PVMFOMXEncNode::DeleteContext(PvmiMIOSession aSession, PvmiCapabilityContext& aContext)
   8007 {
   8008     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::DeleteContext()", iNodeTypeId));
   8009     OSCL_UNUSED_ARG(aSession);
   8010     OSCL_UNUSED_ARG(aContext);
   8011     // This method is not supported so leave
   8012     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::DeleteContext() is not supported!", iNodeTypeId));
   8013     OSCL_LEAVE(PVMFErrNotSupported);
   8014 }
   8015 
   8016 
   8017 void PVMFOMXEncNode::setParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters, int aNumElements, PvmiKvp* &aRetKVP)
   8018 {
   8019     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::setParametersSync()", iNodeTypeId));
   8020     OSCL_UNUSED_ARG(aSession);
   8021 
   8022     // Complete the request synchronously
   8023     DoCapConfigSetParameters(aParameters, aNumElements, aRetKVP);
   8024 }
   8025 
   8026 
   8027 PVMFCommandId PVMFOMXEncNode::setParametersAsync(PvmiMIOSession aSession, PvmiKvp* aParameters, int aNumElements, PvmiKvp*& aRetKVP, OsclAny* aContext)
   8028 {
   8029     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::setParametersAsync()", iNodeTypeId));
   8030     OSCL_UNUSED_ARG(aSession);
   8031     OSCL_UNUSED_ARG(aParameters);
   8032     OSCL_UNUSED_ARG(aNumElements);
   8033     OSCL_UNUSED_ARG(aRetKVP);
   8034     OSCL_UNUSED_ARG(aContext);
   8035 
   8036     // This method is not supported so leave
   8037     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::setParametersAsync() is not supported!", iNodeTypeId));
   8038     OSCL_LEAVE(PVMFErrNotSupported);
   8039     return 0;
   8040 }
   8041 
   8042 
   8043 uint32 PVMFOMXEncNode::getCapabilityMetric(PvmiMIOSession aSession)
   8044 {
   8045     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::getCapabilityMetric()", iNodeTypeId));
   8046     OSCL_UNUSED_ARG(aSession);
   8047     // Not supported so return 0
   8048     return 0;
   8049 }
   8050 
   8051 
   8052 PVMFStatus PVMFOMXEncNode::verifyParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters, int aNumElements)
   8053 {
   8054     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::verifyParametersSync()", iNodeTypeId));
   8055     OSCL_UNUSED_ARG(aSession);
   8056 
   8057     return DoCapConfigVerifyParameters(aParameters, aNumElements);
   8058 }
   8059 
   8060 
   8061 /////////////////////////////////////////////////////////////////////////////
   8062 uint32 PVMFOMXEncNode::GetNumMetadataValues(PVMFMetadataList& aKeyList)
   8063 {
   8064     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::GetNumMetadataValues() called", iNodeTypeId));
   8065 
   8066     uint32 numkeys = aKeyList.size();
   8067 
   8068     if (numkeys <= 0)
   8069     {
   8070         // Don't do anything
   8071         return 0;
   8072     }
   8073 
   8074     // Count the number of value entries for the provided key list
   8075     uint32 numvalentries = 0;
   8076     PVMF_MPEGVideoProfileType aProfile;
   8077     PVMF_MPEGVideoLevelType aLevel;
   8078     for (uint32 lcv = 0; lcv < numkeys; lcv++)
   8079     {
   8080         if ((oscl_strcmp(aKeyList[lcv].get_cstr(), PVOMXENCMETADATA_CODECINFO_VIDEO_WIDTH_KEY) == 0) &&
   8081                 iYUVWidth > 0)
   8082         {
   8083             // Video width
   8084             ++numvalentries;
   8085         }
   8086         else if ((oscl_strcmp(aKeyList[lcv].get_cstr(), PVOMXENCMETADATA_CODECINFO_VIDEO_HEIGHT_KEY) == 0) &&
   8087                  iYUVHeight > 0)
   8088         {
   8089             // Video height
   8090             ++numvalentries;
   8091         }
   8092         else if ((oscl_strcmp(aKeyList[lcv].get_cstr(), PVOMXENCMETADATA_CODECINFO_VIDEO_PROFILE_KEY) == 0) &&
   8093                  (GetProfileAndLevel(aProfile, aLevel) == PVMFSuccess))
   8094 
   8095         {
   8096             // Video profile
   8097             ++numvalentries;
   8098         }
   8099         else if ((oscl_strcmp(aKeyList[lcv].get_cstr(), PVOMXENCMETADATA_CODECINFO_VIDEO_LEVEL_KEY) == 0) &&
   8100                  (GetProfileAndLevel(aProfile, aLevel) == PVMFSuccess))
   8101         {
   8102             // Video level
   8103             ++numvalentries;
   8104         }
   8105         else if ((oscl_strcmp(aKeyList[lcv].get_cstr(), PVOMXENCMETADATA_CODECINFO_VIDEO_AVGBITRATE_KEY) == 0) &&
   8106                  (iAvgBitrateValue > 0))
   8107 
   8108         {
   8109             // Video average bitrate
   8110             if (iAvgBitrateValue > 0)
   8111                 ++numvalentries;
   8112         }
   8113         else if ((oscl_strcmp(aKeyList[lcv].get_cstr(), PVOMXENCMETADATA_CODECINFO_VIDEO_FORMAT_KEY) == 0) &&
   8114                  (((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))
   8115         {
   8116             // Format
   8117             ++numvalentries;
   8118         }
   8119     }
   8120 
   8121     return numvalentries;
   8122 }
   8123 
   8124 /////////////////////////////////////////////////////////////////////////////
   8125 PVMFCommandId PVMFOMXEncNode::GetNodeMetadataKeys(PVMFSessionId aSessionId, PVMFMetadataList& aKeyList, uint32 starting_index, int32 max_entries, char* query_key, const OsclAny* aContext)
   8126 {
   8127     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNodeCommand::GetNodeMetadataKeys() called", iNodeTypeId));
   8128 
   8129     PVMFOMXEncNodeCommand cmd;
   8130     cmd.PVMFOMXEncNodeCommand::Construct(aSessionId, PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_GETNODEMETADATAKEY, &aKeyList, starting_index, max_entries, query_key, aContext);
   8131     return QueueCommandL(cmd);
   8132 }
   8133 
   8134 /////////////////////////////////////////////////////////////////////////////
   8135 PVMFCommandId PVMFOMXEncNode::GetNodeMetadataValues(PVMFSessionId aSessionId, PVMFMetadataList& aKeyList, Oscl_Vector<PvmiKvp, OsclMemAllocator>& aValueList, uint32 starting_index, int32 max_entries, const OsclAny* aContext)
   8136 {
   8137     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNodeCommand::GetNodeMetadataValue() called", iNodeTypeId));
   8138 
   8139     PVMFOMXEncNodeCommand cmd;
   8140     cmd.PVMFOMXEncNodeCommand::Construct(aSessionId, PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_GETNODEMETADATAVALUE, &aKeyList, &aValueList, starting_index, max_entries, aContext);
   8141     return QueueCommandL(cmd);
   8142 }
   8143 
   8144 // From PVMFMetadataExtensionInterface
   8145 /////////////////////////////////////////////////////////////////////////////
   8146 PVMFStatus PVMFOMXEncNode::ReleaseNodeMetadataKeys(PVMFMetadataList& , uint32 , uint32)
   8147 {
   8148     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::ReleaseNodeMetadataKeys() called", iNodeTypeId));
   8149     //nothing needed-- there's no dynamic allocation in this node's key list
   8150     return PVMFSuccess;
   8151 }
   8152 
   8153 // From PVMFMetadataExtensionInterface
   8154 /////////////////////////////////////////////////////////////////////////////
   8155 PVMFStatus PVMFOMXEncNode::ReleaseNodeMetadataValues(Oscl_Vector<PvmiKvp, OsclMemAllocator>& aValueList, uint32 start, uint32 end)
   8156 {
   8157     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::ReleaseNodeMetadataValues() called", iNodeTypeId));
   8158 
   8159     if (aValueList.size() == 0 || start > end)
   8160     {
   8161         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::ReleaseNodeMetadataValues() Invalid start/end index", iNodeTypeId));
   8162         return PVMFErrArgument;
   8163     }
   8164 
   8165     if (end >= aValueList.size())
   8166     {
   8167         end = aValueList.size() - 1;
   8168     }
   8169 
   8170     for (uint32 i = start; i <= end; i++)
   8171     {
   8172         if (aValueList[i].key != NULL)
   8173         {
   8174             switch (GetValTypeFromKeyString(aValueList[i].key))
   8175             {
   8176                 case PVMI_KVPVALTYPE_CHARPTR:
   8177                     if (aValueList[i].value.pChar_value != NULL)
   8178                     {
   8179                         OSCL_ARRAY_DELETE(aValueList[i].value.pChar_value);
   8180                         aValueList[i].value.pChar_value = NULL;
   8181                     }
   8182                     break;
   8183 
   8184                 case PVMI_KVPVALTYPE_UINT32:
   8185                 case PVMI_KVPVALTYPE_UINT8:
   8186                     // No memory to free for these valtypes
   8187                     break;
   8188 
   8189                 default:
   8190                     // Should not get a value that wasn't created from here
   8191                     break;
   8192             }
   8193 
   8194             OSCL_ARRAY_DELETE(aValueList[i].key);
   8195             aValueList[i].key = NULL;
   8196         }
   8197     }
   8198 
   8199     return PVMFSuccess;
   8200 }
   8201 
   8202 
   8203 
   8204 
   8205 
   8206 
   8207 PVMFStatus PVMFOMXEncNode::GetProfileAndLevel(PVMF_MPEGVideoProfileType& aProfile, PVMF_MPEGVideoLevelType& aLevel)
   8208 {
   8209 
   8210     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::GetProfileAndLevel() In", iNodeTypeId));
   8211 
   8212     if (NULL == iOMXEncoder)
   8213     {
   8214         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::GetProfileAndLevel() iEncoder is Null", iNodeTypeId));
   8215         aProfile = PV_MPEG_VIDEO_RESERVED_PROFILE;
   8216         aLevel  = PV_MPEG_VIDEO_LEVEL_UNKNOWN;
   8217         return PVMFFailure;
   8218     }
   8219 
   8220     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::GetProfileAndLevel() iEncoder is Null", iNodeTypeId));
   8221     aProfile = PV_MPEG_VIDEO_RESERVED_PROFILE;
   8222     aLevel  = PV_MPEG_VIDEO_LEVEL_UNKNOWN;
   8223     // DV: FOR NOW, JUST RETURN FAILURE, WE DON'T SUPPORT THIS FEATURE YET
   8224     return PVMFFailure;
   8225 
   8226 
   8227 }
   8228 
   8229 
   8230 /////////////////////////////////////////////////////////////////////////////
   8231 void PVMFOMXEncNode::LogDiagnostics()
   8232 {
   8233     if (iDiagnosticsLogged == false)
   8234     {
   8235         iDiagnosticsLogged = true;
   8236         PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iDiagnosticsLogger, PVLOGMSG_INFO, (0, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"));
   8237         PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iDiagnosticsLogger, PVLOGMSG_INFO, (0, "PVMFOMXEncNode-%s - Number of Media Msgs Sent = %d", iNodeTypeId, iSeqNum));
   8238         PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iDiagnosticsLogger, PVLOGMSG_INFO, (0, "PVMFOMXEncNode-%s - TS of last encoded msg = %d", iNodeTypeId, ConvertOMXTicksIntoTimestamp(iTimeStampOut)));
   8239     }
   8240 }
   8241 
   8242 
   8243 
   8244 //////////////////////////////////
   8245 /////EXTENSION INTERFACE
   8246 ////////////////////////////////////
   8247 ////////////////////////////////////////////////////////////////////////////
   8248 OSCL_EXPORT_REF bool PVMFOMXEncNode::SetNumLayers(uint32 aNumLayers)
   8249 {
   8250     switch (iInterfaceState)
   8251     {
   8252         case EPVMFNodeStarted:
   8253         case EPVMFNodePaused:
   8254             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   8255                             (0, "PVMFOMXEncNode-%s::SetNumLayers: Error iInterfaceState=%d", iNodeTypeId, iInterfaceState));
   8256             return false;
   8257 
   8258         default:
   8259             break;
   8260     }
   8261 
   8262     if (aNumLayers > MAX_LAYER)
   8263     {
   8264         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   8265                         (0, "PVMFOMXEncNode-%s::SetNumLayers: Error Max num layers is %d", iNodeTypeId, MAX_LAYER));
   8266         return false;
   8267     }
   8268 
   8269     iVideoEncodeParam.iNumLayer = aNumLayers;
   8270     return true;
   8271 }
   8272 
   8273 ////////////////////////////////////////////////////////////////////////////
   8274 OSCL_EXPORT_REF bool PVMFOMXEncNode::SetOutputBitRate(uint32 aLayer, uint32 aBitRate)
   8275 {
   8276     switch (iInterfaceState)
   8277     {
   8278         case EPVMFNodeStarted:
   8279         case EPVMFNodePaused:
   8280             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::SetOutputBitRate: Error iInterfaceState=%d", iInterfaceState));
   8281             return false;
   8282 
   8283         default:
   8284             break;
   8285     }
   8286 
   8287     if ((int32)aLayer >= iVideoEncodeParam.iNumLayer)
   8288     {
   8289         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   8290                         (0, "PVMFOMXEncNode-%s::SetOutputBitRate: Error Invalid layer number", iNodeTypeId));
   8291         return false;
   8292     }
   8293 
   8294     iVideoEncodeParam.iBitRate[aLayer] = aBitRate;
   8295     return true;
   8296 }
   8297 
   8298 ////////////////////////////////////////////////////////////////////////////
   8299 OSCL_EXPORT_REF bool PVMFOMXEncNode::SetOutputFrameSize(uint32 aLayer, uint32 aWidth, uint32 aHeight)
   8300 {
   8301     switch (iInterfaceState)
   8302     {
   8303         case EPVMFNodeStarted:
   8304         case EPVMFNodePaused:
   8305             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   8306                             (0, "PVMFOMXEncNode-%s::SetOutputFrameSize: Error iInterfaceState=%d", iNodeTypeId, iInterfaceState));
   8307             return false;
   8308 
   8309         default:
   8310             break;
   8311     }
   8312 
   8313     if ((int32)aLayer >= iVideoEncodeParam.iNumLayer)
   8314     {
   8315         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   8316                         (0, "PVMFOMXEncNode-%s::SetOutputFrameSize: Error Invalid layer number", iNodeTypeId));
   8317         return false;
   8318     }
   8319 
   8320     iVideoEncodeParam.iFrameWidth[aLayer] = aWidth;
   8321     iVideoEncodeParam.iFrameHeight[aLayer] = aHeight;
   8322     return true;
   8323 }
   8324 
   8325 ////////////////////////////////////////////////////////////////////////////
   8326 OSCL_EXPORT_REF bool PVMFOMXEncNode::SetOutputFrameRate(uint32 aLayer, OsclFloat aFrameRate)
   8327 {
   8328     switch (iInterfaceState)
   8329     {
   8330         case EPVMFNodeStarted:
   8331         case EPVMFNodePaused:
   8332             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   8333                             (0, "PVMFOMXEncNode-%s::SetOutputFrameRate: Error iInterfaceState=%d", iInterfaceState));
   8334             return false;
   8335 
   8336         default:
   8337             break;
   8338     }
   8339 
   8340     if ((int32)aLayer >= iVideoEncodeParam.iNumLayer)
   8341     {
   8342         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   8343                         (0, "PVMFOMXEncNode-%s::SetOutputFrameRate: Error Invalid layer number", iNodeTypeId));
   8344         return false;
   8345     }
   8346 
   8347     iVideoEncodeParam.iFrameRate[aLayer] = OSCL_STATIC_CAST(float, aFrameRate);
   8348     return true;
   8349 }
   8350 
   8351 ////////////////////////////////////////////////////////////////////////////
   8352 OSCL_EXPORT_REF bool PVMFOMXEncNode::SetSegmentTargetSize(uint32 aLayer, uint32 aSizeBytes)
   8353 {
   8354     OSCL_UNUSED_ARG(aLayer);
   8355 
   8356     switch (iInterfaceState)
   8357     {
   8358         case EPVMFNodeStarted:
   8359         case EPVMFNodePaused:
   8360             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   8361                             (0, "PVMFOMXEncNode-%s::SetSegmentTargetSize: Error iInterfaceState=%d", iNodeTypeId, iInterfaceState));
   8362             return false;
   8363 
   8364         default:
   8365             break;
   8366     }
   8367 
   8368     iVideoEncodeParam.iPacketSize = aSizeBytes;
   8369     return true;
   8370 }
   8371 
   8372 ////////////////////////////////////////////////////////////////////////////
   8373 OSCL_EXPORT_REF bool PVMFOMXEncNode::SetRateControlType(uint32 aLayer, PVMFVENRateControlType aRateControl)
   8374 {
   8375     OSCL_UNUSED_ARG(aLayer);
   8376 
   8377     switch (iInterfaceState)
   8378     {
   8379         case EPVMFNodeStarted:
   8380         case EPVMFNodePaused:
   8381             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   8382                             (0, "PVMFOMXEncNode-%s::SetRateControlType: Error iInterfaceState=%d", iNodeTypeId, iInterfaceState));
   8383             return false;
   8384 
   8385         default:
   8386             break;
   8387     }
   8388 
   8389     iVideoEncodeParam.iRateControlType = aRateControl;
   8390     return true;
   8391 }
   8392 
   8393 ////////////////////////////////////////////////////////////////////////////
   8394 OSCL_EXPORT_REF bool PVMFOMXEncNode::SetDataPartitioning(bool aDataPartitioning)
   8395 {
   8396     switch (iInterfaceState)
   8397     {
   8398         case EPVMFNodeStarted:
   8399         case EPVMFNodePaused:
   8400             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   8401                             (0, "PVMFOMXEncNode-%s::SetDataPartitioning: Error iInterfaceState=%d", iNodeTypeId, iInterfaceState));
   8402             return false;
   8403 
   8404         default:
   8405             break;
   8406     }
   8407 
   8408     iVideoEncodeParam.iDataPartitioning = aDataPartitioning;
   8409 
   8410     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
   8411                     (0, "PVMFOMXEncNode-%s::SetDataPartitioning Called", iNodeTypeId));
   8412 
   8413     return true;
   8414 }
   8415 
   8416 ////////////////////////////////////////////////////////////////////////////
   8417 OSCL_EXPORT_REF bool PVMFOMXEncNode::SetIFrameInterval(uint32 aIFrameInterval)
   8418 {
   8419     switch (iInterfaceState)
   8420     {
   8421         case EPVMFNodeStarted:
   8422         case EPVMFNodePaused:
   8423             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   8424                             (0, "PVMFOMXEncNode-%s::SetIFrameInterval: Error iInterfaceState=%d", iNodeTypeId, iInterfaceState));
   8425             return false;
   8426 
   8427         default:
   8428             break;
   8429     }
   8430 
   8431     iVideoEncodeParam.iIFrameInterval = aIFrameInterval;
   8432     return true;
   8433 }
   8434 ////////////////////////////////////////////////////////////////////////////
   8435 OSCL_EXPORT_REF bool PVMFOMXEncNode::SetSceneDetection(bool aSCD)
   8436 {
   8437     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   8438                     (0, "PVMFOMXEncNode-%s::SetSceneDetection to %d", iNodeTypeId, aSCD));
   8439 
   8440 
   8441     switch (iInterfaceState)
   8442     {
   8443         case EPVMFNodeStarted:
   8444         case EPVMFNodePaused:
   8445             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   8446                             (0, "PVMFOMXEncEncNode-%s::SetIFrameInterval: Error iInterfaceState=%d", iNodeTypeId, iInterfaceState));
   8447             return false;
   8448 
   8449         default:
   8450             break;
   8451     }
   8452 
   8453     iVideoEncodeParam.iSceneDetection = aSCD;
   8454 
   8455     return true;
   8456 }
   8457 ////////////////////////////////////////////////////////////////////////////
   8458 OSCL_EXPORT_REF bool PVMFOMXEncNode::SetRVLC(bool aRVLC)
   8459 {
   8460 
   8461     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   8462                     (0, "PVMFOMXEncNode-%s::SetRVLC", iNodeTypeId));
   8463 
   8464     switch (iInterfaceState)
   8465     {
   8466         case EPVMFNodeStarted:
   8467         case EPVMFNodePaused:
   8468             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   8469                             (0, "PVMFOMXEncEncNode-%s::SetRVLC: Error iInterfaceState=%d", iNodeTypeId, iInterfaceState));
   8470             return false;
   8471 
   8472         default:
   8473             break;
   8474     }
   8475 
   8476     iVideoEncodeParam.iRVLCEnable = aRVLC;
   8477 
   8478     return true;
   8479 }
   8480 
   8481 ////////////////////////////////////////////////////////////////////////////
   8482 OSCL_EXPORT_REF bool PVMFOMXEncNode::GetVolHeader(OsclRefCounterMemFrag& aVolHeader)
   8483 {
   8484     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   8485                     (0, "PVMFOMXEncNode-%s::GetVolHeader", iNodeTypeId));
   8486 
   8487 #ifdef _TEST_AE_ERROR_HANDLING
   8488     if (iErrorConfigHeader)
   8489     {
   8490         iInterfaceState = EPVMFNodeError;
   8491     }
   8492 #endif
   8493     switch (iInterfaceState)
   8494     {
   8495         case EPVMFNodeInitialized:
   8496         case EPVMFNodePrepared:
   8497         case EPVMFNodeStarted:
   8498         case EPVMFNodePaused:
   8499             break;
   8500 
   8501         default:
   8502             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   8503                             (0, "PVMFOMXEncNode-%s::GetVolHeader: Error - Wrong state", iNodeTypeId));
   8504             return false;
   8505     }
   8506 
   8507     if (iOutFormat != PVMF_MIME_M4V)
   8508     {
   8509         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   8510                         (0, "PVMFOMXEncNode-%s::GetVolHeader: Error - VOL header only for M4V encode", iNodeTypeId));
   8511         return false;
   8512     }
   8513 
   8514     uint8 *ptr = (uint8 *) iVolHeader.getMemFragPtr();
   8515     //If data partioning mode
   8516     if (iVideoEncodeParam.iDataPartitioning == true)
   8517     {
   8518         ptr[iVolHeader.getMemFragSize() - 1] = 0x8F;
   8519     }
   8520     //else combined mode
   8521     else
   8522     {
   8523         ptr[iVolHeader.getMemFragSize() - 1] = 0x1F;
   8524     }
   8525 
   8526     aVolHeader = iVolHeader;
   8527 
   8528     return true;
   8529 }
   8530 
   8531 ////////////////////////////////////////////////////////////////////////////
   8532 OSCL_EXPORT_REF bool PVMFOMXEncNode::RequestIFrame()
   8533 {
   8534     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   8535                     (0, "PVMFOMXEncNode-%s::RequestIFrame", iNodeTypeId));
   8536 
   8537     switch (iInterfaceState)
   8538     {
   8539         case EPVMFNodeStarted:
   8540         case EPVMFNodePaused:
   8541             break;
   8542         default:
   8543             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   8544                             (0, "PVMFOMXEncNode-%s::RequestIFrame: Error - Wrong state", iNodeTypeId));
   8545             return false;
   8546     }
   8547 
   8548     return true;
   8549 }
   8550 
   8551 ////////////////////////////////////////////////////////////////////////////
   8552 OSCL_EXPORT_REF bool PVMFOMXEncNode::SetCodec(PVMFFormatType aCodec)
   8553 {
   8554     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   8555                     (0, "PVMFOMXEncNode-%s::SetCodec %s", iNodeTypeId, aCodec.getMIMEStrPtr()));
   8556 
   8557     if (SetCodecType(aCodec) == PVMFSuccess)
   8558     {
   8559         return true;
   8560     }
   8561     else
   8562     {
   8563         return false;
   8564     }
   8565 
   8566 }
   8567 
   8568 
   8569 
   8570 PVMFStatus PVMFOMXEncNode::SetCodecType(PVMFFormatType aCodec)
   8571 {
   8572     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   8573                     (0, "PVMFOMXEncNode-%s::SetCodecType: aCodec=%s", iNodeTypeId, aCodec.getMIMEStrPtr()));
   8574 
   8575     switch (iInterfaceState)
   8576     {
   8577         case EPVMFNodeStarted:
   8578         case EPVMFNodePaused:
   8579             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   8580                             (0, "PVMFOMXEncNode-%s::SetCodecType: Error iInterfaceState=%d", iNodeTypeId, iInterfaceState));
   8581 
   8582             return PVMFErrInvalidState;
   8583         default:
   8584             break;
   8585     }
   8586 
   8587     if (aCodec == PVMF_MIME_H2631998)
   8588     {
   8589         iOutFormat = PVMF_MIME_H2631998;
   8590     }
   8591     else if (aCodec == PVMF_MIME_H2632000)
   8592     {
   8593         iOutFormat = PVMF_MIME_H2632000;
   8594     }
   8595     else if (aCodec == PVMF_MIME_M4V)
   8596     {
   8597         iOutFormat = PVMF_MIME_M4V;
   8598     }
   8599     else if (aCodec == PVMF_MIME_H264_VIDEO_RAW ||
   8600              aCodec == PVMF_MIME_H264_VIDEO_MP4)
   8601     {
   8602         iOutFormat = aCodec;
   8603     }
   8604     else if (aCodec == PVMF_MIME_AMR_IETF ||
   8605              aCodec == PVMF_MIME_AMR_IF2 ||
   8606              aCodec == PVMF_MIME_AMRWB_IETF)
   8607     {
   8608         iOutFormat = aCodec;
   8609     }
   8610     else if (aCodec == PVMF_MIME_ADTS ||
   8611              aCodec == PVMF_MIME_ADIF ||
   8612              aCodec == PVMF_MIME_MPEG4_AUDIO)
   8613     {
   8614         iOutFormat = aCodec;
   8615     }
   8616     else
   8617     {
   8618         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   8619                         (0, "PVMFOMXEncNode-%s::SetCodecType: ERROR Unsupported format aCodec=%s", iNodeTypeId, aCodec.getMIMEStrPtr()));
   8620 
   8621         return PVMFErrNotSupported;
   8622     }
   8623 
   8624     return PVMFSuccess;
   8625 }
   8626 
   8627 ////////////////////////////////////////////////////////////////////////////
   8628 OSCL_EXPORT_REF bool PVMFOMXEncNode::SetFSIParam(uint8* aFSIBuff, int aFSIBuffLength)
   8629 {
   8630 
   8631 
   8632     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   8633                     (0, "PVMFOMXEncNode-%s::SetFSIParam: Error- NOT IMPLEMENTED", iNodeTypeId));
   8634     OSCL_UNUSED_ARG(aFSIBuff);
   8635     OSCL_UNUSED_ARG(aFSIBuffLength);
   8636 
   8637     return true;
   8638 }
   8639 
   8640 
   8641 
   8642 // The input format methods are called from the port
   8643 ////////////////////////////////////////////////////////////////////////////
   8644 PVMFStatus PVMFOMXEncNode::SetInputFormat(PVMFFormatType aFormat)
   8645 {
   8646     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   8647                     (0, "PVMFOMXEncNode-%s::SetInputFormat: aFormat=%s", iNodeTypeId, aFormat.getMIMEStrPtr()));
   8648 
   8649     switch (iInterfaceState)
   8650     {
   8651         case EPVMFNodeStarted:
   8652         case EPVMFNodePaused:
   8653             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   8654                             (0, "PVMFOMXEncNode-%s::SetInputFormat: Error - iInterfaceState=%d", iNodeTypeId, iInterfaceState));
   8655             return PVMFErrInvalidState;
   8656         default:
   8657             break;
   8658     }
   8659 
   8660     iInFormat = aFormat;
   8661     return PVMFSuccess;
   8662 }
   8663 
   8664 ////////////////////////////////////////////////////////////////////////////
   8665 PVMFStatus PVMFOMXEncNode::SetInputFrameSize(uint32 aWidth, uint32 aHeight, uint8 aFrmOrient)
   8666 {
   8667     switch (iInterfaceState)
   8668     {
   8669         case EPVMFNodeStarted:
   8670         case EPVMFNodePaused:
   8671             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   8672                             (0, "PVMFOMXEncNode-%s::SetInputFrameSize: Error iInterfaceState=%d", iNodeTypeId, iInterfaceState));
   8673             return false;
   8674         default:
   8675             break;
   8676     }
   8677 
   8678     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   8679                     (0, "PVMFOMXEncNode-%s::SetInputFrameSize: aWidth=%d, aHeight=%d, aFrmOrient=%d", iNodeTypeId, aWidth, aHeight, aFrmOrient));
   8680 
   8681     iVideoInputFormat.iFrameWidth = aWidth;
   8682     iVideoInputFormat.iFrameHeight = aHeight;
   8683     iVideoInputFormat.iFrameOrientation = aFrmOrient;
   8684     return true;
   8685 }
   8686 
   8687 ////////////////////////////////////////////////////////////////////////////
   8688 PVMFStatus PVMFOMXEncNode::SetInputFrameRate(OsclFloat aFrameRate)
   8689 {
   8690     switch (iInterfaceState)
   8691     {
   8692         case EPVMFNodeStarted:
   8693         case EPVMFNodePaused:
   8694             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   8695                             (0, "PVMFOMXEncNode-%s::SetInputFrameRate: Error iInterfaceState=%d", iNodeTypeId, iInterfaceState));
   8696             return false;
   8697         default:
   8698             break;
   8699     }
   8700 
   8701     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   8702                     (0, "PVMFOMXEncNode-%s::SetInputFrameRate: aFrameRate=%d", iNodeTypeId, aFrameRate));
   8703 
   8704     iVideoInputFormat.iFrameRate = OSCL_STATIC_CAST(float, aFrameRate);
   8705     iVideoEncodeParam.iNoFrameSkip = iVideoEncodeParam.iNoCurrentSkip = false;
   8706     return true;
   8707 }
   8708 
   8709 ////////////////////////////////////////////////////////////////////////////
   8710 PVMFFormatType PVMFOMXEncNode::GetCodecType()
   8711 {
   8712     return iOutFormat;
   8713 }
   8714 
   8715 ////////////////////////////////////////////////////////////////////////////
   8716 // DV: Note - for video - there is an uint32 arg
   8717 uint32 PVMFOMXEncNode::GetOutputBitRate(uint32 aLayer)
   8718 {
   8719     if ((int32)aLayer >= iVideoEncodeParam.iNumLayer)
   8720     {
   8721         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   8722                         (0, "PVMFOMXEncNode-%s::GetOutputBitRate: Error - Invalid layer number", iNodeTypeId));
   8723         return 0;
   8724     }
   8725 
   8726     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   8727                     (0, "PVMFOMXEncNode-%s::GetOutputBitRate: =%d", iNodeTypeId, iVideoEncodeParam.iBitRate[aLayer]));
   8728 
   8729     return iVideoEncodeParam.iBitRate[aLayer];
   8730 }
   8731 
   8732 ////////////////////////////////////////////////////////////////////////////
   8733 OsclFloat PVMFOMXEncNode::GetOutputFrameRate(uint32 aLayer)
   8734 {
   8735     if ((int32)aLayer >= iVideoEncodeParam.iNumLayer)
   8736     {
   8737         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   8738                         (0, "PVMFOMXEncNode-%s::GetOutputFrameRate: Error Invalid layer number", iNodeTypeId));
   8739         return 0;
   8740     }
   8741 
   8742     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   8743                     (0, "PVMFOMXEncNode-%s::GetOutputFrameRate: =%f", iNodeTypeId, (OsclFloat) iVideoEncodeParam.iFrameRate[aLayer]));
   8744 
   8745     return (OsclFloat)iVideoEncodeParam.iFrameRate[aLayer];
   8746 }
   8747 
   8748 ////////////////////////////////////////////////////////////////////////////
   8749 PVMFStatus PVMFOMXEncNode::GetOutputFrameSize(uint32 aLayer, uint32& aWidth, uint32& aHeight)
   8750 {
   8751     if ((int32)aLayer >= iVideoEncodeParam.iNumLayer)
   8752     {
   8753         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   8754                         (0, "PVMFOMXEncNode-%s::GetOutputFrameSize: Error Invalid layer number", iNodeTypeId));
   8755         return PVMFFailure;
   8756     }
   8757 
   8758     aWidth = iVideoEncodeParam.iFrameWidth[aLayer];
   8759     aHeight = iVideoEncodeParam.iFrameHeight[aLayer];
   8760     return PVMFSuccess;
   8761 }
   8762 
   8763 ////////////////////////////////////////////////////////////////////////////
   8764 uint32 PVMFOMXEncNode::GetIFrameInterval()
   8765 {
   8766     return iVideoEncodeParam.iIFrameInterval;
   8767 }
   8768 /////////////////////////////////////////////////////////////////////////////
   8769 
   8770 uint32 PVMFOMXEncNode::GetOutputSamplingRate()
   8771 {
   8772 
   8773 
   8774     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   8775                     (0, "PVMFOMXEncNode-%s::GetOutputSamplingRate: =%d", iNodeTypeId, iAudioEncodeParam.iOutputSamplingRate));
   8776 
   8777     return (uint32) iAudioEncodeParam.iOutputSamplingRate;
   8778 }
   8779 /////////////////////////////////////////////////////////////////////////////
   8780 
   8781 uint32 PVMFOMXEncNode::GetOutputNumChannels()
   8782 {
   8783 
   8784 
   8785     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   8786                     (0, "PVMFOMXEncNode-%s::GetOutputNumChannels: =%d", iNodeTypeId, iAudioEncodeParam.iOutputNumChannels));
   8787 
   8788     return (uint32) iAudioEncodeParam.iOutputNumChannels;
   8789 }
   8790 
   8791 /////////////////////////AMRENCInterfaceExtension //////////////////////////
   8792 OSCL_EXPORT_REF PVMFStatus PVMFOMXEncNode::SetOutputBitRate(PVMF_GSMAMR_Rate aBitRate)
   8793 {
   8794     // this particular API is used only for AMR (NB or WB)
   8795     // do some error checking - make sure that NB (i.e. WB) bitrates correspond to NB (i.e. WB) codec
   8796     if ((iOutFormat == PVMF_MIME_AMR_IF2) ||
   8797             (iOutFormat == PVMF_MIME_AMR_IETF)
   8798        )
   8799     {
   8800 
   8801         switch (aBitRate)
   8802         {
   8803             case GSM_AMR_4_75:
   8804             case GSM_AMR_5_15:
   8805             case GSM_AMR_5_90:
   8806             case GSM_AMR_6_70:
   8807             case GSM_AMR_7_40:
   8808             case GSM_AMR_7_95:
   8809             case GSM_AMR_10_2:
   8810             case GSM_AMR_12_2:
   8811 
   8812                 iAudioEncodeParam.iAMRBitrate = aBitRate;
   8813 
   8814                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   8815                                 (0, "PVMFOMXEncNode-%s::SetOutputBitRate() OK - %d", iNodeTypeId, aBitRate));
   8816 
   8817                 return PVMFSuccess;
   8818 
   8819             case GSM_AMR_6_60: // AMR WB bitrates start here
   8820             case GSM_AMR_8_85:
   8821             case GSM_AMR_12_65:
   8822             case GSM_AMR_14_25:
   8823             case GSM_AMR_15_85:
   8824             case GSM_AMR_18_25:
   8825             case GSM_AMR_19_85:
   8826             case GSM_AMR_23_05:
   8827             case GSM_AMR_23_85:
   8828 
   8829                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   8830                                 (0, "PVMFOMXEncNode-%s::SetOutputBitRate() failed - %d", iNodeTypeId, aBitRate));
   8831 
   8832                 return PVMFFailure;
   8833 
   8834             default:
   8835 
   8836                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   8837                                 (0, "PVMFOMXEncNode-%s::SetOutputBitRate() failed - %d", iNodeTypeId, aBitRate));
   8838 
   8839                 return PVMFFailure;
   8840         }
   8841     }
   8842 
   8843     if (iOutFormat == PVMF_MIME_AMRWB_IETF)
   8844     {
   8845         switch (aBitRate)
   8846         {
   8847             case GSM_AMR_4_75:
   8848             case GSM_AMR_5_15:
   8849             case GSM_AMR_5_90:
   8850             case GSM_AMR_6_70:
   8851             case GSM_AMR_7_40:
   8852             case GSM_AMR_7_95:
   8853             case GSM_AMR_10_2:
   8854             case GSM_AMR_12_2:
   8855 
   8856                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   8857                                 (0, "PVMFOMXEncNode-%s::SetOutputBitRate() failed - %d", iNodeTypeId, aBitRate));
   8858 
   8859                 return PVMFFailure;
   8860 
   8861             case GSM_AMR_6_60: // AMR WB bitrates start here
   8862             case GSM_AMR_8_85:
   8863             case GSM_AMR_12_65:
   8864             case GSM_AMR_14_25:
   8865             case GSM_AMR_15_85:
   8866             case GSM_AMR_18_25:
   8867             case GSM_AMR_19_85:
   8868             case GSM_AMR_23_05:
   8869             case GSM_AMR_23_85:
   8870 
   8871                 iAudioEncodeParam.iAMRBitrate = aBitRate;
   8872                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   8873                                 (0, "PVMFOMXEncNode-%s::SetOutputBitRate() OK - %d", iNodeTypeId, aBitRate));
   8874 
   8875                 return PVMFSuccess;
   8876 
   8877             default:
   8878 
   8879                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   8880                                 (0, "PVMFOMXEncNode-%s::SetOutputBitRate() failed - %d", iNodeTypeId, aBitRate));
   8881 
   8882                 return PVMFFailure;
   8883         }
   8884     }
   8885 
   8886     return PVMFSuccess;
   8887 }
   8888 
   8889 ////////////////////////////////////////////////////////////////////////////
   8890 OSCL_EXPORT_REF PVMFStatus PVMFOMXEncNode::SetMaxNumOutputFramesPerBuffer(uint32 aNumOutputFrames)
   8891 {
   8892     iAudioEncodeParam.iMaxNumOutputFramesPerBuffer = aNumOutputFrames;
   8893     return PVMFSuccess;
   8894 }
   8895 
   8896 ////////////////////////////////////////////////////////////////////////////
   8897 OSCL_EXPORT_REF PVMFStatus PVMFOMXEncNode::SetOutputBitRate(uint32 aBitRate)
   8898 {
   8899     // this API is used for Non-AMR codecs
   8900     iAudioEncodeParam.iOutputBitrate = aBitRate;
   8901     return PVMFSuccess;
   8902 }
   8903 
   8904 ////////////////////////////////////////////////////////////////////////////
   8905 OSCL_EXPORT_REF PVMFStatus PVMFOMXEncNode::SetOutputNumChannel(uint32 aNumChannels)
   8906 {
   8907 
   8908     iAudioEncodeParam.iOutputNumChannels = aNumChannels;
   8909     return PVMFSuccess;
   8910 }
   8911 
   8912 ////////////////////////////////////////////////////////////////////////////
   8913 OSCL_EXPORT_REF PVMFStatus PVMFOMXEncNode::SetOutputSamplingRate(uint32 aSamplingRate)
   8914 {
   8915     iAudioEncodeParam.iOutputSamplingRate = aSamplingRate;
   8916     return PVMFSuccess;
   8917 }
   8918 
   8919 
   8920 ////////////////////////////////////////////////////////////////////////////
   8921 PVMFStatus PVMFOMXEncNode::SetInputSamplingRate(uint32 aSamplingRate)
   8922 {
   8923     // do some error checking - make sure the input sampling rate is 8khz (i.e. 16khz) for AMRNB (i.e. WB)
   8924     if (((iOutFormat == PVMF_MIME_AMR_IF2) ||
   8925             (iOutFormat == PVMF_MIME_AMR_IETF)) &&
   8926             (aSamplingRate != 8000)
   8927        )
   8928     {
   8929         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   8930                         (0, "PVMFOMXEncNode-%s::SetInputBitsSamplingRate() failed - %d", iNodeTypeId, aSamplingRate));
   8931 
   8932         return PVMFFailure;
   8933     }
   8934 
   8935     if ((iOutFormat == PVMF_MIME_AMRWB_IETF) && (aSamplingRate != 16000))
   8936     {
   8937         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   8938                         (0, "PVMFOMXEncNode-%s::SetInputBitsSamplingRate() failed - %d", iNodeTypeId, aSamplingRate));
   8939 
   8940         return PVMFFailure;
   8941     }
   8942 
   8943     iAudioInputFormat.iInputSamplingRate = aSamplingRate;
   8944 
   8945     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   8946                     (0, "PVMFOMXEncNode-%s::SetInputBitsSamplingRate() OK setting OutputSamplingRate as well - %d", iNodeTypeId, aSamplingRate));
   8947 
   8948     // set output as well
   8949     iAudioEncodeParam.iOutputSamplingRate = aSamplingRate;
   8950     return PVMFSuccess;
   8951 }
   8952 
   8953 ////////////////////////////////////////////////////////////////////////////
   8954 PVMFStatus PVMFOMXEncNode::SetInputBitsPerSample(uint32 aBitsPerSample)
   8955 {
   8956     if (aBitsPerSample != 16)
   8957     {
   8958         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   8959                         (0, "PVMFOMXEncNode-%s::SetInputBitsPerSample() failed - %d", iNodeTypeId, aBitsPerSample));
   8960 
   8961         return PVMFErrNotSupported;
   8962     }
   8963 
   8964     iAudioInputFormat.iInputBitsPerSample = aBitsPerSample;
   8965 
   8966     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   8967                     (0, "PVMFOMXEncNode-%s::SetInputBitsPerSample() OK - %d", iNodeTypeId, aBitsPerSample));
   8968 
   8969     return PVMFSuccess;
   8970 }
   8971 
   8972 
   8973 ////////////////////////////////////////////////////////////////////////////
   8974 PVMFStatus PVMFOMXEncNode::SetInputNumChannels(uint32 aNumChannels)
   8975 {
   8976     // do some error checking - make sure the number of INPUT channels is 1 for AMR (NB or WB)
   8977 
   8978     if (((iOutFormat == PVMF_MIME_AMR_IF2) ||
   8979             (iOutFormat == PVMF_MIME_AMR_IETF) ||
   8980             (iOutFormat == PVMF_MIME_AMRWB_IETF)) &&
   8981             (aNumChannels > 1)
   8982        )
   8983     {
   8984         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   8985                         (0, "PVMFOMXEncNode-%s::SetInputNumChannels() failed - %d", iNodeTypeId, aNumChannels));
   8986         return PVMFFailure;
   8987     }
   8988 
   8989     iAudioInputFormat.iInputNumChannels = aNumChannels;
   8990 
   8991     //set output as well
   8992     iAudioEncodeParam.iOutputNumChannels = aNumChannels;
   8993     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   8994                     (0, "PVMFOMXEncNode-%s::SetInputNumChannels() OK - %d", iNodeTypeId, aNumChannels));
   8995 
   8996     return PVMFSuccess;
   8997 }
   8998 
   8999 ////////////////////////////////////////////////////////////////////////////
   9000 uint32 PVMFOMXEncNode::GetOutputBitRate()
   9001 {
   9002     if ((iOutFormat == PVMF_MIME_AMR_IF2) ||
   9003             (iOutFormat == PVMF_MIME_AMR_IETF) ||
   9004             (iOutFormat == PVMF_MIME_AMRWB_IETF)
   9005        )
   9006     {
   9007 
   9008         switch (iAudioEncodeParam.iAMRBitrate)
   9009         {
   9010             case GSM_AMR_4_75:
   9011                 return 4750;
   9012             case GSM_AMR_5_15:
   9013                 return 5150;
   9014             case GSM_AMR_5_90:
   9015                 return 5900;
   9016             case GSM_AMR_6_70:
   9017                 return 6700;
   9018             case GSM_AMR_7_40:
   9019                 return 7400;
   9020             case GSM_AMR_7_95:
   9021                 return 7950;
   9022             case GSM_AMR_10_2:
   9023                 return 10200;
   9024             case GSM_AMR_12_2:
   9025                 return 12200;
   9026             case GSM_AMR_6_60: // AMR WB bitrates start here
   9027                 return 6600;
   9028             case GSM_AMR_8_85:
   9029                 return 8850;
   9030             case GSM_AMR_12_65:
   9031                 return 12650;
   9032             case GSM_AMR_14_25:
   9033                 return 14250;
   9034             case GSM_AMR_15_85:
   9035                 return 15850;
   9036             case GSM_AMR_18_25:
   9037                 return 18250;
   9038             case GSM_AMR_19_85:
   9039                 return 19850;
   9040             case GSM_AMR_23_05:
   9041                 return 23050;
   9042             case GSM_AMR_23_85:
   9043                 return 23850;
   9044             default:
   9045                 return 0;
   9046         }
   9047     }
   9048     else
   9049     {
   9050         return iAudioEncodeParam.iOutputBitrate;
   9051     }
   9052 }
   9053 
   9054 
   9055 ///////////////////////// FROM CAP CONFIG IN VIDEO ENC NODE ////////////////////
   9056 PVMFStatus PVMFOMXEncNode::GetConfigParameter(PvmiKvp*& aParameters, int& aNumParamElements, int32 aIndex, PvmiKvpAttr aReqattr)
   9057 {
   9058     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::GetConfigParameter() In", iNodeTypeId));
   9059 
   9060     aNumParamElements = 0;
   9061 
   9062     // Allocate memory for the KVP
   9063     aParameters = (PvmiKvp*)oscl_malloc(sizeof(PvmiKvp));
   9064     if (NULL == aParameters)
   9065     {
   9066         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::GetConfigParameter() Memory allocation for KVP failed", iNodeTypeId));
   9067         return PVMFErrNoMemory;
   9068     }
   9069     oscl_memset(aParameters, 0, sizeof(PvmiKvp));
   9070     // Allocate memory for the key string in KVP
   9071     PvmiKeyType memblock = (PvmiKeyType)oscl_malloc(PVOMXENCNODECONFIG_KEYSTRING_SIZE * sizeof(char));
   9072     if (NULL == memblock)
   9073     {
   9074         oscl_free(aParameters);
   9075         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::GetConfigParameter() Memory allocation for key string failed", iNodeTypeId));
   9076         return PVMFErrNoMemory;
   9077     }
   9078     oscl_strset(memblock, 0, PVOMXENCNODECONFIG_KEYSTRING_SIZE * sizeof(char));
   9079     // Assign the key string buffer to KVP
   9080     aParameters[0].key = memblock;
   9081 
   9082     // Copy the key string
   9083     if (iInFormat == PVMF_MIME_PCM16)
   9084     {
   9085         // Copy the key string
   9086         oscl_strncat(aParameters[0].key, _STRLIT_CHAR("x-pvmf/encoder/audio/"), 21);
   9087         oscl_strncat(aParameters[0].key, PVOMXEncNodeConfigBaseKeys[aIndex].iString, oscl_strlen(PVOMXEncNodeConfigBaseKeys[aIndex].iString));
   9088         oscl_strncat(aParameters[0].key, _STRLIT_CHAR(";type=value;valtype="), 20);
   9089     }
   9090     else
   9091     {
   9092         oscl_strncat(aParameters[0].key, _STRLIT_CHAR("x-pvmf/encoder/video/"), 21);
   9093         oscl_strncat(aParameters[0].key, PVOMXEncNodeConfigBaseKeys[aIndex].iString, oscl_strlen(PVOMXEncNodeConfigBaseKeys[aIndex].iString));
   9094         oscl_strncat(aParameters[0].key, _STRLIT_CHAR(";type=value;valtype="), 20);
   9095     }
   9096     switch (PVOMXEncNodeConfigBaseKeys[aIndex].iValueType)
   9097     {
   9098         case PVMI_KVPVALTYPE_BITARRAY32:
   9099             oscl_strncat(aParameters[0].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_BITARRAY32_STRING), oscl_strlen(PVMI_KVPVALTYPE_BITARRAY32_STRING));
   9100             break;
   9101 
   9102         case PVMI_KVPVALTYPE_KSV:
   9103             oscl_strncat(aParameters[0].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_KSV_STRING), oscl_strlen(PVMI_KVPVALTYPE_KSV_STRING));
   9104             break;
   9105 
   9106         case PVMI_KVPVALTYPE_BOOL:
   9107             oscl_strncat(aParameters[0].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_BOOL_STRING), oscl_strlen(PVMI_KVPVALTYPE_BOOL_STRING));
   9108             break;
   9109 
   9110         case PVMI_KVPVALTYPE_INT32:
   9111             if (PVMI_KVPATTR_CUR == aReqattr)
   9112             {
   9113                 oscl_strncat(aParameters[0].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_INT32_STRING), oscl_strlen(PVMI_KVPVALTYPE_RANGE_UINT32_STRING));
   9114             }
   9115             break;
   9116         case PVMI_KVPVALTYPE_UINT32:
   9117         default:
   9118             if (PVMI_KVPATTR_CAP == aReqattr)
   9119             {
   9120                 oscl_strncat(aParameters[0].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_RANGE_UINT32_STRING), oscl_strlen(PVMI_KVPVALTYPE_RANGE_UINT32_STRING));
   9121             }
   9122             else
   9123             {
   9124                 oscl_strncat(aParameters[0].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_UINT32_STRING), oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING));
   9125             }
   9126             break;
   9127     }
   9128     aParameters[0].key[PVOMXENCNODECONFIG_KEYSTRING_SIZE-1] = 0;
   9129 
   9130     // Copy the requested info
   9131     switch (aIndex)
   9132     {
   9133 
   9134         case SAMPLING_RATE: // "sampling_rate"
   9135             if (PVMI_KVPATTR_CUR == aReqattr)
   9136             {
   9137                 // get the parameter here
   9138                 aParameters[0].value.uint32_value = iAudioInputFormat.iInputSamplingRate;
   9139 
   9140             }
   9141             else if (PVMI_KVPATTR_DEF == aReqattr)
   9142             {
   9143                 // Return default
   9144                 aParameters[0].value.uint32_value = PVMF_AMRENC_DEFAULT_SAMPLING_RATE;
   9145 
   9146             }
   9147             else
   9148             {
   9149                 // Return capability
   9150             }
   9151             break;
   9152 
   9153         case CHANNELS:  // "channels"
   9154 
   9155             if (PVMI_KVPATTR_CUR == aReqattr)
   9156             {
   9157                 // get the par
   9158                 aParameters[0].value.uint32_value = iAudioInputFormat.iInputNumChannels;
   9159             }
   9160             else if (PVMI_KVPATTR_DEF == aReqattr)
   9161             {
   9162                 // Return default
   9163                 aParameters[0].value.uint32_value = PVMF_AMRENC_DEFAULT_NUM_CHANNELS;
   9164             }
   9165             else
   9166             {
   9167                 // Return capability
   9168             }
   9169             break;
   9170 
   9171         case ENCODING_MODE: // "encoding_mode"
   9172             if (PVMI_KVPATTR_CUR == aReqattr)
   9173             {
   9174                 // Return current value
   9175                 aParameters[0].value.uint32_value = iVideoEncodeParam.iEncMode;
   9176             }
   9177             else if (PVMI_KVPATTR_DEF == aReqattr)
   9178             {
   9179                 // Return default
   9180                 aParameters[0].value.uint32_value = EI_ENCMODE_RECORDER;//default setting
   9181             }
   9182             else
   9183             {
   9184                 // Return capability
   9185             }
   9186             break;
   9187 
   9188 #ifdef _TEST_AE_ERROR_HANDLING
   9189         case ERROR_START_INIT://error_start_init
   9190             if (PVMI_KVPATTR_CUR == aReqattr)
   9191             {
   9192                 // Return current value
   9193                 aParameters[0].value.bool_value = iErrorHandlingInit;
   9194             }
   9195             else if (PVMI_KVPATTR_DEF == aReqattr)
   9196             {
   9197                 // Return default
   9198                 aParameters[0].value.bool_value = true;
   9199             }
   9200             else
   9201             {
   9202                 // Return capability
   9203             }
   9204             break;
   9205         case ERROR_ENCODE://error_encode
   9206             if (PVMI_KVPATTR_CUR == aReqattr)
   9207             {
   9208                 // Return current value
   9209                 aParameters[0].value.uint32_value = iErrorHandlingEncodeCount;
   9210             }
   9211             else if (PVMI_KVPATTR_DEF == aReqattr)
   9212             {
   9213                 // Return default
   9214                 aParameters[0].value.uint32_value = 1;
   9215             }
   9216             else
   9217             {
   9218                 // Return capability
   9219             }
   9220             break;
   9221 
   9222 #endif
   9223 
   9224         default:
   9225             // Invalid index
   9226             oscl_free(aParameters[0].key);
   9227             oscl_free(aParameters);
   9228             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::GetConfigParameter() Invalid index to video enc node parameter", iNodeTypeId));
   9229             return PVMFErrNotSupported;
   9230     }
   9231 
   9232     aNumParamElements = 1;
   9233 
   9234     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::GetConfigParameter() Out", iNodeTypeId));
   9235     return PVMFSuccess;
   9236 }
   9237 
   9238 PVMFStatus PVMFOMXEncNode::VerifyAndSetConfigParameter(PvmiKvp& aParameter, bool aSetParam)
   9239 {
   9240     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::VerifyAndSetConfigParameter() In", iNodeTypeId));
   9241 
   9242     // Determine the valtype
   9243     PvmiKvpValueType keyvaltype = GetValTypeFromKeyString(aParameter.key);
   9244     if (PVMI_KVPVALTYPE_UNKNOWN == keyvaltype)
   9245     {
   9246         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::VerifyAndSetConfigParameter() Valtype in key string unknown", iNodeTypeId));
   9247         return PVMFErrNotSupported;
   9248     }
   9249     // Retrieve the fourth component from the key string
   9250     char* compstr = NULL;
   9251     pv_mime_string_extract_type(3, aParameter.key, compstr);
   9252 
   9253     int32 enccomp4ind;
   9254     for (enccomp4ind = 0; enccomp4ind < PVOMXENCNODECONFIG_BASE_NUMKEYS; ++enccomp4ind)
   9255     {
   9256         // Go through each component string at 4th level
   9257         if (pv_mime_strcmp(compstr, (char*)(PVOMXEncNodeConfigBaseKeys[enccomp4ind].iString)) >= 0)
   9258         {
   9259             // Break out of the for loop
   9260             break;
   9261         }
   9262     }
   9263 
   9264     if (PVOMXENCNODECONFIG_BASE_NUMKEYS <= enccomp4ind)
   9265     {
   9266         // Match couldn't be found or non-leaf node specified
   9267         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::VerifyAndSetConfigParameter() Unsupported key or non-leaf node", iNodeTypeId));
   9268         return PVMFErrNotSupported;
   9269     }
   9270 
   9271     // Verify the valtype
   9272     if (keyvaltype != PVOMXEncNodeConfigBaseKeys[enccomp4ind].iValueType)
   9273     {
   9274         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::VerifyAndSetConfigParameter() Valtype does not match for key", iNodeTypeId));
   9275         return PVMFErrNotSupported;
   9276     }
   9277 
   9278     switch (enccomp4ind)
   9279     {
   9280 
   9281 
   9282         case SAMPLING_RATE: // "sampling_rate"
   9283             // Change the parameter
   9284             if (aSetParam)
   9285             {
   9286                 // set the parameter here
   9287                 iAudioInputFormat.iInputSamplingRate = aParameter.value.uint32_value;
   9288                 iAudioEncodeParam.iOutputSamplingRate = aParameter.value.uint32_value;
   9289             }
   9290             break;
   9291 
   9292         case CHANNELS:  // "channels"
   9293             // change the parameter
   9294             if (aSetParam)
   9295             {
   9296                 // set the parameter here
   9297                 iAudioInputFormat.iInputNumChannels = aParameter.value.uint32_value;
   9298                 iAudioEncodeParam.iOutputNumChannels = aParameter.value.uint32_value;
   9299             }
   9300             break;
   9301         case ENCODING_MODE: // "encoding_mode"
   9302             // change the parameter
   9303             if (aSetParam)
   9304             {
   9305                 iVideoEncodeParam.iEncMode = (EncEncodingMode)aParameter.value.uint32_value;
   9306             }
   9307             break;
   9308 
   9309 
   9310 
   9311 #ifdef _TEST_AE_ERROR_HANDLING
   9312         case ERROR_START_INIT: // "error_start_init"
   9313             // change the parameter
   9314             if (aSetParam)
   9315             {
   9316                 iErrorHandlingInit = aParameter.value.bool_value;
   9317             }
   9318             break;
   9319         case ERROR_ENCODE: // "error_avcencode"
   9320             // change the parameter
   9321             if (aSetParam)
   9322             {
   9323 
   9324                 char* paramstr = NULL;
   9325                 OSCL_HeapString<OsclMemAllocator> mode1 = "mode=duration";
   9326                 OSCL_HeapString<OsclMemAllocator> mode2 = "mode=frames";
   9327 
   9328                 if (pv_mime_string_parse_param(aParameter.key, mode1.get_str(), paramstr) > 0)
   9329                 {
   9330                     iErrorEncodeFlag = 1;
   9331                     iErrorHandlingEncodeCount = aParameter.value.uint32_value;
   9332 
   9333                 }
   9334 
   9335                 else if (pv_mime_string_parse_param(aParameter.key, mode2.get_str(), paramstr) > 0)
   9336                 {
   9337                     iErrorEncodeFlag = 2;
   9338                     iErrorHandlingEncodeCount = aParameter.value.uint32_value;
   9339 
   9340                 }
   9341             }
   9342             break;
   9343         case ERROR_NODE_CMD: //"error-node-cmd"
   9344             if (aSetParam)
   9345             {
   9346                 iErrorNodeCmd = aParameter.value.uint32_value;
   9347             }
   9348             break;
   9349         case ERROR_CONFIG_HEADER:
   9350             if (aSetParam)
   9351             {
   9352                 iErrorConfigHeader = aParameter.value.bool_value;
   9353             }
   9354             break;
   9355         case ERROR_DATAPATH_STALL:
   9356             if (aSetParam)
   9357             {
   9358                 iErrorDataPathStall = aParameter.value.uint32_value;
   9359             }
   9360             break;
   9361 #endif
   9362 
   9363         default:
   9364             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::VerifyAndSetConfigParameter() Invalid index for video enc node parameter", iNodeTypeId));
   9365             return PVMFErrNotSupported;
   9366     }
   9367 
   9368     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::VerifyAndSetConfigParameter() Out", iNodeTypeId));
   9369     return PVMFSuccess;
   9370 }
   9371 
   9372 //void PVMFOMXEncNode::setParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters, int aNumElements, PvmiKvp*& aRetKVP)
   9373 void PVMFOMXEncNode::DoCapConfigSetParameters(PvmiKvp* aParameters, int aNumElements, PvmiKvp*& aRetKVP)
   9374 {
   9375     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::DoCapConfigSetParameters()", iNodeTypeId));
   9376     //OSCL_UNUSED_ARG(aSession);
   9377 
   9378     if (NULL == aParameters || aNumElements < 1)
   9379     {
   9380         if (aParameters)
   9381         {
   9382             aRetKVP = aParameters;
   9383         }
   9384         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::DoCapConfigSetParameters() Passed in parameter invalid", iNodeTypeId));
   9385         return;
   9386     }
   9387 
   9388     // Go through each parameter
   9389     for (int32 paramind = 0; paramind < aNumElements; ++paramind)
   9390     {
   9391         // Count the number of components and parameters in the key
   9392         int compcount = pv_mime_string_compcnt(aParameters[paramind].key);
   9393         // Retrieve the first component from the key string
   9394         char* compstr = NULL;
   9395         pv_mime_string_extract_type(0, aParameters[paramind].key, compstr);
   9396 
   9397 
   9398         if ((
   9399                     (pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/encoder/video")) < 0) &&
   9400                     (pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/encoder/audio")) < 0)
   9401                 ) || (compcount < 4))
   9402         {
   9403             // First 3 components should be "x-pvmf/encoder/video" or "x-pvmf/encoder/audio" and there must
   9404             // be at least 4 components
   9405             aRetKVP = &aParameters[paramind];
   9406             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::DoCapConfigSetParameters() Unsupported key", iNodeTypeId));
   9407             return;
   9408         }
   9409 
   9410         // check if audio parameters are asked from video enc instance or vice versa
   9411         if (((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/encoder/video")) > 0) && (iInFormat == PVMF_MIME_PCM16)) ||
   9412                 ((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/encoder/audio")) > 0) && (iInFormat != PVMF_MIME_PCM16))
   9413            )
   9414         {
   9415 
   9416             aRetKVP = &aParameters[paramind];
   9417             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::DoCapConfigSetParameters() Unsupported key", iNodeTypeId));
   9418             return;
   9419         }
   9420 
   9421         if (4 == compcount)
   9422         {
   9423             // Verify and set the passed-in video enc node setting
   9424             PVMFStatus retval = VerifyAndSetConfigParameter(aParameters[paramind], true);
   9425             if (PVMFSuccess != retval)
   9426             {
   9427                 aRetKVP = &aParameters[paramind];
   9428                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::DoCapConfigSetParameters() Setting parameter %d failed", iNodeTypeId, paramind));
   9429                 return;
   9430             }
   9431         }
   9432 
   9433         else
   9434         {
   9435             // Do not support more than 4 components right now
   9436             aRetKVP = &aParameters[paramind];
   9437             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::DoCapConfigSetParameters() Unsupported key", iNodeTypeId));
   9438             return;
   9439         }
   9440     }
   9441     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::DoCapConfigSetParameters() Out", iNodeTypeId));
   9442 }
   9443 
   9444 
   9445 //PVMFStatus PVMFOMXEncNode::getParametersSync(PvmiMIOSession aSession, PvmiKeyType aIdentifier, PvmiKvp*& aParameters, int& aNumParamElements, PvmiCapabilityContext aContext)
   9446 PVMFStatus PVMFOMXEncNode::DoCapConfigGetParametersSync(PvmiKeyType aIdentifier, PvmiKvp*& aParameters, int& aNumParamElements, PvmiCapabilityContext aContext)
   9447 {
   9448     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::DoCapConfigGetParametersSync()", iNodeTypeId));
   9449     //OSCL_UNUSED_ARG(aSession);
   9450     OSCL_UNUSED_ARG(aContext);
   9451 
   9452     // Initialize the output parameters
   9453     aNumParamElements = 0;
   9454     aParameters = NULL;
   9455 
   9456     // Count the number of components and parameters in the key
   9457     int compcount = pv_mime_string_compcnt(aIdentifier);
   9458     // Retrieve the first component from the key string
   9459     char* compstr = NULL;
   9460     pv_mime_string_extract_type(0, aIdentifier, compstr);
   9461 
   9462     if ((
   9463                 (pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/encoder/video")) < 0) &&
   9464                 (pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/encoder/audio")) < 0)
   9465             ) || (compcount < 4))
   9466     {
   9467         // First 3 components should be "x-pvmf/encoder/video" or  "x-pvmf/encoder/audio" and there must
   9468         // be at least 4 components
   9469         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::DoCapConfigGetParametersSync() Invalid key string", iNodeTypeId));
   9470         return PVMFErrNotSupported;
   9471     }
   9472 
   9473     // check if audio parameters are asked from video enc instance or vice versa
   9474     if (((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/encoder/video")) > 0) && (iInFormat == PVMF_MIME_PCM16)) ||
   9475             ((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/encoder/audio")) > 0) && (iInFormat != PVMF_MIME_PCM16))
   9476        )
   9477     {
   9478         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::DoCapConfigGetParameters() Unsupported key", iNodeTypeId));
   9479         return PVMFErrNotSupported;
   9480     }
   9481 
   9482     // Retrieve the fourth component from the key string
   9483     pv_mime_string_extract_type(3, aIdentifier, compstr);
   9484 
   9485     for (int32 enccomp4ind = 0; enccomp4ind < PVOMXENCNODECONFIG_BASE_NUMKEYS; ++enccomp4ind)
   9486     {
   9487         // Go through each video enc component string at 4th level
   9488         if (pv_mime_strcmp(compstr, (char*)(PVOMXEncNodeConfigBaseKeys[enccomp4ind].iString)) >= 0)
   9489         {
   9490             if (4 == compcount)
   9491             {
   9492                 // Determine what is requested
   9493                 PvmiKvpAttr reqattr = GetAttrTypeFromKeyString(aIdentifier);
   9494                 if (PVMI_KVPATTR_UNKNOWN == reqattr)
   9495                 {
   9496                     reqattr = PVMI_KVPATTR_CUR;
   9497                 }
   9498 
   9499                 // Return the requested info
   9500                 PVMFStatus retval = GetConfigParameter(aParameters, aNumParamElements, enccomp4ind, reqattr);
   9501                 if (PVMFSuccess != retval)
   9502                 {
   9503                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::DoCapConfigGetParametersSync() Retrieving video enc node parameter failed", iNodeTypeId));
   9504                     return retval;
   9505                 }
   9506             }
   9507             else
   9508             {
   9509                 // Right now videoenc node doesn't support more than 4 components
   9510                 // for this sub-key string so error out
   9511                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::DoCapConfigGetParametersSync() Unsupported key", iNodeTypeId));
   9512                 return PVMFErrNotSupported;
   9513             }
   9514         }
   9515     }
   9516 
   9517     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::DoCapConfigGetParametersSync() Out", iNodeTypeId));
   9518     if (aNumParamElements == 0)
   9519     {
   9520         // If no one could get the parameter, return error
   9521         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::DoCapConfigGetParametersSync() Unsupported key", iNodeTypeId));
   9522         return PVMFFailure;
   9523     }
   9524     else
   9525     {
   9526         return PVMFSuccess;
   9527     }
   9528 }
   9529 
   9530 //PVMFStatus PVMFOMXEncNode::releaseParameters(PvmiMIOSession aSession, PvmiKvp* aParameters, int aNumElements)
   9531 PVMFStatus PVMFOMXEncNode::DoCapConfigReleaseParameters(PvmiKvp* aParameters, int aNumElements)
   9532 {
   9533     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::releaseParameters()", iNodeTypeId));
   9534     //OSCL_UNUSED_ARG(aSession);
   9535 
   9536     if (aParameters == NULL || aNumElements < 1)
   9537     {
   9538         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::DoCapConfigReleaseParameters() KVP list is NULL or number of elements is 0", iNodeTypeId));
   9539         return PVMFErrArgument;
   9540     }
   9541 
   9542     // Count the number of components and parameters in the key
   9543     int compcount = pv_mime_string_compcnt(aParameters[0].key);
   9544     // Retrieve the first component from the key string
   9545     char* compstr = NULL;
   9546     pv_mime_string_extract_type(0, aParameters[0].key, compstr);
   9547 
   9548     if ((
   9549                 (pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/encoder/video")) < 0) &&
   9550                 (pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/encoder/audio")) < 0)
   9551             ) || (compcount < 3))
   9552     {
   9553         // First 3 component should be "x-pvmf/encoder/video" or "x-pvmf/encoder/audio" and there must
   9554         // be at least three components
   9555         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::DoCapConfigReleaseParameters() Unsupported key", iNodeTypeId));
   9556         return PVMFErrNotSupported;
   9557     }
   9558 
   9559     // check if audio parameters are asked from video enc instance or vice versa
   9560     if (((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/encoder/video")) > 0) && (iInFormat == PVMF_MIME_PCM16)) ||
   9561             ((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/encoder/audio")) > 0) && (iInFormat != PVMF_MIME_PCM16))
   9562        )
   9563     {
   9564         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::DoCapConfigReleaseParameters() Unsupported key", iNodeTypeId));
   9565         return PVMFErrNotSupported;
   9566     }
   9567 
   9568     // Retrieve the third component from the key string
   9569     pv_mime_string_extract_type(2, aParameters[0].key, compstr);
   9570 
   9571     // Go through each KVP and release memory for value if allocated from heap
   9572     for (int32 ii = 0; ii < aNumElements; ++ii)
   9573     {
   9574         // Next check if it is a value type that allocated memory
   9575         PvmiKvpType kvptype = GetTypeFromKeyString(aParameters[ii].key);
   9576         if (PVMI_KVPTYPE_VALUE == kvptype || PVMI_KVPTYPE_UNKNOWN == kvptype)
   9577         {
   9578             PvmiKvpValueType keyvaltype = GetValTypeFromKeyString(aParameters[ii].key);
   9579             if (PVMI_KVPVALTYPE_UNKNOWN == keyvaltype)
   9580             {
   9581                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::DoCapConfigReleaseParameters() Valtype not specified in key string", iNodeTypeId));
   9582                 return PVMFErrNotSupported;
   9583             }
   9584 
   9585             if (PVMI_KVPVALTYPE_CHARPTR == keyvaltype && NULL != aParameters[ii].value.pChar_value)
   9586             {
   9587                 oscl_free(aParameters[ii].value.pChar_value);
   9588                 aParameters[ii].value.pChar_value = NULL;
   9589             }
   9590             else if (keyvaltype == PVMI_KVPVALTYPE_KSV && NULL != aParameters[ii].value.key_specific_value)
   9591             {
   9592                 oscl_free(aParameters[ii].value.key_specific_value);
   9593                 aParameters[ii].value.key_specific_value = NULL;
   9594             }
   9595             else if (PVMI_KVPVALTYPE_RANGE_UINT32 == keyvaltype && NULL != aParameters[ii].value.key_specific_value)
   9596             {
   9597                 range_uint32* rui32 = (range_uint32*)aParameters[ii].value.key_specific_value;
   9598                 aParameters[ii].value.key_specific_value = NULL;
   9599                 oscl_free(rui32);
   9600             }
   9601             // @TODO Add more types if video enc node starts returning more types
   9602         }
   9603     }
   9604 
   9605     // Video enc node allocated its key strings in one chunk so just free the first key string ptr
   9606     oscl_free(aParameters[0].key);
   9607 
   9608     // Free memory for the parameter list
   9609     oscl_free(aParameters);
   9610     aParameters = NULL;
   9611 
   9612     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::DoCapConfigReleaseParameters() Out", iNodeTypeId));
   9613     return PVMFSuccess;
   9614 }
   9615 
   9616 
   9617 //PVMFStatus PVMFOMXEncNode::verifyParametersSync (PvmiMIOSession aSession, PvmiKvp* aParameters, int aNumElements)
   9618 PVMFStatus PVMFOMXEncNode::DoCapConfigVerifyParameters(PvmiKvp* aParameters, int aNumElements)
   9619 {
   9620     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::DoCapConfigVerifyParameters()", iNodeTypeId));
   9621     //OSCL_UNUSED_ARG(aSession);
   9622 
   9623     if (NULL == aParameters || aNumElements < 1)
   9624     {
   9625         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::DoCapConfigVerifyParameters() Passed in parameter invalid", iNodeTypeId));
   9626         return PVMFErrArgument;
   9627     }
   9628 
   9629     // Go through each parameter
   9630     for (int32 paramind = 0; paramind < aNumElements; ++paramind)
   9631     {
   9632         // Count the number of components and parameters in the key
   9633         int compcount = pv_mime_string_compcnt(aParameters[paramind].key);
   9634         // Retrieve the first component from the key string
   9635         char* compstr = NULL;
   9636         pv_mime_string_extract_type(0, aParameters[paramind].key, compstr);
   9637 
   9638         if (
   9639             ((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/encoder/video")) < 0) &&
   9640              (pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/encoder/audio")) < 0)
   9641             ) || compcount < 3)
   9642         {
   9643             // First 3 components should be "x-pvmf/encoder/video" or
   9644             // "x-pvmf/enoder/audio" and there must
   9645             // be at least 3 components
   9646 
   9647             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::DoCapConfigVerifyParameters() Unsupported key", iNodeTypeId));
   9648             return PVMFErrNotSupported;
   9649         }
   9650 
   9651         // check if audio parameters are asked from video enc instance or vice versa
   9652         if (((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/encoder/video")) > 0) && (iInFormat == PVMF_MIME_PCM16)) ||
   9653                 ((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/encoder/audio")) > 0) && (iInFormat != PVMF_MIME_PCM16))
   9654            )
   9655         {
   9656             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::DoCapConfigVerifyParameters() Unsupported key", iNodeTypeId));
   9657             return PVMFErrNotSupported;
   9658         }
   9659 
   9660         if (4 == compcount)
   9661         {
   9662             // Verify and set the passed-in video enc node setting
   9663             PVMFStatus retval = VerifyAndSetConfigParameter(aParameters[paramind], false);
   9664             if (retval != PVMFSuccess)
   9665             {
   9666                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::DoCapConfigVerifyParameters() Setting parameter %d failed", iNodeTypeId, paramind));
   9667                 return retval;
   9668             }
   9669         }
   9670         else
   9671         {
   9672             // Do not support more than 4 components right now
   9673             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::DoCapConfigVerifyParameters() Unsupported key", iNodeTypeId));
   9674             return PVMFErrNotSupported;
   9675         }
   9676     }
   9677 
   9678     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXEncNode-%s::DoCapConfigVerifyParameters() Out", iNodeTypeId));
   9679     return PVMFSuccess;
   9680 
   9681 }
   9682 
   9683 int32 PVMFOMXEncNode::PushBackKeyVal(Oscl_Vector<PvmiKvp, OsclMemAllocator>*& aValueListPtr, PvmiKvp &aKeyVal)
   9684 {
   9685     int32 leavecode = 0;
   9686     OSCL_TRY(leavecode, (*aValueListPtr).push_back(aKeyVal));
   9687     return leavecode;
   9688 }
   9689 
   9690 int32 PVMFOMXEncNode::Push_Back_MetadataKeys(const char* aMetadataKey)
   9691 {
   9692     int32 leavecode = 0;
   9693     OSCL_TRY(leavecode, iAvailableMetadataKeys.push_back(aMetadataKey));
   9694     return leavecode;
   9695 }
   9696 
   9697 int32 PVMFOMXEncNode::Push_Back_MetadataKeys(PVMFMetadataList *&aKeylistptr, uint32 aLcv)
   9698 {
   9699     int32 leavecode = 0;
   9700     OSCL_TRY(leavecode, aKeylistptr->push_back(iAvailableMetadataKeys[aLcv]));
   9701     return leavecode;
   9702 }
   9703 
   9704 int32 PVMFOMXEncNode::CreateNewArray(char*& aPtr, int32 aLen)
   9705 {
   9706     int32 leavecode = 0;
   9707     OSCL_TRY(leavecode,
   9708              aPtr = OSCL_ARRAY_NEW(char, aLen););
   9709     return leavecode;
   9710 }
   9711 
   9712 int32 PVMFOMXEncNode::MemAllocate(OsclAny *&aPtr, OsclMemPoolFixedChunkAllocator *aMemPool, uint32 aAllocSize)
   9713 {
   9714     uint32 errcode = 0;
   9715     OSCL_TRY(errcode, aPtr = (OsclAny *) aMemPool->allocate(aAllocSize));
   9716     return errcode;
   9717 }
   9718 
   9719 bool PVMFOMXEncNode::ParseFullAVCFramesIntoNALs(OMX_BUFFERHEADERTYPE* aOutputBuffer)
   9720 {
   9721     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVMFOMXEncNode-%s : ParseFullAVCFramesIntoNALs IN", iNodeTypeId));
   9722 
   9723     if (iOMXComponentUsesNALStartCodes && !(aOutputBuffer->nFlags & OMX_BUFFERFLAG_EXTRADATA))
   9724     {
   9725         OMX_U32 offset = aOutputBuffer->nOffset;
   9726         OMX_U32 length = aOutputBuffer->nFilledLen;
   9727         OMX_U8* pBuffer = aOutputBuffer->pBuffer + offset;
   9728         OMX_U8* pCurrNAL;
   9729         OMX_U32 bytesConsumed;
   9730         int32 nalSize;
   9731 
   9732         iNumNALs = 0;
   9733 
   9734         while (length > 0)
   9735         {
   9736             nalSize = length;
   9737 
   9738             if (false == AVCAnnexBGetNALUnit(pBuffer, &pCurrNAL, &nalSize, false))
   9739             {
   9740                 break;
   9741             }
   9742 
   9743             bytesConsumed = nalSize + (int32)(pCurrNAL - pBuffer);
   9744             length -= bytesConsumed;
   9745             pBuffer += bytesConsumed;
   9746 
   9747             if ((iNALSizeArrayMaxElems > iNumNALs) && (iNALSizeArray != NULL))
   9748             {
   9749                 iNALSizeArray[iNumNALs] = nalSize;
   9750                 iNALPtrArray[iNumNALs] = (uint8*)pCurrNAL; /* need store NAL ptrs since start code can be either 4 bytes or 3 bytes */
   9751                 iNumNALs++;
   9752             }
   9753             else
   9754             {
   9755                 iNumNALs++;
   9756 
   9757                 // count the number of NALs in the buffer
   9758                 while (length > 0)
   9759                 {
   9760                     nalSize = length;
   9761 
   9762                     if (false == AVCAnnexBGetNALUnit(pBuffer, &pCurrNAL, &nalSize, false))
   9763                     {
   9764                         break;
   9765                     }
   9766 
   9767                     bytesConsumed = nalSize + (int32)(pCurrNAL - pBuffer);
   9768                     length -= bytesConsumed;
   9769                     pBuffer += bytesConsumed;
   9770 
   9771                     iNumNALs++;
   9772                 }
   9773 
   9774                 // reassign alloc size to new max.
   9775                 iNALSizeArrayMaxElems = iNumNALs;
   9776 
   9777                 // free memory and then reallocate
   9778                 if (iNALSizeArray != NULL)
   9779                 {
   9780                     oscl_free(iNALSizeArray);
   9781                 }
   9782                 iNALSizeArray = (uint32*) oscl_malloc(sizeof(uint32) * iNALSizeArrayMaxElems);
   9783 
   9784                 if (iNALPtrArray != NULL)
   9785                 {
   9786                     oscl_free(iNALPtrArray);
   9787                 }
   9788                 iNALPtrArray = (uint8**) oscl_malloc(sizeof(uint8*) * iNALSizeArrayMaxElems);
   9789 
   9790                 // reset parameters and start over
   9791                 iNumNALs = 0;
   9792                 length = aOutputBuffer->nFilledLen;
   9793                 pBuffer = aOutputBuffer->pBuffer + offset;
   9794 
   9795                 if (iNALSizeArray == NULL || iNALPtrArray == NULL)
   9796                 {
   9797                     iNALSizeArrayMaxElems = 0;
   9798 
   9799                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVMFOMXEncNode-%s : ParseFullAVCFramesIntoNALs ERROR - Out of Memory", iNodeTypeId));
   9800                     return false;
   9801                 }
   9802             }
   9803         }
   9804 
   9805         if (iNumNALs <= 0)
   9806         {
   9807             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVMFOMXEncNode-%s : ParseFullAVCFramesIntoNALs ERROR", iNodeTypeId));
   9808             return false;
   9809         }
   9810     }
   9811     else if (aOutputBuffer->nFlags & OMX_BUFFERFLAG_EXTRADATA)
   9812     {
   9813         // get extra data from end of buffer
   9814         OMX_OTHER_EXTRADATATYPE *pExtra;
   9815         OMX_U32 offset = aOutputBuffer->nOffset + aOutputBuffer->nFilledLen;
   9816         OMX_U32 allocLen = aOutputBuffer->nAllocLen;
   9817         OMX_U8* pTemp = aOutputBuffer->pBuffer + offset;
   9818 
   9819         // align
   9820         pExtra = (OMX_OTHER_EXTRADATATYPE *)(((OMX_U32) pTemp + 3) & ~3);
   9821         offset += (OMX_U32) pExtra - (OMX_U32) pTemp;
   9822 
   9823         while (pExtra->eType != OMX_ExtraDataNone)
   9824         {
   9825             if (pExtra->eType == OMX_ExtraDataNALSizeArray)
   9826             {
   9827                 iNumNALs = pExtra->nDataSize >> 2;
   9828                 if ((iNALSizeArrayMaxElems > iNumNALs) && (iNALSizeArray != NULL))
   9829                 {
   9830                     oscl_memcpy(iNALSizeArray, ((OMX_U8*)pExtra + 20), pExtra->nDataSize); // 20 is the size of the extra data struct (minus data hint)
   9831                 }
   9832                 else
   9833                 {
   9834                     // reassign alloc size to new max.
   9835                     iNALSizeArrayMaxElems = iNumNALs;
   9836 
   9837                     // free memory and then reallocate
   9838                     if (iNALSizeArray != NULL)
   9839                     {
   9840                         oscl_free(iNALSizeArray);
   9841                     }
   9842 
   9843                     iNALSizeArray = (uint32*) oscl_malloc(sizeof(uint32) * iNALSizeArrayMaxElems);
   9844                     if (iNALSizeArray == NULL)
   9845                     {
   9846                         iNALSizeArrayMaxElems = 0;
   9847 
   9848                         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVMFOMXEncNode-%s : ParseFullAVCFramesIntoNALs ERROR - Out of Memory", iNodeTypeId));
   9849                         return false;
   9850                     }
   9851 
   9852                     oscl_memcpy(iNALSizeArray, ((OMX_U8*)pExtra + 20), pExtra->nDataSize); // 20 is the size of the extra data struct (minus data hint)
   9853                 }
   9854 
   9855                 break;
   9856             }
   9857 
   9858             offset += pExtra->nSize;
   9859             /* 20 is size of extra data struct (minus data hint),
   9860              * so if there isn't enough room for there to be a full struct, and we haven't reached an OMX_ExtraDataNone
   9861              * the data is corrupt
   9862              */
   9863             if (offset > (allocLen - 20))
   9864             {
   9865                 // corrupt data
   9866                 break;
   9867             }
   9868             else
   9869             {
   9870                 pExtra = (OMX_OTHER_EXTRADATATYPE *)((OMX_U8*)pExtra + pExtra->nSize);
   9871             }
   9872         }
   9873 
   9874         if (pExtra->eType != OMX_ExtraDataNALSizeArray)
   9875         {
   9876             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVMFOMXEncNode-%s : ParseFullAVCFramesIntoNALs ERROR", iNodeTypeId));
   9877             return false;
   9878         }
   9879     }
   9880     else
   9881     {
   9882         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVMFOMXEncNode-%s : ParseFullAVCFramesIntoNALs ERROR", iNodeTypeId));
   9883         return false;
   9884     }
   9885 
   9886     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVMFOMXEncNode-%s : ParseFullAVCFramesIntoNALs OUT", iNodeTypeId));
   9887     return true;
   9888 }
   9889 
   9890 /* utility function copied from the AVC Decoder interface */
   9891 bool PVMFOMXEncNode::AVCAnnexBGetNALUnit(uint8 *bitstream, uint8 **nal_unit, int32 *size, bool getPtrOnly)
   9892 {
   9893     int32 i, j, FoundStartCode = 0;
   9894     int32 end;
   9895 
   9896     i = 0;
   9897     while (bitstream[i] == 0 && i < *size)
   9898     {
   9899         i++;
   9900     }
   9901     if (i >= *size)
   9902     {
   9903         *nal_unit = bitstream;
   9904         return false; /* cannot find any start_code_prefix. */
   9905     }
   9906     else if (bitstream[i] != 0x1)
   9907     {
   9908         i = -1;  /* start_code_prefix is not at the beginning, continue */
   9909     }
   9910 
   9911     i++;
   9912     *nal_unit = bitstream + i; /* point to the beginning of the NAL unit */
   9913 
   9914     if (getPtrOnly)
   9915     {
   9916         // size not needed, just return with ptr
   9917         return true;
   9918     }
   9919 
   9920     j = end = i;
   9921     while (!FoundStartCode)
   9922     {
   9923         while ((j + 1 < *size) && (bitstream[j] != 0 || bitstream[j+1] != 0))  /* see 2 consecutive zero bytes */
   9924         {
   9925             j++;
   9926         }
   9927         end = j;   /* stop and check for start code */
   9928         while (j + 2 < *size && bitstream[j+2] == 0) /* keep reading for zero byte */
   9929         {
   9930             j++;
   9931         }
   9932         if (j + 2 >= *size)
   9933         {
   9934             *size -= i;
   9935             return true;  /* cannot find the second start_code_prefix */
   9936         }
   9937         if (bitstream[j+2] == 0x1)
   9938         {
   9939             FoundStartCode = 1;
   9940         }
   9941         else
   9942         {
   9943             /* could be emulation code 0x3 */
   9944             j += 2; /* continue the search */
   9945         }
   9946     }
   9947 
   9948     *size = end - i;
   9949 
   9950     return true;
   9951 }
   9952 
   9953 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
   9954 bool PVMFOMXEncNode::CheckM4vVopStartCode(uint8* data, int* len)
   9955 {
   9956     int32 count = 0;
   9957     int32 i = *len;
   9958 
   9959     if (i < 4)  // at least the size of frame header
   9960     {
   9961         return false;
   9962     }
   9963     while (--i)
   9964     {
   9965         if ((count > 1) && (data[0] == 0x01) && (data[1] == 0xB6))
   9966         {
   9967             i += 2;
   9968             break;
   9969         }
   9970 
   9971         if (*data++)
   9972             count = 0;
   9973         else
   9974             count++;
   9975     }
   9976 
   9977     // i is number of bytes left (including 00 00 01 B6)
   9978     if (i > 0)
   9979     {
   9980         *len = (*len - i - 1); // len before finding VOP start code
   9981         return true;
   9982     }
   9983 
   9984     return false;
   9985 }
   9986 
   9987 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
   9988 OMX_TICKS PVMFOMXEncNode::ConvertTimestampIntoOMXTicks(const MediaClockConverter& src)
   9989 {
   9990     // This is similar to mediaclockconverter set_value method - except without using the modulo for upper part of 64 bits
   9991 
   9992     // Timescale value cannot be zero
   9993     OSCL_ASSERT(src.get_timescale() != 0);
   9994     if (src.get_timescale() == 0)
   9995     {
   9996         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   9997                         (0, "PVMFOMXEncNode-%s::ConvertTimestampIntoOMXTicks Input timescale is 0", iNodeTypeId));
   9998 
   9999         SetState(EPVMFNodeError);
   10000         ReportErrorEvent(PVMFErrResourceConfiguration);
   10001         return (OMX_TICKS) 0;
   10002     }
   10003 
   10004     OSCL_ASSERT(iTimeScale != 0);
   10005     if (0 == iTimeScale)
   10006     {
   10007         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   10008                         (0, "PVMFOMXEncNode-%s::ConvertTimestampIntoOMXTicks target timescale is 0", iNodeTypeId));
   10009 
   10010         SetState(EPVMFNodeError);
   10011         ReportErrorEvent(PVMFErrResourceConfiguration);
   10012         return (OMX_TICKS) 0;
   10013     }
   10014 
   10015     uint64 value = (uint64(src.get_wrap_count())) << 32;
   10016     value += src.get_current_timestamp();
   10017     // rounding up
   10018     value = (uint64(value) * iTimeScale + uint64(src.get_timescale() - 1)) / src.get_timescale();
   10019     return (OMX_TICKS) value;
   10020 
   10021 
   10022 }
   10023 ////////////////////////////////////////////////////////////////////////////////////
   10024 uint32 PVMFOMXEncNode::ConvertOMXTicksIntoTimestamp(const OMX_TICKS &src)
   10025 {
   10026     // omx ticks use microsecond timescale (iTimeScale = 1000000)
   10027     // This is similar to mediaclockconverter set_value method
   10028 
   10029     // Timescale value cannot be zero
   10030     OSCL_ASSERT(iOutTimeScale != 0);
   10031     if (0 == iOutTimeScale)
   10032     {
   10033         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   10034                         (0, "PVMFOMXEncNode-%s::ConvertOMXTicksIntoTimestamp Output timescale is 0", iNodeTypeId));
   10035 
   10036         SetState(EPVMFNodeError);
   10037         ReportErrorEvent(PVMFErrResourceConfiguration);
   10038         return (uint32) 0;
   10039     }
   10040 
   10041     OSCL_ASSERT(iTimeScale != 0);
   10042     if (0 == iTimeScale)
   10043     {
   10044         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   10045                         (0, "PVMFOMXEncNode-%s::ConvertOMXTicksIntoTimestamp target timescale is 0", iNodeTypeId));
   10046 
   10047         SetState(EPVMFNodeError);
   10048         ReportErrorEvent(PVMFErrResourceConfiguration);
   10049         return (uint32) 0;
   10050     }
   10051 
   10052     uint32 current_ts;
   10053 
   10054     uint64 value = (uint64) src;
   10055 
   10056     // rounding up
   10057     value = (uint64(value) * iOutTimeScale + uint64(iTimeScale - 1)) / iTimeScale;
   10058 
   10059     current_ts = (uint32)(value & 0xFFFFFFFF);
   10060     return (uint32) current_ts;
   10061 
   10062 }
   10063 
   10064 ////////////////////////////////////////////////////////////////////////////////
   10065 bool PVMFOMXEncNode::CheckComponentForMultRoles(OMX_STRING aCompName, OMX_STRING aRole)
   10066 {
   10067     OMX_ERRORTYPE err = OMX_ErrorNone;
   10068 
   10069     // find out how many roles the component supports
   10070     OMX_U32 NumRoles;
   10071     err = OMX_MasterGetRolesOfComponent(aCompName, &NumRoles, NULL);
   10072     if (err != OMX_ErrorNone)
   10073     {
   10074         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   10075                     (0, "PVMFOMXEncNode-%s::CheckComponentForMultRoles() Problem getting component roles", iNodeTypeId));
   10076 
   10077         return false;
   10078     }
   10079 
   10080     // if the component supports multiple roles, call OMX_SetParameter
   10081     if (NumRoles > 1)
   10082     {
   10083         OMX_PARAM_COMPONENTROLETYPE RoleParam;
   10084         CONFIG_SIZE_AND_VERSION(RoleParam);
   10085         oscl_strncpy((OMX_STRING)RoleParam.cRole, aRole, OMX_MAX_STRINGNAME_SIZE);
   10086         err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamStandardComponentRole, &RoleParam);
   10087         if (err != OMX_ErrorNone)
   10088         {
   10089             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   10090                             (0, "PVMFOMXEncNode-%s::CheckComponentForMultRoles() Problem setting component role", iNodeTypeId));
   10091 
   10092             return false;
   10093         }
   10094     }
   10095 
   10096     return true;
   10097 }
   10098 
   10099 ////////////////////////////////////////////////////////////////////////////////
   10100 bool PVMFOMXEncNode::CheckComponentCapabilities(PVMFFormatType* aOutFormat)
   10101 {
   10102     OMX_ERRORTYPE err = OMX_ErrorNone;
   10103 
   10104     // GET CAPABILITY FLAGS FROM PV COMPONENT, IF this fails, use defaults
   10105     PV_OMXComponentCapabilityFlagsType Cap_flags;
   10106     err = OMX_GetParameter(iOMXEncoder, (OMX_INDEXTYPE) PV_OMX_COMPONENT_CAPABILITY_TYPE_INDEX, &Cap_flags);
   10107     if (err != OMX_ErrorNone)
   10108     {
   10109         SetDefaultCapabilityFlags();
   10110     }
   10111     else
   10112     {
   10113         iIsOMXComponentMultiThreaded = (OMX_TRUE == Cap_flags.iIsOMXComponentMultiThreaded) ? true : false;
   10114         iOMXComponentSupportsExternalInputBufferAlloc = (OMX_TRUE == Cap_flags.iOMXComponentSupportsExternalInputBufferAlloc) ? true : false;
   10115         iOMXComponentSupportsExternalOutputBufferAlloc = (OMX_TRUE == Cap_flags.iOMXComponentSupportsExternalOutputBufferAlloc) ? true : false;
   10116         iOMXComponentSupportsMovableInputBuffers = (OMX_TRUE == Cap_flags.iOMXComponentSupportsMovableInputBuffers) ? true : false;
   10117         iOMXComponentSupportsPartialFrames = (OMX_TRUE == Cap_flags.iOMXComponentSupportsPartialFrames) ? true : false;
   10118         iOMXComponentUsesNALStartCodes = (OMX_TRUE == Cap_flags.iOMXComponentUsesNALStartCodes) ? true : false;
   10119         iOMXComponentCanHandleIncompleteFrames = (OMX_TRUE == Cap_flags.iOMXComponentCanHandleIncompleteFrames) ? true : false;
   10120         iOMXComponentUsesFullAVCFrames = (OMX_TRUE == Cap_flags.iOMXComponentUsesFullAVCFrames) ? true : false;
   10121     }
   10122 
   10123     /* iOMXComponentUsesNALStartCodes:    The component inserts start codes before NALs
   10124 
   10125       iOMXComponentUsesFullAVCFrames
   10126        && !iOMXComponentUsesNALStartCodes:  The component outputs full frames, and stores NAL start codes using the
   10127                  OMX ExtraData structure in the output buffer
   10128 
   10129       iOMXComponentUsesFullAVCFrames
   10130        && iOMXComponentUsesNALStartCodes:  The component outputs full frames, and delimits NALs by their start codes
   10131 
   10132       aOutFormat == PVMF_MIME_H264_VIDEO_RAW
   10133        && !iOMXComponentUsesNALStartCodes:  The node inserts the start codes and hides them / exposes them when needed
   10134 
   10135       aOutFormat == PVMF_MIME_H264_VIDEO_RAW
   10136        && !iOMXComponentUsesNALStartCodes
   10137        && iOMXComponentUsesFullAVCFrames:  This is an invalid combination.  If the node wants raw output, and the component
   10138                  uses full frames, and no start codes, then there is no way to detect the
   10139                  NAL boundaries.
   10140     */
   10141 
   10142     if (*aOutFormat == PVMF_MIME_H264_VIDEO_RAW &&
   10143             iOMXComponentUsesFullAVCFrames && !iOMXComponentUsesNALStartCodes)
   10144     {
   10145         // This is an invalid combination (see above). Therefore, return an error.
   10146 
   10147 
   10148         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   10149                         (0, "PVMFOMXEncNode-%s::CheckComponentCapabilities() Component cannot support %s format", iNodeTypeId, PVMF_MIME_H264_VIDEO_RAW));
   10150 
   10151         return false;
   10152     }
   10153 
   10154     // find out about parameters
   10155     if (aOutFormat->isAudio())
   10156     {
   10157         if (!NegotiateAudioComponentParameters())
   10158         {
   10159             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   10160                             (0, "PVMFOMXEncNode-%s::CheckComponentCapabilities() Cannot get component parameters", iNodeTypeId));
   10161 
   10162             return false;
   10163         }
   10164     }
   10165     else
   10166     {
   10167 
   10168         if (!NegotiateVideoComponentParameters())
   10169         {
   10170             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   10171                             (0, "PVMFOMXEncNode-%s::CheckComponentCapabilities() Cannot get component parameters", iNodeTypeId));
   10172 
   10173             return false;
   10174         }
   10175     }
   10176 
   10177     return true;
   10178 }
   10179 
   10180 
   10181