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_audiodec_node.h"
     19 #include "pvlogger.h"
     20 #include "oscl_error_codes.h"
     21 #include "pvmf_omx_basedec_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 #include "latmpayloadparser.h"
     28 
     29 
     30 #include "OMX_Core.h"
     31 #include "pvmf_omx_basedec_callbacks.h"     //used for thin AO in Decoder's callbacks
     32 #include "pv_omxcore.h"
     33 
     34 // needed for capability and config
     35 #include "pv_omx_config_parser.h"
     36 
     37 #include "utils/Log.h"
     38 #undef LOG_TAG
     39 #define LOG_TAG "PVOMXAudDecNode"
     40 
     41 #define CONFIG_SIZE_AND_VERSION(param) \
     42         param.nSize=sizeof(param); \
     43         param.nVersion.s.nVersionMajor = SPECVERSIONMAJOR; \
     44         param.nVersion.s.nVersionMinor = SPECVERSIONMINOR; \
     45         param.nVersion.s.nRevision = SPECREVISION; \
     46         param.nVersion.s.nStep = SPECSTEP;
     47 
     48 
     49 
     50 #define PVOMXAUDIODEC_MEDIADATA_POOLNUM 2*NUMBER_OUTPUT_BUFFER
     51 #define PVOMXAUDIODEC_MEDIADATA_CHUNKSIZE 128
     52 
     53 
     54 // Node default settings
     55 
     56 #define PVOMXAUDIODECNODE_CONFIG_MIMETYPE_DEF 0
     57 
     58 #define PVMF_OMXAUDIODEC_NUM_METADATA_VALUES 6
     59 
     60 // Constant character strings for metadata keys
     61 static const char PVOMXAUDIODECMETADATA_CODECINFO_AUDIO_FORMAT_KEY[] = "codec-info/audio/format";
     62 static const char PVOMXAUDIODECMETADATA_CODECINFO_AUDIO_CHANNELS_KEY[] = "codec-info/audio/channels";
     63 static const char PVOMXAUDIODECMETADATA_CODECINFO_AUDIO_SAMPLERATE_KEY[] = "codec-info/audio/sample-rate";
     64 static const char PVOMXAUDIODECMETADATA_CODECINFO_AUDIO_AVGBITRATE_KEY[] = "codec-info/audio/avgbitrate";
     65 static const char PVOMXAUDIODECMETADATA_CODECINFO_AUDIO_AACOBJECTTYPE_KEY[] = "codec-info/audio/aac-objecttype";
     66 static const char PVOMXAUDIODECMETADATA_CODECINFO_AUDIO_AACSTREAMTYPE_KEY[] = "codec-info/audio/aac-streamtype";
     67 
     68 
     69 static const char PVOMXAUDIODECMETADATA_SEMICOLON[] = ";";
     70 
     71 /////////////////////////////////////////////////////////////////////////////
     72 // Class Destructor
     73 /////////////////////////////////////////////////////////////////////////////
     74 PVMFOMXAudioDecNode::~PVMFOMXAudioDecNode()
     75 {
     76     DeleteLATMParser();
     77     ReleaseAllPorts();
     78 }
     79 
     80 /////////////////////////////////////////////////////////////////////////////
     81 // Add AO to the scheduler
     82 /////////////////////////////////////////////////////////////////////////////
     83 PVMFStatus PVMFOMXAudioDecNode::ThreadLogon()
     84 {
     85     PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFOMXAudioDecNode:ThreadLogon"));
     86 
     87     switch (iInterfaceState)
     88     {
     89         case EPVMFNodeCreated:
     90             if (!IsAdded())
     91             {
     92                 AddToScheduler();
     93                 iIsAdded = true;
     94             }
     95             iLogger = PVLogger::GetLoggerObject("PVMFOMXAudioDecNode");
     96             iRunlLogger = PVLogger::GetLoggerObject("Run.PVMFOMXAudioDecNode");
     97             iDataPathLogger = PVLogger::GetLoggerObject("datapath");
     98             iClockLogger = PVLogger::GetLoggerObject("clock");
     99             iDiagnosticsLogger = PVLogger::GetLoggerObject("pvplayerdiagnostics.decnode.OMXAudioDecnode");
    100 
    101             SetState(EPVMFNodeIdle);
    102             return PVMFSuccess;
    103 
    104         default:
    105             return PVMFErrInvalidState;
    106     }
    107 }
    108 
    109 /////////////////////
    110 // Private Section //
    111 /////////////////////
    112 
    113 /////////////////////////////////////////////////////////////////////////////
    114 // Class Constructor
    115 /////////////////////////////////////////////////////////////////////////////
    116 PVMFOMXAudioDecNode::PVMFOMXAudioDecNode(int32 aPriority) :
    117         PVMFOMXBaseDecNode(aPriority, "PVMFOMXAudioDecNode")
    118 {
    119     iInterfaceState = EPVMFNodeCreated;
    120 
    121     iNodeConfig.iMimeType = PVOMXAUDIODECNODE_CONFIG_MIMETYPE_DEF;
    122 
    123 
    124     int32 err;
    125     OSCL_TRY(err,
    126 
    127              //Create the input command queue.  Use a reserve to avoid lots of
    128              //dynamic memory allocation.
    129              iInputCommands.Construct(PVMF_OMXBASEDEC_NODE_COMMAND_ID_START, PVMF_OMXBASEDEC_NODE_COMMAND_VECTOR_RESERVE);
    130 
    131              //Create the "current command" queue.  It will only contain one
    132              //command at a time, so use a reserve of 1.
    133              iCurrentCommand.Construct(0, 1);
    134 
    135              //Set the node capability data.
    136              //This node can support an unlimited number of ports.
    137              iCapability.iCanSupportMultipleInputPorts = false;
    138              iCapability.iCanSupportMultipleOutputPorts = false;
    139              iCapability.iHasMaxNumberOfPorts = true;
    140              iCapability.iMaxNumberOfPorts = 2;
    141              iCapability.iInputFormatCapability.push_back(PVMF_MIME_MPEG4_AUDIO);
    142              iCapability.iInputFormatCapability.push_back(PVMF_MIME_3640);
    143              iCapability.iInputFormatCapability.push_back(PVMF_MIME_ADIF);
    144              iCapability.iInputFormatCapability.push_back(PVMF_MIME_LATM);
    145              iCapability.iInputFormatCapability.push_back(PVMF_MIME_ASF_MPEG4_AUDIO);
    146              iCapability.iInputFormatCapability.push_back(PVMF_MIME_AAC_SIZEHDR);
    147 
    148              iCapability.iInputFormatCapability.push_back(PVMF_MIME_AMR_IF2);
    149              iCapability.iInputFormatCapability.push_back(PVMF_MIME_AMR_IETF);
    150              iCapability.iInputFormatCapability.push_back(PVMF_MIME_AMR);
    151              iCapability.iInputFormatCapability.push_back(PVMF_MIME_AMRWB_IETF);
    152              iCapability.iInputFormatCapability.push_back(PVMF_MIME_AMRWB);
    153 
    154              iCapability.iInputFormatCapability.push_back(PVMF_MIME_MP3);
    155 
    156              iCapability.iInputFormatCapability.push_back(PVMF_MIME_WMA);
    157 
    158              iCapability.iOutputFormatCapability.push_back(PVMF_MIME_PCM16);
    159 
    160              iAvailableMetadataKeys.reserve(PVMF_OMXAUDIODEC_NUM_METADATA_VALUES);
    161              iAvailableMetadataKeys.clear();
    162             );
    163     // LATM init
    164     iLATMParser = NULL;
    165     iLATMConfigBuffer = NULL;
    166     iLATMConfigBufferSize = 0;
    167 
    168     //Try Allocate FSI buffer
    169 
    170     // Do This first in case of Query
    171     OSCL_TRY(err, iFsiFragmentAlloc.size(PVOMXAUDIODEC_MEDIADATA_POOLNUM, sizeof(channelSampleInfo)));
    172 
    173 
    174     OSCL_TRY(err, iPrivateDataFsiFragmentAlloc.size(PVOMXAUDIODEC_MEDIADATA_POOLNUM, sizeof(OsclAny *)));
    175 }
    176 
    177 /////////////////////////////////////////////////////////////////////////////
    178 // This routine will process incomming message from the port
    179 /////////////////////////////////////////////////////////////////////////////
    180 bool PVMFOMXAudioDecNode::ProcessIncomingMsg(PVMFPortInterface* aPort)
    181 {
    182     //Called by the AO to process one buffer off the port's
    183     //incoming data queue.  This routine will dequeue and
    184     //dispatch the data.
    185 
    186     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
    187                     (0, "0x%x PVMFOMXAudioDecNode::ProcessIncomingMsg: aPort=0x%x", this, aPort));
    188 
    189     PVMFStatus status = PVMFFailure;
    190 #ifdef SIMULATE_DROP_MSGS
    191     if ((((PVMFOMXDecPort*)aPort)->iNumFramesConsumed % 300 == 299))  // && (((PVMFOMXDecPort*)aPort)->iNumFramesConsumed < 30) )
    192     {
    193 
    194         // just dequeue
    195         PVMFSharedMediaMsgPtr msg;
    196 
    197         status = aPort->DequeueIncomingMsg(msg);
    198         ((PVMFOMXDecPort*)aPort)->iNumFramesConsumed++;
    199         status = aPort->DequeueIncomingMsg(msg);
    200         ((PVMFOMXDecPort*)aPort)->iNumFramesConsumed++;
    201         status = aPort->DequeueIncomingMsg(msg);
    202         ((PVMFOMXDecPort*)aPort)->iNumFramesConsumed++;
    203 
    204 #ifdef _DEBUG
    205         printf("PVMFOMXAudioDecNode::ProcessIncomingMsg() SIMULATED DROP 3 MSGS\n");
    206 #endif
    207 
    208 
    209     }
    210 #endif
    211 
    212 #ifdef SIMULATE_BOS
    213 
    214     if ((((PVMFOMXDecPort*)aPort)->iNumFramesConsumed == 6))
    215     {
    216 
    217         PVMFSharedMediaCmdPtr BOSCmdPtr = PVMFMediaCmd::createMediaCmd();
    218 
    219         // Set the format ID to BOS
    220         BOSCmdPtr->setFormatID(PVMF_MEDIA_CMD_BOS_FORMAT_ID);
    221 
    222         // Set the timestamp
    223         BOSCmdPtr->setTimestamp(201);
    224         BOSCmdPtr->setStreamID(0);
    225 
    226         // Convert to media message and send it out
    227         PVMFSharedMediaMsgPtr mediaMsgOut;
    228         convertToPVMFMediaCmdMsg(mediaMsgOut, BOSCmdPtr);
    229 
    230         //store the stream id and time stamp of bos message
    231         iStreamID = mediaMsgOut->getStreamID();
    232         iBOSTimestamp = mediaMsgOut->getTimestamp();
    233 
    234 
    235         iInputTimestampClock.set_clock(iBOSTimestamp, 0);
    236         iOMXTicksTimestamp = ConvertTimestampIntoOMXTicks(iInputTimestampClock);
    237 
    238         iSendBOS = true;
    239 
    240 #ifdef _DEBUG
    241         printf("PVMFOMXAudioDecNode::ProcessIncomingMsg() SIMULATED BOS\n");
    242 #endif
    243         ((PVMFOMXDecPort*)aPort)->iNumFramesConsumed++;
    244         return true;
    245 
    246     }
    247 #endif
    248 
    249 #ifdef SIMULATE_PREMATURE_EOS
    250     if (((PVMFOMXDecPort*)aPort)->iNumFramesConsumed == 5)
    251     {
    252         PVMFSharedMediaCmdPtr EOSCmdPtr = PVMFMediaCmd::createMediaCmd();
    253 
    254         // Set the format ID to EOS
    255         EOSCmdPtr->setFormatID(PVMF_MEDIA_CMD_EOS_FORMAT_ID);
    256 
    257         // Set the timestamp
    258         EOSCmdPtr->setTimestamp(200);
    259 
    260         // Convert to media message and send it out
    261         PVMFSharedMediaMsgPtr mediaMsgOut;
    262         convertToPVMFMediaCmdMsg(mediaMsgOut, EOSCmdPtr);
    263 
    264         ((PVMFOMXDecPort*)aPort)->iNumFramesConsumed++;
    265 
    266         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
    267                         (0, "PVMFOMXAudioDecNode::ProcessIncomingMsg: SIMULATED EOS"));
    268 #ifdef _DEBUG
    269         printf("PVMFOMXAudioDecNode::ProcessIncomingMsg() SIMULATED EOS\n");
    270 #endif
    271         // Set EOS flag
    272         iEndOfDataReached = true;
    273         // Save the timestamp for the EOS cmd
    274         iEndOfDataTimestamp = mediaMsgOut->getTimestamp();
    275 
    276         return true;
    277     }
    278 
    279 #endif
    280 
    281 
    282 
    283     PVMFSharedMediaMsgPtr msg;
    284 
    285     status = aPort->DequeueIncomingMsg(msg);
    286     if (status != PVMFSuccess)
    287     {
    288         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
    289                         (0, "0x%x PVMFOMXAudioDecNode::ProcessIncomingMsg: Error - DequeueIncomingMsg failed", this));
    290         return false;
    291     }
    292 
    293     if (msg->getFormatID() == PVMF_MEDIA_CMD_BOS_FORMAT_ID)
    294     {
    295         //store the stream id and time stamp of bos message
    296         iStreamID = msg->getStreamID();
    297         iBOSTimestamp = msg->getTimestamp();
    298 
    299 
    300         iInputTimestampClock.set_clock(iBOSTimestamp, 0);
    301         iOMXTicksTimestamp = ConvertTimestampIntoOMXTicks(iInputTimestampClock);
    302 
    303         iSendBOS = true;
    304 
    305         // if new BOS arrives, and
    306         //if we're in the middle of a partial frame assembly
    307         // abandon it and start fresh
    308         if (iObtainNewInputBuffer == false)
    309         {
    310             if (iInputBufferUnderConstruction != NULL)
    311             {
    312                 if (iInBufMemoryPool != NULL)
    313                 {
    314                     iInBufMemoryPool->deallocate((OsclAny *)iInputBufferUnderConstruction);
    315                 }
    316                 iInputBufferUnderConstruction = NULL;
    317             }
    318             iObtainNewInputBuffer = true;
    319 
    320         }
    321 
    322         // needed to init the sequence numbers and timestamp for partial frame assembly
    323         iFirstDataMsgAfterBOS = true;
    324         iKeepDroppingMsgsUntilMarkerBit = false;
    325 
    326         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
    327                         (0, "PVMFOMXAudioDecNode::ProcessIncomingMsg: Received BOS stream %d, timestamp %d", iStreamID, iBOSTimestamp));
    328         ((PVMFOMXDecPort*)aPort)->iNumFramesConsumed++;
    329         return true;
    330     }
    331     else if (msg->getFormatID() == PVMF_MEDIA_CMD_EOS_FORMAT_ID)
    332     {
    333         // Set EOS flag
    334         iEndOfDataReached = true;
    335         // Save the timestamp for the EOS cmd
    336         iEndOfDataTimestamp = msg->getTimestamp();
    337 
    338         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
    339                         (0, "PVMFOMXAudioDecNode::ProcessIncomingMsg: Received EOS"));
    340 
    341         ((PVMFOMXDecPort*)aPort)->iNumFramesConsumed++;
    342         return true; // do not do conversion into media data, just set the flag and leave
    343     }
    344 
    345 
    346     ///////////////////////////////////////////////////////////////////////////////////////
    347     ///////////////////////////////////////////////////////////////////////
    348     // For LATM data, need to convert to raw bitstream
    349     if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_LATM)
    350     {
    351         // Keep looping and parsing LATM data until frame complete or data queue runs out
    352         uint8 retval; //=FRAME_INCOMPLETE;
    353         // if LATM parser does not exist (very first frame), create it:
    354         if (iLATMParser == NULL)
    355         {
    356             // Create and configure the LATM parser based on the stream MUX config
    357             // which should be sent as the format specific config in the first media data
    358             if (CreateLATMParser() != PVMFSuccess)
    359             {
    360 
    361                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
    362                                 (0, "PVMFOMXAudioDecNode::Process Incoming Msg - LATM parser cannot be created"));
    363                 OSCL_ASSERT(false);
    364                 ReportErrorEvent(PVMFErrResourceConfiguration);
    365                 ChangeNodeState(EPVMFNodeError);
    366                 return true;
    367             }
    368 
    369             // get FSI
    370             OsclRefCounterMemFrag DataFrag;
    371             msg->getFormatSpecificInfo(DataFrag);
    372 
    373             //get pointer to the data fragment
    374             uint8* initbuffer = (uint8 *) DataFrag.getMemFragPtr();
    375             uint32 initbufsize = (int32) DataFrag.getMemFragSize();
    376 
    377             iLATMConfigBufferSize = initbufsize;
    378             iLATMConfigBuffer = iLATMParser->ParseStreamMuxConfig(initbuffer, (int32 *) & iLATMConfigBufferSize);
    379             if (iLATMConfigBuffer == NULL)
    380             {
    381                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
    382                                 (0, "PVMFOMXAudioDecNode::ProcessIncomingMsg() LATM Stream MUX config parsing failed"));
    383                 OSCL_ASSERT(false);
    384                 ReportErrorEvent(PVMFErrResourceConfiguration);
    385                 ChangeNodeState(EPVMFNodeError);
    386                 return true;
    387             }
    388 
    389         }
    390 
    391         do
    392         {
    393             if (msg->getFormatID() == PVMF_MEDIA_CMD_EOS_FORMAT_ID)
    394             {
    395                 // Set EOS flag
    396                 iEndOfDataReached = true;
    397                 // Save the timestamp for the EOS cmd
    398                 iEndOfDataTimestamp = msg->getTimestamp();
    399 
    400                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
    401                                 (0, "PVMFOMXAudioDecNode::ProcessIncomingMsg: Received EOS"));
    402 
    403                 ((PVMFOMXDecPort*)aPort)->iNumFramesConsumed++;
    404                 return true; // do not do conversion into media data, just set the flag and leave
    405 
    406             }
    407             // Convert the next input media msg to media data
    408             PVMFSharedMediaDataPtr mediaData;
    409             convertToPVMFMediaData(mediaData, msg);
    410 
    411 
    412             ((PVMFOMXDecPort*)aPort)->iNumFramesConsumed++;
    413 
    414             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iDataPathLogger, PVLOGMSG_INFO,
    415                             (0, "PVMFOMXAudioDecNode::ProcessIncomingMsg: TS=%d, SEQNUM= %d", msg->getTimestamp(), msg->getSeqNum()));
    416 
    417 
    418             // Convert the LATM data to raw bitstream
    419             retval = iLATMParser->compose(mediaData);
    420 
    421             // if frame is complete, break out of the loop
    422             if (retval != FRAME_INCOMPLETE && retval != FRAME_ERROR)
    423                 break;
    424 
    425             // frame is not complete, keep looping
    426             if (aPort->IncomingMsgQueueSize() == 0)
    427             {
    428                 // no more data in the input port queue, unbind current msg, and return
    429                 msg.Unbind();
    430                 // enable reading more data from port
    431                 break;
    432             }
    433             else
    434             {
    435                 msg.Unbind();
    436                 aPort->DequeueIncomingMsg(msg); // dequeue the message directly from input port
    437 
    438             }
    439 
    440             // Log parser error
    441             if (retval == FRAME_ERROR)
    442             {
    443                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
    444                                 (0, "PVMFAACDecNode::GetInputMediaData() LATM parser error"));
    445             }
    446         }
    447         while ((retval == FRAME_INCOMPLETE || retval == FRAME_ERROR));
    448 
    449         if (retval == FRAME_COMPLETE)
    450         {
    451             // Save the media data containing the parser data as the input media data
    452             iDataIn = iLATMParser->GetOutputBuffer();
    453             // set the MARKER bit on the data msg, since this is a complete frame produced by LATM parser
    454             iDataIn->setMarkerInfo(PVMF_MEDIA_DATA_MARKER_INFO_M_BIT);
    455             PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO,
    456                             (0, "PVMFOMXAudioDecNode::ProcessIncomingMsg: - LATM frame assembled"));
    457 
    458         }
    459         else if ((retval == FRAME_INCOMPLETE) || (retval == FRAME_ERROR))
    460         {
    461             // Do nothing and wait for more data to come in
    462             PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO,
    463                             (0, "PVMFOMXAudioDecNode::ProcessIncomingMsg: - incomplete LATM"));
    464             // return immediately (i.e. don't assign anything to iDataIn, which will prevent
    465             // processing
    466             return true;
    467         }
    468         else if (retval == FRAME_OUTPUTNOTAVAILABLE)
    469         {
    470             // This should not happen since this node processes one parsed media data at a time
    471             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
    472                             (0, "PVMFOMXAudioDecNode::ProcessIncomingMsg: LATM parser OUTPUT NOT AVAILABLE"));
    473 
    474             msg.Unbind();
    475 
    476             OSCL_ASSERT(false);
    477             ReportErrorEvent(PVMFErrResourceConfiguration);
    478             ChangeNodeState(EPVMFNodeError);
    479 
    480             return true;
    481         }
    482     }
    483 /////////////////////////////////////////////////////////
    484     //////////////////////////
    485     else
    486     {
    487         // regular (i.e. Non-LATM case)
    488         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iDataPathLogger, PVLOGMSG_INFO,
    489                         (0, "PVMFOMXAudioDecNode::ProcessIncomingMsg: TS=%d, SEQNUM= %d", msg->getTimestamp(), msg->getSeqNum()));
    490 
    491         convertToPVMFMediaData(iDataIn, msg);
    492         ((PVMFOMXDecPort*)aPort)->iNumFramesConsumed++;
    493     }
    494 
    495     iCurrFragNum = 0; // for new message, reset the fragment counter
    496     iIsNewDataFragment = true;
    497 
    498 
    499     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXAudioDecNode::ProcessIncomingMsg() Received %d frames", ((PVMFOMXDecPort*)aPort)->iNumFramesConsumed));
    500 
    501     //return true if we processed an activity...
    502     return true;
    503 }
    504 
    505 /////////////////////////////////////////////////////////////////////////////
    506 // This routine will handle the PortReEnable state
    507 /////////////////////////////////////////////////////////////////////////////
    508 PVMFStatus PVMFOMXAudioDecNode::HandlePortReEnable()
    509 {
    510     // set the port index so that we get parameters for the proper port
    511     iParamPort.nPortIndex = iPortIndexForDynamicReconfig;
    512 
    513     CONFIG_SIZE_AND_VERSION(iParamPort);
    514 
    515     // get new parameters of the port
    516     OMX_GetParameter(iOMXDecoder, OMX_IndexParamPortDefinition, &iParamPort);
    517 
    518     // send command for port re-enabling (for this to happen, we must first recreate the buffers)
    519     OMX_SendCommand(iOMXDecoder, OMX_CommandPortEnable, iPortIndexForDynamicReconfig, NULL);
    520 
    521 
    522     // get also input info (for frame duration if necessary)
    523     OMX_ERRORTYPE Err;
    524     OMX_PTR CodecProfilePtr;
    525     OMX_INDEXTYPE CodecProfileIndx;
    526     OMX_AUDIO_PARAM_AACPROFILETYPE Audio_Aac_Param;
    527 
    528     // determine the proper index and structure (based on codec type)
    529     if (iInPort)
    530     {
    531         // AAC
    532         if (((PVMFOMXDecPort*)iInPort)->iFormat ==  PVMF_MIME_MPEG4_AUDIO ||
    533                 ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_3640 ||
    534                 ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_LATM ||
    535                 ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_ADIF ||
    536                 ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_ASF_MPEG4_AUDIO ||
    537                 ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AAC_SIZEHDR) // for testing
    538         {
    539             CodecProfilePtr = (OMX_PTR) & Audio_Aac_Param;
    540             CodecProfileIndx = OMX_IndexParamAudioAac;
    541             Audio_Aac_Param.nPortIndex = iInputPortIndex;
    542 
    543             CONFIG_SIZE_AND_VERSION(Audio_Aac_Param);
    544 
    545 
    546             // get parameters:
    547             Err = OMX_GetParameter(iOMXDecoder, CodecProfileIndx, CodecProfilePtr);
    548             if (Err != OMX_ErrorNone)
    549             {
    550                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
    551                                 (0, "PVMFOMXAudioDecNode::HandlePortReEnable() Port Reconfiguration -> Input port parameters problem"));
    552 
    553                 SetState(EPVMFNodeError);
    554                 ReportErrorEvent(PVMFErrResource);
    555                 return PVMFErrResource;
    556             }
    557         }
    558         // for AMR, frame sizes are known, no need to get the parameters
    559         // for MP3, frame sizes cannot be obtained through OMX params
    560         // for WMA, frame sizes cannot be obtained through OMX params
    561     }
    562 
    563 
    564 
    565     PVMFFormatType Format = PVMF_MIME_FORMAT_UNKNOWN;
    566     if (iInPort != NULL)
    567     {
    568         Format = ((PVMFOMXDecPort*)iInPort)->iFormat;
    569     }
    570     if (Format ==  PVMF_MIME_MPEG4_AUDIO ||
    571             Format == PVMF_MIME_3640 ||
    572             Format == PVMF_MIME_LATM ||
    573             Format == PVMF_MIME_ADIF ||
    574             Format == PVMF_MIME_ASF_MPEG4_AUDIO ||
    575             Format == PVMF_MIME_AAC_SIZEHDR) // for testing
    576     {
    577         iSamplesPerFrame = Audio_Aac_Param.nFrameLength;
    578     }
    579     // AMR
    580     else if (Format == PVMF_MIME_AMR_IF2 ||
    581              Format == PVMF_MIME_AMR_IETF ||
    582              Format == PVMF_MIME_AMR)
    583     {
    584         // AMR NB has fs=8khz Mono and the frame is 20ms long, i.e. there is 160 samples per frame
    585         iSamplesPerFrame = PVOMXAUDIODEC_AMRNB_SAMPLES_PER_FRAME;
    586     }
    587     else if (Format == PVMF_MIME_AMRWB_IETF ||
    588              Format == PVMF_MIME_AMRWB)
    589     {
    590         // AMR WB has fs=16khz Mono and the frame is 20ms long, i.e. there is 320 samples per frame
    591         iSamplesPerFrame = PVOMXAUDIODEC_AMRWB_SAMPLES_PER_FRAME;
    592     }
    593     else if (Format == PVMF_MIME_MP3)
    594     {
    595         // frame size is either 576 or 1152 samples per frame. However, this information cannot be
    596         // obtained through OMX MP3 Params. Assume that it's 1152
    597         iSamplesPerFrame = PVOMXAUDIODEC_MP3_DEFAULT_SAMPLES_PER_FRAME;
    598     }
    599     else if (Format == PVMF_MIME_WMA)
    600     {
    601         // output frame size is unknown in WMA. However, the PV-WMA decoder can control the number
    602         // of samples it places in an output buffer, so we can create an output buffer of arbitrary size
    603         // and let the decoder control how it is filled
    604         iSamplesPerFrame = 0; // unknown
    605     }
    606 
    607     // is this output port?
    608     if (iPortIndexForDynamicReconfig == iOutputPortIndex)
    609     {
    610 
    611         // GET the output buffer params and sizes
    612         OMX_AUDIO_PARAM_PCMMODETYPE Audio_Pcm_Param;
    613         Audio_Pcm_Param.nPortIndex = iOutputPortIndex; // we're looking for output port params
    614 
    615         CONFIG_SIZE_AND_VERSION(Audio_Pcm_Param);
    616 
    617 
    618 
    619         Err = OMX_GetParameter(iOMXDecoder, OMX_IndexParamAudioPcm, &Audio_Pcm_Param);
    620         if (Err != OMX_ErrorNone)
    621         {
    622             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
    623                             (0, "PVMFOMXAudioDecNode::HandlePortReEnable() Port Reconfiguration -> Cannot get component output parameters"));
    624 
    625             SetState(EPVMFNodeError);
    626             ReportErrorEvent(PVMFErrResource);
    627             return PVMFErrResource;
    628         }
    629 
    630         iPCMSamplingRate = Audio_Pcm_Param.nSamplingRate; // can be set to 0 (if unknown)
    631 
    632         if (iPCMSamplingRate == 0) // use default sampling rate (i.e. 48000)
    633             iPCMSamplingRate = PVOMXAUDIODEC_DEFAULT_SAMPLINGRATE;
    634 
    635         iNumberOfAudioChannels = Audio_Pcm_Param.nChannels;     // should be 1 or 2
    636         if (iNumberOfAudioChannels != 1 && iNumberOfAudioChannels != 2)
    637         {
    638             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
    639                             (0, "PVMFOMXAudioDecNode::HandlePortReEnable() Port Reconfiguration -> Output parameters num channels = %d", iNumberOfAudioChannels));
    640 
    641             SetState(EPVMFNodeError);
    642             ReportErrorEvent(PVMFErrResource);
    643             return PVMFErrResource;
    644         }
    645 
    646         if ((iSamplesPerFrame != 0) && ((iSamplesPerFrame * 1000) > iPCMSamplingRate))
    647             // if this iSamplesPerFrame is known and is large enough to ensure that the iMilliSecPerFrame calculation
    648             // below won't be set to 0.
    649         {
    650             // CALCULATE NumBytes per frame, Msec per frame, etc.
    651             iNumBytesPerFrame = 2 * iSamplesPerFrame * iNumberOfAudioChannels;
    652             iMilliSecPerFrame = (iSamplesPerFrame * 1000) / iPCMSamplingRate;
    653             // Determine the size of each PCM output buffer. Size would be big enough to hold certain time amount of PCM data
    654             uint32 numframes = PVOMXAUDIODEC_DEFAULT_OUTPUTPCM_TIME / iMilliSecPerFrame;
    655 
    656             if (PVOMXAUDIODEC_DEFAULT_OUTPUTPCM_TIME % iMilliSecPerFrame)
    657             {
    658                 // If there is a remainder, include one more frame
    659                 ++numframes;
    660             }
    661 
    662             // set the output buffer size accordingly:
    663             iOMXComponentOutputBufferSize = numframes * iNumBytesPerFrame;
    664         }
    665         else
    666             iOMXComponentOutputBufferSize = (2 * iNumberOfAudioChannels * PVOMXAUDIODEC_DEFAULT_OUTPUTPCM_TIME * iPCMSamplingRate) / 1000; // assuming 16 bits per sample
    667 
    668         if (iOMXComponentOutputBufferSize < iParamPort.nBufferSize)
    669         {
    670             // the OMX spec says that nBuffersize is a read only field, but the client is allowed to allocate
    671             // a buffer size larger than nBufferSize.
    672             iOMXComponentOutputBufferSize = iParamPort.nBufferSize;
    673         }
    674 
    675 
    676         // do we need to increase the number of buffers?
    677         if (iNumOutputBuffers < iParamPort.nBufferCountMin)
    678             iNumOutputBuffers = iParamPort.nBufferCountMin;
    679 
    680         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
    681                         (0, "PVMFOMXAudioDecNode::HandlePortReEnable() new output buffers %d, size %d", iNumOutputBuffers, iOMXComponentOutputBufferSize));
    682 
    683         //Send the FSI information to media output node here, before setting output
    684         //port parameters to the omx component
    685         // Check if Fsi configuration need to be sent
    686         sendFsi = true;
    687         iCompactFSISettingSucceeded = false;
    688 
    689         if (sendFsi)
    690         {
    691             int fsiErrorCode = 0;
    692 
    693             OsclRefCounterMemFrag FsiMemfrag;
    694 
    695             OSCL_TRY(fsiErrorCode, FsiMemfrag = iFsiFragmentAlloc.get(););
    696 
    697             OSCL_FIRST_CATCH_ANY(fsiErrorCode, PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
    698                                  (0, "PVMFOMXAudioDecNode::HandlePortReEnable() Failed to allocate memory for  FSI")));
    699 
    700             if (fsiErrorCode == 0)
    701             {
    702                 channelSampleInfo* pcminfo = (channelSampleInfo*) FsiMemfrag.getMemFragPtr();
    703 
    704                 if (pcminfo != NULL)
    705                 {
    706                     OSCL_ASSERT(pcminfo != NULL);
    707 
    708                     pcminfo->samplingRate    = iPCMSamplingRate;
    709                     pcminfo->desiredChannels = iNumberOfAudioChannels;
    710                     pcminfo->bitsPerSample = 16;
    711                     pcminfo->num_buffers = iNumOutputBuffers;
    712                     pcminfo->buffer_size = iOMXComponentOutputBufferSize;
    713 
    714                     OsclMemAllocator alloc;
    715                     int32 KeyLength = oscl_strlen(PVMF_FORMAT_SPECIFIC_INFO_KEY_PCM) + 1;
    716                     PvmiKeyType KvpKey = (PvmiKeyType)alloc.ALLOCATE(KeyLength);
    717 
    718                     if (NULL == KvpKey)
    719                     {
    720                         return false;
    721                     }
    722 
    723                     oscl_strncpy(KvpKey, PVMF_FORMAT_SPECIFIC_INFO_KEY_PCM, KeyLength);
    724                     int32 err;
    725 
    726                     OSCL_TRY(err, ((PVMFOMXDecPort*)iOutPort)->pvmiSetPortFormatSpecificInfoSync(FsiMemfrag, KvpKey););
    727                     if (err != OsclErrNone)
    728                     {
    729                         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
    730                                         (0, "PVMFOMXAudioDecNode::HandlePortReEnable - Problem to set FSI"));
    731                     }
    732                     else
    733                     {
    734                         sendFsi = false;
    735                         iCompactFSISettingSucceeded = true;
    736                     }
    737 
    738 
    739                     alloc.deallocate((OsclAny*)(KvpKey));
    740                 }
    741                 else
    742                 {
    743                     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
    744                                     (0, "PVMFOMXAudioDecNode::HandlePortReEnable - Problem allocating Output FSI"));
    745                     SetState(EPVMFNodeError);
    746                     ReportErrorEvent(PVMFErrNoMemory);
    747                     return false; // this is going to make everything go out of scope
    748                 }
    749             }
    750             else
    751             {
    752                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
    753                                 (0, "PVMFOMXAudioDecNode::HandlePortReEnable - Problem allocating Output FSI"));
    754                 return false; // this is going to make everything go out of scope
    755             }
    756 
    757 
    758         }
    759 
    760 
    761         //Buffer allocator kvp query and allocation has to be done again if we landed into handle port reconfiguration
    762 
    763         PvmiKvp* kvp = NULL;
    764         int numKvp = 0;
    765         PvmiKeyType aIdentifier = (PvmiKeyType)PVMF_BUFFER_ALLOCATOR_KEY;
    766         int32 err, err1;
    767         ipExternalOutputBufferAllocatorInterface = NULL;
    768 
    769         OSCL_TRY(err, ((PVMFOMXDecPort*)iOutPort)->pvmiGetBufferAllocatorSpecificInfoSync(aIdentifier, kvp, numKvp););
    770 
    771         if ((err == OsclErrNone) && (NULL != kvp))
    772         {
    773             ipExternalOutputBufferAllocatorInterface = (PVInterface *)kvp->value.key_specific_value;
    774 
    775             if (ipExternalOutputBufferAllocatorInterface)
    776             {
    777                 PVInterface* pTempPVInterfacePtr = NULL;
    778                 OSCL_TRY(err, ipExternalOutputBufferAllocatorInterface->queryInterface(PVMFFixedSizeBufferAllocUUID, pTempPVInterfacePtr););
    779 
    780                 OSCL_TRY(err1, ((PVMFOMXDecPort*)iOutPort)->releaseParametersSync(kvp, numKvp););
    781 
    782                 if (err1 != OsclErrNone)
    783                 {
    784                     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
    785                                     (0, "PVMFOMXAudioDecNode::HandlePortReEnable - Unable to Release Parameters"));
    786                 }
    787 
    788                 if ((err == OsclErrNone) && (NULL != pTempPVInterfacePtr))
    789                 {
    790                     ipFixedSizeBufferAlloc = OSCL_STATIC_CAST(PVMFFixedSizeBufferAlloc*, pTempPVInterfacePtr);
    791 
    792                     uint32 iNumBuffers, iBufferSize;
    793 
    794                     iNumBuffers = ipFixedSizeBufferAlloc->getNumBuffers();
    795                     iBufferSize = ipFixedSizeBufferAlloc->getBufferSize();
    796 
    797                     if ((iNumBuffers < iParamPort.nBufferCountMin) || (iBufferSize < iOMXComponentOutputBufferSize))
    798                     {
    799                         ipExternalOutputBufferAllocatorInterface->removeRef();
    800                         ipExternalOutputBufferAllocatorInterface = NULL;
    801                     }
    802                     else
    803                     {
    804                         iNumOutputBuffers = iNumBuffers;
    805                         iOMXComponentOutputBufferSize = iBufferSize;
    806                     }
    807 
    808                 }
    809                 else
    810                 {
    811                     ipExternalOutputBufferAllocatorInterface->removeRef();
    812                     ipExternalOutputBufferAllocatorInterface = NULL;
    813                 }
    814             }
    815         }
    816 
    817 
    818         /* Allocate output buffers */
    819         if (!CreateOutMemPool(iNumOutputBuffers))
    820         {
    821 
    822             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
    823                             (0, "PVMFOMXAudioDecNode::HandlePortReEnable() Port Reconfiguration -> Cannot allocate output buffers "));
    824 
    825             SetState(EPVMFNodeError);
    826             ReportErrorEvent(PVMFErrNoMemory);
    827             return PVMFErrNoMemory;
    828         }
    829 
    830         if (out_ctrl_struct_ptr == NULL)
    831         {
    832 
    833             out_ctrl_struct_ptr = (OsclAny **) oscl_malloc(iNumOutputBuffers * sizeof(OsclAny *));
    834 
    835             if (out_ctrl_struct_ptr == NULL)
    836             {
    837                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
    838                                 (0, "PVMFOMXAudioDecNode::HandlePortReEnable() out_ctrl_struct_ptr == NULL"));
    839 
    840                 SetState(EPVMFNodeError);
    841                 ReportErrorEvent(PVMFErrNoMemory);
    842                 return PVMFErrNoMemory;
    843             }
    844         }
    845 
    846         if (out_buff_hdr_ptr == NULL)
    847         {
    848 
    849             out_buff_hdr_ptr = (OsclAny **) oscl_malloc(iNumOutputBuffers * sizeof(OsclAny *));
    850 
    851             if (out_buff_hdr_ptr == NULL)
    852             {
    853                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
    854                                 (0, "PVMFOMXAudioDecNode::HandlePortReEnable()  out_buff_hdr_ptr == NULL"));
    855 
    856                 SetState(EPVMFNodeError);
    857                 ReportErrorEvent(PVMFErrNoMemory);
    858                 return PVMFErrNoMemory;
    859             }
    860         }
    861 
    862 
    863         if (!ProvideBuffersToComponent(iOutBufMemoryPool, // allocator
    864                                        iOutputAllocSize,     // size to allocate from pool (hdr only or hdr+ buffer)
    865                                        iNumOutputBuffers, // number of buffers
    866                                        iOMXComponentOutputBufferSize, // actual buffer size
    867                                        iOutputPortIndex, // port idx
    868                                        iOMXComponentSupportsExternalOutputBufferAlloc, // can component use OMX_UseBuffer
    869                                        false // this is not input
    870                                       ))
    871         {
    872 
    873 
    874             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
    875                             (0, "PVMFOMXAudioDecNode::HandlePortReEnable() Port Reconfiguration -> Cannot provide output buffers to component"));
    876 
    877             SetState(EPVMFNodeError);
    878             ReportErrorEvent(PVMFErrNoMemory);
    879             return PVMFErrNoMemory;
    880 
    881         }
    882 
    883         // do not drop output any more, i.e. enable output to be sent downstream
    884         iDoNotSendOutputBuffersDownstreamFlag = false;
    885 
    886 
    887     }
    888     else
    889     {
    890         // this is input port
    891 
    892         iOMXComponentInputBufferSize = iParamPort.nBufferSize;
    893         // do we need to increase the number of buffers?
    894         if (iNumInputBuffers < iParamPort.nBufferCountMin)
    895             iNumInputBuffers = iParamPort.nBufferCountMin;
    896 
    897         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
    898                         (0, "PVMFOMXAudioDecNode::HandlePortReEnable() new buffers %d, size %d", iNumInputBuffers, iOMXComponentInputBufferSize));
    899 
    900         /* Allocate input buffers */
    901         if (!CreateInputMemPool(iNumInputBuffers))
    902         {
    903             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
    904                             (0, "PVMFOMXAudioDecNode::HandlePortReEnable() Port Reconfiguration -> Cannot allocate new input buffers to component"));
    905 
    906             SetState(EPVMFNodeError);
    907             ReportErrorEvent(PVMFErrNoMemory);
    908             return PVMFErrNoMemory;
    909         }
    910 
    911         if (in_ctrl_struct_ptr == NULL)
    912         {
    913 
    914             in_ctrl_struct_ptr = (OsclAny **) oscl_malloc(iNumInputBuffers * sizeof(OsclAny *));
    915 
    916             if (in_ctrl_struct_ptr == NULL)
    917             {
    918                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
    919                                 (0, "PVMFOMXAudioDecNode::HandlePortReEnable() in_ctrl_struct_ptr == NULL"));
    920 
    921                 SetState(EPVMFNodeError);
    922                 ReportErrorEvent(PVMFErrNoMemory);
    923                 return PVMFErrNoMemory;
    924             }
    925         }
    926 
    927         if (in_buff_hdr_ptr == NULL)
    928         {
    929 
    930             in_buff_hdr_ptr = (OsclAny **) oscl_malloc(iNumInputBuffers * sizeof(OsclAny *));
    931 
    932             if (in_buff_hdr_ptr == NULL)
    933             {
    934                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
    935                                 (0, "PVMFOMXAudioDecNode::HandlePortReEnable()  in_buff_hdr_ptr == NULL"));
    936 
    937                 SetState(EPVMFNodeError);
    938                 ReportErrorEvent(PVMFErrNoMemory);
    939                 return PVMFErrNoMemory;
    940             }
    941         }
    942 
    943 
    944         if (!ProvideBuffersToComponent(iInBufMemoryPool, // allocator
    945                                        iInputAllocSize,  // size to allocate from pool (hdr only or hdr+ buffer)
    946                                        iNumInputBuffers, // number of buffers
    947                                        iOMXComponentInputBufferSize, // actual buffer size
    948                                        iInputPortIndex, // port idx
    949                                        iOMXComponentSupportsExternalInputBufferAlloc, // can component use OMX_UseBuffer
    950                                        true // this is input
    951                                       ))
    952         {
    953 
    954 
    955             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
    956                             (0, "PVMFOMXAudioDecNode::HandlePortReEnable() Port Reconfiguration -> Cannot provide new input buffers to component"));
    957 
    958             SetState(EPVMFNodeError);
    959             ReportErrorEvent(PVMFErrNoMemory);
    960             return PVMFErrNoMemory;
    961 
    962         }
    963         // do not drop partially consumed input
    964         iDoNotSaveInputBuffersFlag = false;
    965 
    966     }
    967 
    968     // if the callback that the port was re-enabled has not arrived yet, wait for it
    969     // if it has arrived, it will set the state to either PortReconfig or to ReadyToDecode
    970     if (iProcessingState != EPVMFOMXBaseDecNodeProcessingState_PortReconfig &&
    971             iProcessingState != EPVMFOMXBaseDecNodeProcessingState_ReadyToDecode)
    972         iProcessingState = EPVMFOMXBaseDecNodeProcessingState_WaitForPortEnable;
    973 
    974     return PVMFSuccess; // allow rescheduling of the node
    975 }
    976 ////////////////////////////////////////////////////////////////////////////////
    977 bool PVMFOMXAudioDecNode::NegotiateComponentParameters(OMX_PTR aOutputParameters)
    978 {
    979     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
    980                     (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() In"));
    981 
    982     OMX_ERRORTYPE Err;
    983     // first get the number of ports and port indices
    984     OMX_PORT_PARAM_TYPE AudioPortParameters;
    985     uint32 NumPorts;
    986     uint32 ii;
    987 
    988 
    989     pvAudioConfigParserInputs aInputs;
    990     AudioOMXConfigParserOutputs *pOutputParameters;
    991 
    992     aInputs.inPtr = (uint8*)((PVMFOMXDecPort*)iInPort)->iTrackConfig;
    993     aInputs.inBytes = (int32)((PVMFOMXDecPort*)iInPort)->iTrackConfigSize;
    994     aInputs.iMimeType = ((PVMFOMXDecPort*)iInPort)->iFormat;
    995     pOutputParameters = (AudioOMXConfigParserOutputs *)aOutputParameters;
    996 
    997     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
    998                     (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() Calling audio config parser - TrackConfig = %p, TrackConfigSize = %d, mimetype = %s", aInputs.inPtr, aInputs.inBytes, aInputs.iMimeType.getMIMEStrPtr()));
    999 
   1000 
   1001 
   1002     if (aInputs.iMimeType == PVMF_MIME_WMA)
   1003     {
   1004         iNumberOfAudioChannels = pOutputParameters->Channels;
   1005         iPCMSamplingRate = pOutputParameters->SamplesPerSec;
   1006     }
   1007     else if (aInputs.iMimeType == PVMF_MIME_MPEG4_AUDIO ||
   1008              aInputs.iMimeType == PVMF_MIME_3640 ||
   1009              aInputs.iMimeType == PVMF_MIME_LATM ||
   1010              aInputs.iMimeType == PVMF_MIME_ADIF ||
   1011              aInputs.iMimeType == PVMF_MIME_ASF_MPEG4_AUDIO ||
   1012              aInputs.iMimeType == PVMF_MIME_AAC_SIZEHDR)
   1013 
   1014     {
   1015         iNumberOfAudioChannels = pOutputParameters->Channels;
   1016     }
   1017 
   1018     CONFIG_SIZE_AND_VERSION(AudioPortParameters);
   1019     // get starting number
   1020     Err = OMX_GetParameter(iOMXDecoder, OMX_IndexParamAudioInit, &AudioPortParameters);
   1021     NumPorts = AudioPortParameters.nPorts; // must be at least 2 of them (in&out)
   1022 
   1023     if (Err != OMX_ErrorNone || NumPorts < 2)
   1024     {
   1025         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1026                         (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() There is insuffucient (%d) ports", NumPorts));
   1027         return false;
   1028     }
   1029 
   1030 
   1031     // loop through ports starting from the starting index to find index of the first input port
   1032     for (ii = AudioPortParameters.nStartPortNumber ; ii < AudioPortParameters.nStartPortNumber + NumPorts; ii++)
   1033     {
   1034         // get port parameters, and determine if it is input or output
   1035         // if there are more than 2 ports, the first one we encounter that has input direction is picked
   1036 
   1037         iParamPort.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
   1038 
   1039         //port
   1040         iParamPort.nPortIndex = ii;
   1041 
   1042         CONFIG_SIZE_AND_VERSION(iParamPort);
   1043 
   1044         Err = OMX_GetParameter(iOMXDecoder, OMX_IndexParamPortDefinition, &iParamPort);
   1045 
   1046         if (Err != OMX_ErrorNone)
   1047         {
   1048             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1049                             (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() Problem negotiating with port %d ", ii));
   1050 
   1051             return false;
   1052         }
   1053 
   1054         if (iParamPort.eDir == OMX_DirInput)
   1055         {
   1056             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1057                             (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() Found Input port index %d ", ii));
   1058 
   1059             iInputPortIndex = ii;
   1060             break;
   1061         }
   1062     }
   1063     if (ii == AudioPortParameters.nStartPortNumber + NumPorts)
   1064     {
   1065         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1066                         (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() Cannot find any input port "));
   1067         return false;
   1068     }
   1069 
   1070 
   1071     // loop through ports starting from the starting index to find index of the first output port
   1072     for (ii = AudioPortParameters.nStartPortNumber ; ii < AudioPortParameters.nStartPortNumber + NumPorts; ii++)
   1073     {
   1074         // get port parameters, and determine if it is input or output
   1075         // if there are more than 2 ports, the first one we encounter that has output direction is picked
   1076 
   1077 
   1078         //port
   1079         iParamPort.nPortIndex = ii;
   1080 
   1081         CONFIG_SIZE_AND_VERSION(iParamPort);
   1082 
   1083         Err = OMX_GetParameter(iOMXDecoder, OMX_IndexParamPortDefinition, &iParamPort);
   1084 
   1085         if (Err != OMX_ErrorNone)
   1086         {
   1087             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1088                             (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() Problem negotiating with port %d ", ii));
   1089 
   1090             return false;
   1091         }
   1092 
   1093         if (iParamPort.eDir == OMX_DirOutput)
   1094         {
   1095             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1096                             (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() Found Output port index %d ", ii));
   1097 
   1098             iOutputPortIndex = ii;
   1099             break;
   1100         }
   1101     }
   1102     if (ii == AudioPortParameters.nStartPortNumber + NumPorts)
   1103     {
   1104         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1105                         (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() Cannot find any output port "));
   1106         return false;
   1107     }
   1108 
   1109 
   1110 
   1111     // now get input parameters
   1112 
   1113     CONFIG_SIZE_AND_VERSION(iParamPort);
   1114 
   1115     //Input port
   1116     iParamPort.nPortIndex = iInputPortIndex;
   1117     Err = OMX_GetParameter(iOMXDecoder, OMX_IndexParamPortDefinition, &iParamPort);
   1118     if (Err != OMX_ErrorNone)
   1119     {
   1120         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1121                         (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() Problem negotiating with input port %d ", iInputPortIndex));
   1122         return false;
   1123     }
   1124 
   1125     // preset the number of input buffers
   1126     //iNumInputBuffers = NUMBER_INPUT_BUFFER;
   1127     iNumInputBuffers = iParamPort.nBufferCountActual;  // use the value provided by component
   1128 
   1129     // do we need to increase the number of buffers?
   1130     if (iNumInputBuffers < iParamPort.nBufferCountMin)
   1131         iNumInputBuffers = iParamPort.nBufferCountMin;
   1132 
   1133     iOMXComponentInputBufferSize = iParamPort.nBufferSize;
   1134 
   1135     iParamPort.nBufferCountActual = iNumInputBuffers;
   1136 
   1137     // set the number of actual input buffers
   1138     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1139                     (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() Inport buffers %d,size %d", iNumInputBuffers, iOMXComponentInputBufferSize));
   1140 
   1141 
   1142 
   1143 
   1144     CONFIG_SIZE_AND_VERSION(iParamPort);
   1145     iParamPort.nPortIndex = iInputPortIndex;
   1146     // finalize setting input port parameters
   1147     Err = OMX_SetParameter(iOMXDecoder, OMX_IndexParamPortDefinition, &iParamPort);
   1148     if (Err != OMX_ErrorNone)
   1149     {
   1150         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1151                         (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() Problem setting parameters in input port %d ", iInputPortIndex));
   1152         return false;
   1153     }
   1154 
   1155 
   1156     // in case of WMA - config parser decodes config info and produces reliable numchannels and sampling rate
   1157     // set these values now to prevent unnecessary port reconfig
   1158     if (aInputs.iMimeType == PVMF_MIME_WMA)
   1159     {
   1160         // First get the structure
   1161         OMX_AUDIO_PARAM_PCMMODETYPE Audio_Pcm_Param;
   1162         Audio_Pcm_Param.nPortIndex = iOutputPortIndex; // we're looking for output port params
   1163         CONFIG_SIZE_AND_VERSION(Audio_Pcm_Param);
   1164 
   1165         Err = OMX_GetParameter(iOMXDecoder, OMX_IndexParamAudioPcm, &Audio_Pcm_Param);
   1166         if (Err != OMX_ErrorNone)
   1167         {
   1168             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1169                             (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() Problem negotiating PCM parameters with output port %d ", iOutputPortIndex));
   1170             return false;
   1171         }
   1172 
   1173         // set the sampling rate obtained from config parser
   1174         Audio_Pcm_Param.nSamplingRate = iPCMSamplingRate; // can be set to 0 (if unknown)
   1175 
   1176         // set number of channels obtained from config parser
   1177         Audio_Pcm_Param.nChannels = iNumberOfAudioChannels;     // should be 1 or 2
   1178 
   1179         // Now, set the parameters
   1180         Audio_Pcm_Param.nPortIndex = iOutputPortIndex; // we're looking for output port params
   1181         CONFIG_SIZE_AND_VERSION(Audio_Pcm_Param);
   1182 
   1183         Err = OMX_SetParameter(iOMXDecoder, OMX_IndexParamAudioPcm, &Audio_Pcm_Param);
   1184         if (Err != OMX_ErrorNone)
   1185         {
   1186             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1187                             (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() Problem Setting PCM parameters with output port %d ", iOutputPortIndex));
   1188             return false;
   1189         }
   1190 
   1191     }
   1192 
   1193 
   1194     // Codec specific info set/get: SamplingRate, formats etc.
   1195     // NOTE: iParamPort is modified in the routine below - it is loaded from the component output port values
   1196     // Based on sampling rate - we also determine the desired output buffer size
   1197     if (!GetSetCodecSpecificInfo())
   1198         return false;
   1199 
   1200 
   1201 
   1202     //Port 1 for output port
   1203     iParamPort.nPortIndex = iOutputPortIndex;
   1204 
   1205     CONFIG_SIZE_AND_VERSION(iParamPort);
   1206 
   1207     Err = OMX_GetParameter(iOMXDecoder, OMX_IndexParamPortDefinition, &iParamPort);
   1208     if (Err != OMX_ErrorNone)
   1209     {
   1210         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1211                         (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() Problem negotiating with output port %d ", iOutputPortIndex));
   1212         return false;
   1213     }
   1214 
   1215     // set number of output buffers and the size
   1216     iNumOutputBuffers = iParamPort.nBufferCountActual;
   1217 
   1218     if (iNumOutputBuffers > NUMBER_OUTPUT_BUFFER)
   1219         iNumOutputBuffers = NUMBER_OUTPUT_BUFFER; // make sure to limit this number to what the port can hold
   1220 
   1221 
   1222     if (iNumOutputBuffers < iParamPort.nBufferCountMin)
   1223         iNumOutputBuffers = iParamPort.nBufferCountMin;
   1224 
   1225 
   1226     //Send the FSI information to media output node here, before setting output
   1227     //port parameters to the omx component
   1228 
   1229     // Check if Fsi configuration need to be sent
   1230     sendFsi = true;
   1231     iCompactFSISettingSucceeded = false;
   1232     if (sendFsi)
   1233     {
   1234         int fsiErrorCode = 0;
   1235 
   1236         OsclRefCounterMemFrag FsiMemfrag;
   1237 
   1238         OSCL_TRY(fsiErrorCode, FsiMemfrag = iFsiFragmentAlloc.get(););
   1239 
   1240         OSCL_FIRST_CATCH_ANY(fsiErrorCode, PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   1241                              (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() Failed to allocate memory for  FSI")));
   1242 
   1243         if (fsiErrorCode == 0)
   1244         {
   1245             channelSampleInfo* pcminfo = (channelSampleInfo*) FsiMemfrag.getMemFragPtr();
   1246             if (pcminfo != NULL)
   1247             {
   1248                 OSCL_ASSERT(pcminfo != NULL);
   1249 
   1250                 pcminfo->samplingRate    = iPCMSamplingRate;
   1251                 pcminfo->desiredChannels = iNumberOfAudioChannels;
   1252                 pcminfo->bitsPerSample = 16;
   1253                 pcminfo->num_buffers = iNumOutputBuffers;
   1254                 pcminfo->buffer_size = iOMXComponentOutputBufferSize;
   1255 
   1256                 OsclMemAllocator alloc;
   1257                 int32 KeyLength = oscl_strlen(PVMF_FORMAT_SPECIFIC_INFO_KEY_PCM) + 1;
   1258                 PvmiKeyType KvpKey = (PvmiKeyType)alloc.ALLOCATE(KeyLength);
   1259 
   1260                 if (NULL == KvpKey)
   1261                 {
   1262                     return false;
   1263                 }
   1264 
   1265                 oscl_strncpy(KvpKey, PVMF_FORMAT_SPECIFIC_INFO_KEY_PCM, KeyLength);
   1266                 int32 err;
   1267 
   1268                 OSCL_TRY(err, ((PVMFOMXDecPort*)iOutPort)->pvmiSetPortFormatSpecificInfoSync(FsiMemfrag, KvpKey););
   1269                 if (err != OsclErrNone)
   1270                 {
   1271                     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
   1272                                     (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters - Problem to set FSI"));
   1273                 }
   1274                 else
   1275                 {
   1276                     sendFsi = false;
   1277                     iCompactFSISettingSucceeded = true;
   1278                 }
   1279 
   1280                 alloc.deallocate((OsclAny*)(KvpKey));
   1281 
   1282 
   1283             }
   1284             else
   1285             {
   1286                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
   1287                                 (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters - Problem allocating Output FSI"));
   1288                 SetState(EPVMFNodeError);
   1289                 ReportErrorEvent(PVMFErrNoMemory);
   1290                 return false; // this is going to make everything go out of scope
   1291             }
   1292         }
   1293         else
   1294         {
   1295             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
   1296                             (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters - Problem allocating Output FSI"));
   1297             return false; // this is going to make everything go out of scope
   1298         }
   1299 
   1300 
   1301     }
   1302 
   1303     //Try querying the buffer allocator KVP for output buffer allocation outside of the node
   1304     PvmiKvp* kvp = NULL;
   1305     int numKvp = 0;
   1306     PvmiKeyType aIdentifier = (PvmiKeyType)PVMF_BUFFER_ALLOCATOR_KEY;
   1307     int32 err, err1;
   1308     ipExternalOutputBufferAllocatorInterface = NULL;
   1309 
   1310     OSCL_TRY(err, ((PVMFOMXDecPort*)iOutPort)->pvmiGetBufferAllocatorSpecificInfoSync(aIdentifier, kvp, numKvp););
   1311 
   1312     if ((err == OsclErrNone) && (NULL != kvp))
   1313     {
   1314         ipExternalOutputBufferAllocatorInterface = (PVInterface*) kvp->value.key_specific_value;
   1315 
   1316         if (ipExternalOutputBufferAllocatorInterface)
   1317         {
   1318             PVInterface* pTempPVInterfacePtr = NULL;
   1319 
   1320             OSCL_TRY(err, ipExternalOutputBufferAllocatorInterface->queryInterface(PVMFFixedSizeBufferAllocUUID, pTempPVInterfacePtr););
   1321 
   1322             OSCL_TRY(err1, ((PVMFOMXDecPort*)iOutPort)->releaseParametersSync(kvp, numKvp););
   1323             if (err1 != OsclErrNone)
   1324             {
   1325                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
   1326                                 (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters - Unable to Release Parameters"));
   1327             }
   1328 
   1329             if ((err == OsclErrNone) && (NULL != pTempPVInterfacePtr))
   1330             {
   1331                 ipFixedSizeBufferAlloc = OSCL_STATIC_CAST(PVMFFixedSizeBufferAlloc*, pTempPVInterfacePtr);
   1332 
   1333                 uint32 iNumBuffers, iBufferSize;
   1334 
   1335                 iNumBuffers = ipFixedSizeBufferAlloc->getNumBuffers();
   1336                 iBufferSize = ipFixedSizeBufferAlloc->getBufferSize();
   1337 
   1338                 if ((iNumBuffers < iParamPort.nBufferCountMin) || (iBufferSize < iOMXComponentOutputBufferSize))
   1339                 {
   1340                     ipExternalOutputBufferAllocatorInterface->removeRef();
   1341                     ipExternalOutputBufferAllocatorInterface = NULL;
   1342                 }
   1343                 else
   1344                 {
   1345                     iNumOutputBuffers = iNumBuffers;
   1346                     iOMXComponentOutputBufferSize = iBufferSize;
   1347 
   1348                 }
   1349 
   1350             }
   1351             else
   1352             {
   1353                 ipExternalOutputBufferAllocatorInterface->removeRef();
   1354                 ipExternalOutputBufferAllocatorInterface = NULL;
   1355 
   1356             }
   1357         }
   1358     }
   1359 
   1360 
   1361     iParamPort.nBufferCountActual = iNumOutputBuffers;
   1362 
   1363     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1364                     (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() Outport buffers %d,size %d", iNumOutputBuffers, iOMXComponentOutputBufferSize));
   1365 
   1366     CONFIG_SIZE_AND_VERSION(iParamPort);
   1367     iParamPort.nPortIndex = iOutputPortIndex;
   1368     // finalize setting output port parameters
   1369     Err = OMX_SetParameter(iOMXDecoder, OMX_IndexParamPortDefinition, &iParamPort);
   1370     if (Err != OMX_ErrorNone)
   1371     {
   1372         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1373                         (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() Problem setting parameters in output port %d ", iOutputPortIndex));
   1374         return false;
   1375     }
   1376 
   1377     //Set input audio format
   1378     //This is need it since a single component could handle differents roles
   1379 
   1380     // Init to desire format
   1381     PVMFFormatType Format = PVMF_MIME_FORMAT_UNKNOWN;
   1382     if (iInPort != NULL)
   1383     {
   1384         Format = ((PVMFOMXDecPort*)iInPort)->iFormat;
   1385     }
   1386     if (Format == PVMF_MIME_MPEG4_AUDIO ||
   1387             Format == PVMF_MIME_3640 ||
   1388             Format == PVMF_MIME_LATM ||
   1389             Format == PVMF_MIME_ADIF ||
   1390             Format == PVMF_MIME_ASF_MPEG4_AUDIO ||
   1391             Format == PVMF_MIME_AAC_SIZEHDR)
   1392     {
   1393         iOMXAudioCompressionFormat = OMX_AUDIO_CodingAAC;
   1394     }
   1395     else if (Format == PVMF_MIME_AMR_IF2 ||
   1396              Format == PVMF_MIME_AMR_IETF ||
   1397              Format == PVMF_MIME_AMR ||
   1398              Format == PVMF_MIME_AMRWB_IETF ||
   1399              Format == PVMF_MIME_AMRWB)
   1400     {
   1401         iOMXAudioCompressionFormat = OMX_AUDIO_CodingAMR;
   1402     }
   1403     else if (Format == PVMF_MIME_MP3)
   1404     {
   1405         iOMXAudioCompressionFormat = OMX_AUDIO_CodingMP3;
   1406     }
   1407     else if (Format == PVMF_MIME_WMA)
   1408     {
   1409         iOMXAudioCompressionFormat = OMX_AUDIO_CodingWMA;
   1410     }
   1411     else
   1412     {
   1413         // Illegal codec specified.
   1414         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1415                         (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() Problem setting audio compression format"));
   1416         return false;
   1417     }
   1418 
   1419 
   1420     OMX_AUDIO_PARAM_PORTFORMATTYPE AudioPortFormat;
   1421     CONFIG_SIZE_AND_VERSION(AudioPortFormat);
   1422     AudioPortFormat.nPortIndex = iInputPortIndex;
   1423 
   1424     // Search the proper format index and set it.
   1425     // Since we already know that the component has the role we need, search until finding the proper nIndex
   1426     // if component does not find the format will return OMX_ErrorNoMore
   1427 
   1428     for (ii = 0;; ii++)
   1429     {
   1430         AudioPortFormat.nIndex = ii;
   1431         Err = OMX_GetParameter(iOMXDecoder, OMX_IndexParamAudioPortFormat, &AudioPortFormat);
   1432         if (Err != OMX_ErrorNone)
   1433         {
   1434             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1435                             (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() Problem setting audio compression format"));
   1436             return false;
   1437         }
   1438         if (iOMXAudioCompressionFormat == AudioPortFormat.eEncoding)
   1439         {
   1440             break;
   1441         }
   1442     }
   1443     // Now set the format to confirm parameters
   1444     Err = OMX_SetParameter(iOMXDecoder, OMX_IndexParamAudioPortFormat, &AudioPortFormat);
   1445     if (Err != OMX_ErrorNone)
   1446     {
   1447         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1448                         (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() Problem setting audio compression format"));
   1449         return false;
   1450     }
   1451 
   1452 
   1453     return true;
   1454 }
   1455 
   1456 bool PVMFOMXAudioDecNode::GetSetCodecSpecificInfo()
   1457 {
   1458 
   1459     // for AAC, need to let the decoder know about the type of AAC format. Need to get the frame length
   1460     // need to get the parameters
   1461     OMX_PTR CodecProfilePtr = NULL;
   1462     OMX_INDEXTYPE CodecProfileIndx = OMX_IndexAudioStartUnused;
   1463     OMX_AUDIO_PARAM_AACPROFILETYPE Audio_Aac_Param;
   1464     OMX_AUDIO_PARAM_AMRTYPE Audio_Amr_Param;
   1465     OMX_AUDIO_PARAM_MP3TYPE Audio_Mp3_Param;
   1466     OMX_AUDIO_PARAM_WMATYPE Audio_Wma_Param;
   1467     OMX_ERRORTYPE Err = OMX_ErrorNone;
   1468     PVMFFormatType Format = PVMF_MIME_FORMAT_UNKNOWN;
   1469 
   1470     // determine the proper index and structure (based on codec type)
   1471 
   1472     if (iInPort != NULL)
   1473     {
   1474         Format = ((PVMFOMXDecPort*)iInPort)->iFormat;
   1475     }
   1476     if (Format ==  PVMF_MIME_MPEG4_AUDIO ||
   1477             Format == PVMF_MIME_3640 ||
   1478             Format == PVMF_MIME_LATM ||
   1479             Format == PVMF_MIME_ADIF ||
   1480             Format == PVMF_MIME_ASF_MPEG4_AUDIO ||
   1481             Format == PVMF_MIME_AAC_SIZEHDR) // for testing
   1482     {
   1483         // AAC
   1484 
   1485         CodecProfilePtr = (OMX_PTR) & Audio_Aac_Param;
   1486         CodecProfileIndx = OMX_IndexParamAudioAac;
   1487         Audio_Aac_Param.nPortIndex = iInputPortIndex;
   1488 
   1489         CONFIG_SIZE_AND_VERSION(Audio_Aac_Param);
   1490     }
   1491     // AMR
   1492     else if (Format ==  PVMF_MIME_AMR_IF2 ||
   1493              Format == PVMF_MIME_AMR_IETF ||
   1494              Format == PVMF_MIME_AMR ||
   1495              Format == PVMF_MIME_AMRWB_IETF ||
   1496              Format == PVMF_MIME_AMRWB)
   1497     {
   1498         CodecProfilePtr = (OMX_PTR) & Audio_Amr_Param;
   1499         CodecProfileIndx = OMX_IndexParamAudioAmr;
   1500         Audio_Amr_Param.nPortIndex = iInputPortIndex;
   1501 
   1502         CONFIG_SIZE_AND_VERSION(Audio_Amr_Param);
   1503     }
   1504     else if (Format == PVMF_MIME_MP3)
   1505     {
   1506         CodecProfilePtr = (OMX_PTR) & Audio_Mp3_Param;
   1507         CodecProfileIndx = OMX_IndexParamAudioMp3;
   1508         Audio_Mp3_Param.nPortIndex = iInputPortIndex;
   1509 
   1510         CONFIG_SIZE_AND_VERSION(Audio_Mp3_Param);
   1511     }
   1512     else if (Format == PVMF_MIME_WMA)
   1513     {
   1514         CodecProfilePtr = (OMX_PTR) & Audio_Wma_Param;
   1515         CodecProfileIndx = OMX_IndexParamAudioWma;
   1516         Audio_Wma_Param.nPortIndex = iInputPortIndex;
   1517 
   1518         CONFIG_SIZE_AND_VERSION(Audio_Wma_Param);
   1519     }
   1520 
   1521     // first get parameters:
   1522     Err = OMX_GetParameter(iOMXDecoder, CodecProfileIndx, CodecProfilePtr);
   1523     if (Err != OMX_ErrorNone)
   1524     {
   1525         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1526                         (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() Problem getting codec profile parameter on input port %d ", iInputPortIndex));
   1527         return false;
   1528     }
   1529     // Set the stream format
   1530 
   1531 
   1532     // AAC FORMATS:
   1533     if (Format ==  PVMF_MIME_MPEG4_AUDIO)
   1534     {
   1535         Audio_Aac_Param.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS;
   1536     }
   1537     else if (Format ==  PVMF_MIME_3640)
   1538     {
   1539         Audio_Aac_Param.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS;
   1540     }
   1541     else if (Format == PVMF_MIME_LATM)
   1542     {
   1543         Audio_Aac_Param.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4LATM;
   1544     }
   1545     else if (Format == PVMF_MIME_ADIF)
   1546     {
   1547         Audio_Aac_Param.eAACStreamFormat = OMX_AUDIO_AACStreamFormatADIF;
   1548     }
   1549     else if (Format == PVMF_MIME_ASF_MPEG4_AUDIO)
   1550     {
   1551         Audio_Aac_Param.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS;
   1552     }
   1553     else if (Format == PVMF_MIME_AAC_SIZEHDR) // for testing
   1554     {
   1555         Audio_Aac_Param.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS;
   1556     }
   1557     // AMR FORMATS
   1558     else if (Format == PVMF_MIME_AMR_IF2)
   1559     {
   1560         Audio_Amr_Param.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatIF2;
   1561         Audio_Amr_Param.eAMRBandMode = OMX_AUDIO_AMRBandModeNB0; // we don't know the bitrate yet, but for init
   1562         // purposes, we'll set this to any NarrowBand bitrate
   1563         // to indicate NB vs WB
   1564     }
   1565     // File format
   1566     // NB
   1567     else if (Format == PVMF_MIME_AMR_IETF)
   1568     {
   1569         Audio_Amr_Param.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
   1570         Audio_Amr_Param.eAMRBandMode = OMX_AUDIO_AMRBandModeNB0; // we don't know the bitrate yet, but for init
   1571         // purposes, we'll set this to any NarrowBand bitrate
   1572         // to indicate NB vs WB
   1573     }
   1574     // WB
   1575     else if (Format == PVMF_MIME_AMRWB_IETF)
   1576     {
   1577         Audio_Amr_Param.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
   1578         Audio_Amr_Param.eAMRBandMode = OMX_AUDIO_AMRBandModeWB0; // we don't know the bitrate yet, but for init
   1579         // purposes, we'll set this to any WideBand bitrate
   1580         // to indicate NB vs WB
   1581     }
   1582     // streaming with Table of Contents
   1583     else if (Format == PVMF_MIME_AMR)
   1584     {
   1585         Audio_Amr_Param.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatRTPPayload;
   1586         Audio_Amr_Param.eAMRBandMode = OMX_AUDIO_AMRBandModeNB0; // we don't know the bitrate yet, but for init
   1587         // purposes, we'll set this to any WideBand bitrate
   1588         // to indicate NB vs WB
   1589     }
   1590     else if (Format == PVMF_MIME_AMRWB)
   1591     {
   1592         Audio_Amr_Param.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatRTPPayload;
   1593         Audio_Amr_Param.eAMRBandMode = OMX_AUDIO_AMRBandModeWB0; // we don't know the bitrate yet, but for init
   1594         // purposes, we'll set this to any WideBand bitrate
   1595         // to indicate NB vs WB
   1596     }
   1597     else if (Format == PVMF_MIME_MP3)
   1598     {
   1599         // nothing to do here
   1600     }
   1601     else if (Format == PVMF_MIME_WMA)
   1602     {
   1603         Audio_Wma_Param.eFormat = OMX_AUDIO_WMAFormatUnused; // set this initially
   1604     }
   1605     else
   1606     {
   1607         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1608                         (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() Unknown format in input port negotiation "));
   1609         return false;
   1610     }
   1611 
   1612     // set parameters to inform teh component of the stream type
   1613     Err = OMX_SetParameter(iOMXDecoder, CodecProfileIndx, CodecProfilePtr);
   1614     if (Err != OMX_ErrorNone)
   1615     {
   1616         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1617                         (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() Problem setting codec profile parameter on input port %d ", iInputPortIndex));
   1618         return false;
   1619     }
   1620 
   1621 
   1622     // read the output frame size
   1623     // AAC
   1624     if (Format ==  PVMF_MIME_MPEG4_AUDIO ||
   1625             Format == PVMF_MIME_3640 ||
   1626             Format == PVMF_MIME_LATM ||
   1627             Format == PVMF_MIME_ADIF ||
   1628             Format == PVMF_MIME_ASF_MPEG4_AUDIO ||
   1629             Format == PVMF_MIME_AAC_SIZEHDR) // for testing
   1630     {
   1631         // AAC frame size is 1024 samples or 2048 samples for AAC-HE
   1632         iSamplesPerFrame = Audio_Aac_Param.nFrameLength;
   1633     }
   1634     // AMR
   1635     else if (Format == PVMF_MIME_AMR_IF2 ||
   1636              Format == PVMF_MIME_AMR_IETF ||
   1637              Format == PVMF_MIME_AMR)
   1638     {
   1639         // AMR NB has fs=8khz Mono and the frame is 20ms long, i.e. there is 160 samples per frame
   1640         iSamplesPerFrame = PVOMXAUDIODEC_AMRNB_SAMPLES_PER_FRAME;
   1641     }
   1642     else if (Format == PVMF_MIME_AMRWB_IETF ||
   1643              Format == PVMF_MIME_AMRWB)
   1644     {
   1645         // AMR WB has fs=16khz Mono and the frame is 20ms long, i.e. there is 320 samples per frame
   1646         iSamplesPerFrame = PVOMXAUDIODEC_AMRWB_SAMPLES_PER_FRAME;
   1647     }
   1648     else if (Format == PVMF_MIME_MP3)
   1649     {
   1650         // frame size is either 576 or 1152 samples per frame. However, this information cannot be
   1651         // obtained through OMX MP3 Params. Assume that it's 1152
   1652         iSamplesPerFrame = PVOMXAUDIODEC_MP3_DEFAULT_SAMPLES_PER_FRAME;
   1653     }
   1654     else if (Format == PVMF_MIME_WMA)
   1655     {
   1656         // output frame size is unknown in WMA. However, the PV-WMA decoder can control the number
   1657         // of samples it places in an output buffer, so we can create an output buffer of arbitrary size
   1658         // and let the decoder control how it is filled
   1659         iSamplesPerFrame = 0; // unknown
   1660     }
   1661 
   1662     // iSamplesPerFrame depends on the codec.
   1663     // for AAC: iSamplesPerFrame = 1024
   1664     // for AAC+: iSamplesPerFrame = 2048
   1665     // for AMRNB: iSamplesPerFrame = 160
   1666     // for AMRWB: iSamplesPerFrame = 320
   1667     // for MP3:   iSamplesPerFrame = unknown, but either 1152 or 576 (we pick 1152 as default)
   1668     // for WMA:    unknown (iSamplesPerFrame is set to 0)
   1669 
   1670     // GET the output buffer params and sizes
   1671     OMX_AUDIO_PARAM_PCMMODETYPE Audio_Pcm_Param;
   1672     Audio_Pcm_Param.nPortIndex = iOutputPortIndex; // we're looking for output port params
   1673 
   1674     CONFIG_SIZE_AND_VERSION(Audio_Pcm_Param);
   1675 
   1676 
   1677     Err = OMX_GetParameter(iOMXDecoder, OMX_IndexParamAudioPcm, &Audio_Pcm_Param);
   1678     if (Err != OMX_ErrorNone)
   1679     {
   1680         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1681                         (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() Problem negotiating PCM parameters with output port %d ", iOutputPortIndex));
   1682         return false;
   1683     }
   1684 
   1685 
   1686     // these are some initial default values that may change
   1687     iPCMSamplingRate = Audio_Pcm_Param.nSamplingRate; // can be set to 0 (if unknown)
   1688 
   1689     if (iPCMSamplingRate == 0) // use default sampling rate (i.e. 48000)
   1690         iPCMSamplingRate = PVOMXAUDIODEC_DEFAULT_SAMPLINGRATE;
   1691 
   1692     iNumberOfAudioChannels = Audio_Pcm_Param.nChannels;     // should be 1 or 2
   1693     if (iNumberOfAudioChannels != 1 && iNumberOfAudioChannels != 2)
   1694         return false;
   1695 
   1696 
   1697     if ((iSamplesPerFrame != 0) && ((iSamplesPerFrame * 1000) > iPCMSamplingRate))
   1698         // if this iSamplesPerFrame is known and is large enough to ensure that the iMilliSecPerFrame calculation
   1699         // below won't be set to 0.
   1700     {
   1701         // CALCULATE NumBytes per frame, Msec per frame, etc.
   1702 
   1703         iNumBytesPerFrame = 2 * iSamplesPerFrame * iNumberOfAudioChannels;
   1704         iMilliSecPerFrame = (iSamplesPerFrame * 1000) / iPCMSamplingRate;
   1705         // Determine the size of each PCM output buffer. Size would be big enough to hold certain time amount of PCM data
   1706         uint32 numframes = PVOMXAUDIODEC_DEFAULT_OUTPUTPCM_TIME / iMilliSecPerFrame;
   1707 
   1708         if (PVOMXAUDIODEC_DEFAULT_OUTPUTPCM_TIME % iMilliSecPerFrame)
   1709         {
   1710             // If there is a remainder, include one more frame
   1711             ++numframes;
   1712         }
   1713         // set the output buffer size accordingly:
   1714         iOMXComponentOutputBufferSize = numframes * iNumBytesPerFrame;
   1715     }
   1716     else
   1717         iOMXComponentOutputBufferSize = (2 * iNumberOfAudioChannels * PVOMXAUDIODEC_DEFAULT_OUTPUTPCM_TIME * iPCMSamplingRate) / 1000; // assuming 16 bits per sample
   1718 
   1719     //Port 1 for output port
   1720     iParamPort.nPortIndex = iOutputPortIndex;
   1721     CONFIG_SIZE_AND_VERSION(iParamPort);
   1722     Err = OMX_GetParameter(iOMXDecoder, OMX_IndexParamPortDefinition, &iParamPort);
   1723     if (Err != OMX_ErrorNone)
   1724     {
   1725         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1726                         (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() Problem negotiating with output port %d ", iOutputPortIndex));
   1727         return false;
   1728     }
   1729 
   1730     if (iOMXComponentOutputBufferSize < iParamPort.nBufferSize)
   1731     {
   1732         // the OMX spec says that nBuffersize is a read only field, but the client is allowed to allocate
   1733         // a buffer size larger than nBufferSize.
   1734         iOMXComponentOutputBufferSize = iParamPort.nBufferSize;
   1735     }
   1736 
   1737     return true;
   1738 
   1739 }
   1740 
   1741 /////////////////////////////////////////////////////////////////////////////
   1742 bool PVMFOMXAudioDecNode::InitDecoder(PVMFSharedMediaDataPtr& DataIn)
   1743 {
   1744 
   1745     OsclRefCounterMemFrag DataFrag;
   1746     OsclRefCounterMemFrag refCtrMemFragOut;
   1747     uint8* initbuffer = NULL;
   1748     uint32 initbufsize = 0;
   1749 
   1750 
   1751     // NOTE: the component may not start decoding without providing the Output buffer to it,
   1752     //      here, we're sending input/config buffers.
   1753     //      Then, we'll go to ReadyToDecode state and send output as well
   1754 
   1755     if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_LATM)
   1756     {
   1757         // must have the LATM config buffer and size already present
   1758         if (iLATMConfigBuffer != NULL)
   1759         {
   1760             initbuffer = iLATMConfigBuffer;
   1761             initbufsize = iLATMConfigBufferSize;
   1762         }
   1763         else
   1764         {
   1765             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   1766                             (0, "PVMFOMXAudioDecNode::InitDecoder() Error - LATM config buffer not present"));
   1767             return false;
   1768         }
   1769     }
   1770     else if (((PVMFOMXDecPort*)iInPort)->iFormat ==  PVMF_MIME_MPEG4_AUDIO ||
   1771              ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_3640 ||
   1772              ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_ADIF ||
   1773              ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_ASF_MPEG4_AUDIO ||
   1774              ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AAC_SIZEHDR) // for testing
   1775     {
   1776         // get format specific info and send it as config data:
   1777         DataIn->getFormatSpecificInfo(DataFrag);
   1778         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1779                         (0, "PVMFOMXAudioDecNode::InitDecoder() VOL header (Size=%d)", DataFrag.getMemFragSize()));
   1780 
   1781         //get pointer to the data fragment
   1782         initbuffer = (uint8 *) DataFrag.getMemFragPtr();
   1783         initbufsize = (int32) DataFrag.getMemFragSize();
   1784 
   1785     }           // in some cases, initbufsize may be 0, and initbuf= NULL. Config is done after 1st frame of data
   1786     else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMR_IF2 ||
   1787              ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMR_IETF ||
   1788              ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMR ||
   1789              ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMRWB_IETF ||
   1790              ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMRWB ||
   1791              ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_MP3)
   1792     {
   1793         initbuffer = NULL; // no special config header. Need to decode 1 frame
   1794         initbufsize = 0;
   1795     }
   1796 
   1797     else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_WMA)
   1798     {
   1799         // in case of WMA, get config parameters from the port
   1800         initbuffer = ((PVMFOMXDecPort*)iInPort)->getTrackConfig();
   1801         initbufsize = (int32)((PVMFOMXDecPort*)iInPort)->getTrackConfigSize();
   1802 
   1803         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1804                         (0, "PVMFOMXAudioDecNode::InitDecoder() for WMA Decoder. Initialization data Size %d.", initbufsize));
   1805     }
   1806 
   1807 
   1808     if (initbufsize > 0)
   1809     {
   1810 
   1811 
   1812         if (!SendConfigBufferToOMXComponent(initbuffer, initbufsize))
   1813         {
   1814             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   1815                             (0, "PVMFOMXAudioDecNode::InitDecoder() Error in processing config buffer"));
   1816             return false;
   1817         }
   1818     }
   1819 
   1820 
   1821 
   1822 
   1823     return true;
   1824 }
   1825 
   1826 
   1827 
   1828 /////////////////////////////////////////////////////////////////////////////
   1829 ////////////////////// CALLBACK PROCESSING FOR EVENT HANDLER
   1830 /////////////////////////////////////////////////////////////////////////////
   1831 OMX_ERRORTYPE PVMFOMXAudioDecNode::EventHandlerProcessing(OMX_OUT OMX_HANDLETYPE aComponent,
   1832         OMX_OUT OMX_PTR aAppData,
   1833         OMX_OUT OMX_EVENTTYPE aEvent,
   1834         OMX_OUT OMX_U32 aData1,
   1835         OMX_OUT OMX_U32 aData2,
   1836         OMX_OUT OMX_PTR aEventData)
   1837 {
   1838 
   1839     OSCL_UNUSED_ARG(aComponent);
   1840     OSCL_UNUSED_ARG(aAppData);
   1841     OSCL_UNUSED_ARG(aEventData);
   1842 
   1843 
   1844     switch (aEvent)
   1845     {
   1846         case OMX_EventCmdComplete:
   1847         {
   1848 
   1849             switch (aData1)
   1850             {
   1851                 case OMX_CommandStateSet:
   1852                 {
   1853                     HandleComponentStateChange(aData2);
   1854                     break;
   1855                 }
   1856                 case OMX_CommandFlush:
   1857                 {
   1858                     // flush can be sent as part of repositioning or as part of port reconfig
   1859 
   1860                     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   1861                                     (0, "PVMFOMXAudioDecNode::EventHandlerProcessing: OMX_CommandFlush - completed on port %d", aData2));
   1862 
   1863                     if (iIsRepositioningRequestSentToComponent)
   1864                     {
   1865                         if (aData2 == iOutputPortIndex)
   1866                         {
   1867                             iIsOutputPortFlushed = true;
   1868                         }
   1869                         else if (aData2 == iInputPortIndex)
   1870                         {
   1871                             iIsInputPortFlushed = true;
   1872                         }
   1873 
   1874                         if (iIsOutputPortFlushed && iIsInputPortFlushed)
   1875                         {
   1876                             iIsRepositionDoneReceivedFromComponent = true;
   1877                         }
   1878                     }
   1879 
   1880                     if (IsAdded())
   1881                         RunIfNotReady();
   1882 
   1883                 }
   1884 
   1885                 break;
   1886 
   1887                 case OMX_CommandPortDisable:
   1888                 {
   1889                     // if port disable command is done, we can re-allocate the buffers and re-enable the port
   1890 
   1891                     iProcessingState = EPVMFOMXBaseDecNodeProcessingState_PortReEnable;
   1892                     iPortIndexForDynamicReconfig =  aData2;
   1893 
   1894                     RunIfNotReady();
   1895                     break;
   1896                 }
   1897                 case OMX_CommandPortEnable:
   1898                     // port enable command is done. Check if the other port also reported change.
   1899                     // If not, we can start data flow. Otherwise, must start dynamic reconfig procedure for
   1900                     // the other port as well.
   1901                 {
   1902                     if (iSecondPortReportedChange)
   1903                     {
   1904                         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   1905                                         (0, "PVMFOMXAudioDecNode::EventHandlerProcessing: OMX_CommandPortEnable - completed on port %d, dynamic reconfiguration needed on port %d", aData2, iSecondPortToReconfig));
   1906 
   1907                         iProcessingState = EPVMFOMXBaseDecNodeProcessingState_PortReconfig;
   1908                         iPortIndexForDynamicReconfig = iSecondPortToReconfig;
   1909                         iSecondPortReportedChange = false;
   1910                     }
   1911                     else
   1912                     {
   1913                         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   1914                                         (0, "PVMFOMXAudioDecNode::EventHandlerProcessing: OMX_CommandPortEnable - completed on port %d, resuming normal data flow", aData2));
   1915                         iProcessingState = EPVMFOMXBaseDecNodeProcessingState_ReadyToDecode;
   1916                         iDynamicReconfigInProgress = false;
   1917                         // in case pause or stop command was sent to component
   1918                         // change processing state (because the node might otherwise
   1919                         // start sending buffers to component before pause/stop is processed)
   1920                         if (iPauseCommandWasSentToComponent)
   1921                         {
   1922                             iProcessingState = EPVMFOMXBaseDecNodeProcessingState_Pausing;
   1923                         }
   1924                         if (iStopCommandWasSentToComponent)
   1925                         {
   1926                             iProcessingState = EPVMFOMXBaseDecNodeProcessingState_Stopping;
   1927                         }
   1928                     }
   1929                     RunIfNotReady();
   1930                     break;
   1931                 }
   1932 
   1933                 case OMX_CommandMarkBuffer:
   1934                     // nothing to do here yet;
   1935                     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   1936                                     (0, "PVMFOMXAudioDecNode::EventHandlerProcessing: OMX_CommandMarkBuffer - completed - no action taken"));
   1937 
   1938                     break;
   1939 
   1940                 default:
   1941                 {
   1942                     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   1943                                     (0, "PVMFOMXAudioDecNode::EventHandlerProcessing: Unsupported event"));
   1944                     break;
   1945                 }
   1946             }//end of switch (aData1)
   1947 
   1948             break;
   1949         }//end of case OMX_EventCmdComplete
   1950 
   1951         case OMX_EventError:
   1952         {
   1953             LOGE("Ln %d OMX_EventError nData1 %d nData2 %d", __LINE__, aData1, aData2);
   1954             if (aData1 == (OMX_U32) OMX_ErrorStreamCorrupt)
   1955             {
   1956                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   1957                                 (0, "PVMFOMXAudioDecNode::EventHandlerProcessing: OMX_EventError - Bitstream corrupt error"));
   1958                 // Errors from corrupt bitstream are reported as info events
   1959                 ReportInfoEvent(PVMFInfoProcessingFailure, NULL);
   1960 
   1961             }
   1962             else if (aData1 == (OMX_U32) OMX_ErrorInvalidState)
   1963             {
   1964                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   1965                                 (0, "PVMFOMXAudioDecNode::EventHandlerProcessing: OMX_EventError - OMX_ErrorInvalidState"));
   1966                 HandleComponentStateChange(OMX_StateInvalid);
   1967             }
   1968             else
   1969             {
   1970 
   1971                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   1972                                 (0, "PVMFOMXAudioDecNode::EventHandlerProcessing: OMX_EventError"));
   1973                 // for now, any error from the component will be reported as error
   1974                 ReportErrorEvent(PVMFErrProcessing, NULL, NULL);
   1975                 SetState(EPVMFNodeError);
   1976             }
   1977             break;
   1978 
   1979 
   1980 
   1981         }
   1982 
   1983         case OMX_EventBufferFlag:
   1984         {
   1985             // the component is reporting it encountered end of stream flag
   1986             // we'll send EOS when we receive the last buffer marked with eos
   1987 
   1988 
   1989             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1990                             (0, "PVMFOMXAudioDecNode::EventHandlerProcessing: OMX_EventBufferFlag (EOS) flag returned from OMX component"));
   1991 
   1992             RunIfNotReady();
   1993             break;
   1994         }//end of case OMX_EventBufferFlag
   1995 
   1996         case OMX_EventMark:
   1997         {
   1998 
   1999             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2000                             (0, "PVMFOMXAudioDecNode::EventHandlerProcessing: OMX_EventMark returned from OMX component - no action taken"));
   2001 
   2002             RunIfNotReady();
   2003             break;
   2004         }//end of case OMX_EventMark
   2005 
   2006         case OMX_EventPortSettingsChanged:
   2007         {
   2008 
   2009             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2010                             (0, "PVMFOMXAudioDecNode::EventHandlerProcessing: OMX_EventPortSettingsChanged returned from OMX component"));
   2011 
   2012             // first check if dynamic reconfiguration is already in progress,
   2013             // if so, wait until this is completed, and then initiate the 2nd reconfiguration
   2014             if (iDynamicReconfigInProgress)
   2015             {
   2016                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2017                                 (0, "PVMFOMXAudioDecNode::EventHandlerProcessing: OMX_EventPortSettingsChanged returned for port %d, dynamic reconfig already in progress", aData1));
   2018 
   2019                 iSecondPortToReconfig = aData1;
   2020                 iSecondPortReportedChange = true;
   2021 
   2022                 // check the audio sampling rate and fs right away in case of output port
   2023                 // is this output port?
   2024                 if (iSecondPortToReconfig == iOutputPortIndex)
   2025                 {
   2026 
   2027                     OMX_ERRORTYPE Err;
   2028                     // GET the output buffer params and sizes
   2029                     OMX_AUDIO_PARAM_PCMMODETYPE Audio_Pcm_Param;
   2030                     Audio_Pcm_Param.nPortIndex = iOutputPortIndex; // we're looking for output port params
   2031                     CONFIG_SIZE_AND_VERSION(Audio_Pcm_Param);
   2032 
   2033 
   2034 
   2035                     Err = OMX_GetParameter(iOMXDecoder, OMX_IndexParamAudioPcm, &Audio_Pcm_Param);
   2036                     if (Err != OMX_ErrorNone)
   2037                     {
   2038                         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   2039                                         (0, "PVMFOMXAudioDecNode::EventHandlerProcessing() PortSettingsChanged -> Cannot get component output parameters"));
   2040 
   2041                         SetState(EPVMFNodeError);
   2042                         ReportErrorEvent(PVMFErrResource);
   2043                     }
   2044 
   2045                     iPCMSamplingRate = Audio_Pcm_Param.nSamplingRate; // can be set to 0 (if unknown)
   2046 
   2047                     if (iPCMSamplingRate == 0) // use default sampling rate (i.e. 48000)
   2048                         iPCMSamplingRate = PVOMXAUDIODEC_DEFAULT_SAMPLINGRATE;
   2049 
   2050                     iNumberOfAudioChannels = Audio_Pcm_Param.nChannels;     // should be 1 or 2
   2051                     if (iNumberOfAudioChannels != 1 && iNumberOfAudioChannels != 2)
   2052                     {
   2053                         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   2054                                         (0, "PVMFOMXAudioDecNode::EventHandlerProcessing() PortSettingsChanged -> Output parameters num channels = %d", iNumberOfAudioChannels));
   2055 
   2056                         SetState(EPVMFNodeError);
   2057                         ReportErrorEvent(PVMFErrResource);
   2058 
   2059                     }
   2060                 }
   2061             }
   2062             else
   2063             {
   2064                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2065                                 (0, "PVMFOMXAudioDecNode::EventHandlerProcessing: OMX_EventPortSettingsChanged returned for port %d", aData1));
   2066 
   2067                 iProcessingState = EPVMFOMXBaseDecNodeProcessingState_PortReconfig;
   2068                 iPortIndexForDynamicReconfig = aData1;
   2069                 // start "discarding" data right away, don't wait
   2070                 // check the audio sampling rate and fs right away in case of output port
   2071                 // is this output port?
   2072                 if (iPortIndexForDynamicReconfig == iOutputPortIndex)
   2073                 {
   2074 
   2075                     OMX_ERRORTYPE Err;
   2076                     // GET the output buffer params and sizes
   2077                     OMX_AUDIO_PARAM_PCMMODETYPE Audio_Pcm_Param;
   2078                     Audio_Pcm_Param.nPortIndex = iOutputPortIndex; // we're looking for output port params
   2079 
   2080                     CONFIG_SIZE_AND_VERSION(Audio_Pcm_Param);
   2081 
   2082 
   2083                     Err = OMX_GetParameter(iOMXDecoder, OMX_IndexParamAudioPcm, &Audio_Pcm_Param);
   2084                     if (Err != OMX_ErrorNone)
   2085                     {
   2086                         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   2087                                         (0, "PVMFOMXAudioDecNode::EventHandlerProcessing() PortSettingsChanged -> Cannot get component output parameters"));
   2088 
   2089                         SetState(EPVMFNodeError);
   2090                         ReportErrorEvent(PVMFErrResource);
   2091 
   2092                     }
   2093 
   2094                     iPCMSamplingRate = Audio_Pcm_Param.nSamplingRate; // can be set to 0 (if unknown)
   2095 
   2096                     if (iPCMSamplingRate == 0) // use default sampling rate (i.e. 48000)
   2097                         iPCMSamplingRate = PVOMXAUDIODEC_DEFAULT_SAMPLINGRATE;
   2098 
   2099                     iNumberOfAudioChannels = Audio_Pcm_Param.nChannels;     // should be 1 or 2
   2100                     if (iNumberOfAudioChannels != 1 && iNumberOfAudioChannels != 2)
   2101                     {
   2102                         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   2103                                         (0, "PVMFOMXAudioDecNode::EventHandlerProcessing() PortSettingsChanged -> Output parameters num channels = %d", iNumberOfAudioChannels));
   2104 
   2105                         SetState(EPVMFNodeError);
   2106                         ReportErrorEvent(PVMFErrResource);
   2107                     }
   2108                 }
   2109                 iDynamicReconfigInProgress = true;
   2110             }
   2111 
   2112             RunIfNotReady();
   2113             break;
   2114         }//end of case OMX_PortSettingsChanged
   2115 
   2116         case OMX_EventResourcesAcquired:        //not supported
   2117         {
   2118             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2119                             (0, "PVMFOMXAudioDecNode::EventHandlerProcessing: OMX_EventResourcesAcquired returned from OMX component - no action taken"));
   2120 
   2121             RunIfNotReady();
   2122 
   2123             break;
   2124         }
   2125 
   2126         default:
   2127         {
   2128             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2129                             (0, "PVMFOMXAudioDecNode::EventHandlerProcessing:  Unknown Event returned from OMX component - no action taken"));
   2130 
   2131             break;
   2132         }
   2133 
   2134     }//end of switch (eEvent)
   2135 
   2136 
   2137 
   2138     return OMX_ErrorNone;
   2139 }
   2140 
   2141 
   2142 
   2143 
   2144 ////////////////////////////////////////////////////////////////////////////////////////////////
   2145 ///////////////////////////// Put output buffer in outgoing queue //////////////////////////////
   2146 ////////////////////////////////////////////////////////////////////////////////////////////////
   2147 bool PVMFOMXAudioDecNode::QueueOutputBuffer(OsclSharedPtr<PVMFMediaDataImpl> &mediadataimplout, uint32 aDataLen)
   2148 {
   2149 
   2150     bool status = true;
   2151     PVMFSharedMediaDataPtr mediaDataOut;
   2152     int32 leavecode = OsclErrNone;
   2153 
   2154     // NOTE: ASSUMPTION IS THAT OUTGOING QUEUE IS BIG ENOUGH TO QUEUE ALL THE OUTPUT BUFFERS
   2155     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2156                     (0, "PVMFOMXAudioDecNode::QueueOutputFrame: In"));
   2157 
   2158     // First check if we can put outgoing msg. into the queue
   2159     if (iOutPort->IsOutgoingQueueBusy())
   2160     {
   2161         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
   2162                         (0, "PVMFOMXAudioDecNode::QueueOutputFrame() OutgoingQueue is busy"));
   2163         return false;
   2164     }
   2165 
   2166     OSCL_TRY(leavecode,
   2167              mediaDataOut = PVMFMediaData::createMediaData(mediadataimplout, iMediaDataMemPool););
   2168     if (OsclErrNone == leavecode)
   2169     {
   2170 
   2171         // Update the filled length of the fragment
   2172         mediaDataOut->setMediaFragFilledLen(0, aDataLen);
   2173 
   2174         // Set timestamp
   2175         mediaDataOut->setTimestamp(iOutTimeStamp);
   2176 
   2177         // Set sequence number
   2178         mediaDataOut->setSeqNum(iSeqNum++);
   2179         // set stream id
   2180         mediaDataOut->setStreamID(iStreamID);
   2181 
   2182 
   2183         PVLOGGER_LOGMSG(PVLOGMSG_INST_REL, iDataPathLogger, PVLOGMSG_INFO, (0, ":PVMFOMXAudioDecNode::QueueOutputFrame(): - SeqNum=%d, TS=%d", iSeqNum, iOutTimeStamp));
   2184         int fsiErrorCode = 0;
   2185 
   2186         // Check if Fsi configuration need to be sent
   2187         if (sendFsi && !iCompactFSISettingSucceeded)
   2188         {
   2189 
   2190             OsclRefCounterMemFrag FsiMemfrag;
   2191 
   2192             OSCL_TRY(fsiErrorCode, FsiMemfrag = iFsiFragmentAlloc.get(););
   2193 
   2194             OSCL_FIRST_CATCH_ANY(fsiErrorCode, PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   2195                                  (0, "PVMFOMXAudioDecNode::RemoveOutputFrame() Failed to allocate memory for  FSI")));
   2196 
   2197             if (fsiErrorCode == 0)
   2198             {
   2199 
   2200                 channelSampleInfo* pcminfo = (channelSampleInfo*) FsiMemfrag.getMemFragPtr();
   2201                 if (pcminfo != NULL)
   2202                 {
   2203                     OSCL_ASSERT(pcminfo != NULL);
   2204 
   2205                     pcminfo->samplingRate    = iPCMSamplingRate;
   2206                     pcminfo->desiredChannels = iNumberOfAudioChannels;
   2207 
   2208                     mediaDataOut->setFormatSpecificInfo(FsiMemfrag);
   2209 
   2210 
   2211                     OsclMemAllocator alloc;
   2212                     int32 KeyLength = oscl_strlen(PVMF_FORMAT_SPECIFIC_INFO_KEY) + 1;
   2213                     PvmiKeyType KvpKey = (PvmiKeyType)alloc.ALLOCATE(KeyLength);
   2214 
   2215                     if (NULL == KvpKey)
   2216                     {
   2217                         SetState(EPVMFNodeError);
   2218                         ReportErrorEvent(PVMFErrNoMemory);
   2219                         return false;
   2220                     }
   2221 
   2222                     oscl_strncpy(KvpKey, PVMF_FORMAT_SPECIFIC_INFO_KEY, KeyLength);
   2223                     int32 err;
   2224 
   2225                     OSCL_TRY(err, ((PVMFOMXDecPort*)iOutPort)->pvmiSetPortFormatSpecificInfoSync(FsiMemfrag, KvpKey););
   2226                     if (err != OsclErrNone)
   2227                     {
   2228                         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
   2229                                         (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters - Problem to set FSI"));
   2230                         SetState(EPVMFNodeError);
   2231                         ReportErrorEvent(PVMFErrNoMemory);
   2232                         return false; // this is going to make everyth go out of scope
   2233                     }
   2234 
   2235 
   2236                     alloc.deallocate((OsclAny*)(KvpKey));
   2237 
   2238 
   2239 
   2240                 }
   2241                 else
   2242                 {
   2243                     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
   2244                                     (0, "PVMFOMXAudioDecNode::QueueOutputFrame - Problem allocating Output FSI"));
   2245                     SetState(EPVMFNodeError);
   2246                     ReportErrorEvent(PVMFErrNoMemory);
   2247                     return false; // this is going to make everything go out of scope
   2248                 }
   2249             }
   2250             else
   2251             {
   2252                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
   2253                                 (0, "PVMFOMXAudioDecNode::QueueOutputFrame - Problem allocating Output FSI"));
   2254                 return false; // this is going to make everything go out of scope
   2255             }
   2256 
   2257             // Reset the flag
   2258             sendFsi = false;
   2259         }
   2260 
   2261         if (fsiErrorCode == 0)
   2262         {
   2263             // Send frame to downstream node
   2264             PVMFSharedMediaMsgPtr mediaMsgOut;
   2265             convertToPVMFMediaMsg(mediaMsgOut, mediaDataOut);
   2266 
   2267             if (iOutPort && (iOutPort->QueueOutgoingMsg(mediaMsgOut) == PVMFSuccess))
   2268             {
   2269                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   2270                                 (0, "PVMFOMXAudioDecNode::QueueOutputFrame(): Queued frame OK "));
   2271 
   2272             }
   2273             else
   2274             {
   2275                 // we should not get here because we always check for whether queue is busy or not
   2276                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   2277                                 (0, "PVMFOMXAudioDecNode::QueueOutputFrame(): Send frame failed"));
   2278                 return false;
   2279             }
   2280         }
   2281 
   2282 
   2283     }//end of if (OsclErrNone == leavecode)
   2284     else
   2285     {
   2286         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   2287                         (0, "PVMFOMXAudioDecNode::QueueOutputFrame() call PVMFMediaData::createMediaData is failed"));
   2288         return false;
   2289     }
   2290 
   2291     return status;
   2292 
   2293 }
   2294 
   2295 /////////////////////////////////////////////////////////////////////////////
   2296 void PVMFOMXAudioDecNode::DoRequestPort(PVMFOMXBaseDecNodeCommand& aCmd)
   2297 {
   2298     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2299                     (0, "PVMFOMXAudioDecNode::DoRequestPort() In"));
   2300     //This node supports port request from any state
   2301 
   2302     //retrieve port tag.
   2303     int32 tag;
   2304     OSCL_String* portconfig;
   2305 
   2306     aCmd.PVMFOMXBaseDecNodeCommandBase::Parse(tag, portconfig);
   2307 
   2308     PVMFPortInterface* port = NULL;
   2309     int32 leavecode = OsclErrNone;
   2310     //validate the tag...
   2311     switch (tag)
   2312     {
   2313         case PVMF_OMX_DEC_NODE_PORT_TYPE_INPUT:
   2314             if (iInPort)
   2315             {
   2316                 CommandComplete(iInputCommands, aCmd, PVMFFailure);
   2317                 break;
   2318             }
   2319             OSCL_TRY(leavecode, iInPort = OSCL_NEW(PVMFOMXDecPort, ((int32)tag, this, (OMX_STRING)PVMF_OMX_AUDIO_DEC_INPUT_PORT_NAME)););
   2320             if (leavecode || iInPort == NULL)
   2321             {
   2322                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   2323                                 (0, "PVMFOMXAudioDecNode::DoRequestPort: Error - Input port instantiation failed"));
   2324                 CommandComplete(iInputCommands, aCmd, PVMFErrArgument);
   2325                 return;
   2326             }
   2327             port = iInPort;
   2328             break;
   2329 
   2330         case PVMF_OMX_DEC_NODE_PORT_TYPE_OUTPUT:
   2331             if (iOutPort)
   2332             {
   2333                 CommandComplete(iInputCommands, aCmd, PVMFFailure);
   2334                 break;
   2335             }
   2336             OSCL_TRY(leavecode, iOutPort = OSCL_NEW(PVMFOMXDecPort, ((int32)tag, this, (OMX_STRING)PVMF_OMX_AUDIO_DEC_OUTPUT_PORT_NAME)));
   2337             if (leavecode || iOutPort == NULL)
   2338             {
   2339                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   2340                                 (0, "PVMFOMXAudioDecNode::DoRequestPort: Error - Output port instantiation failed"));
   2341                 CommandComplete(iInputCommands, aCmd, PVMFErrArgument);
   2342                 return;
   2343             }
   2344             port = iOutPort;
   2345             break;
   2346 
   2347         default:
   2348             //bad port tag
   2349             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   2350                             (0, "PVMFOMXAudioDecNode::DoRequestPort: Error - Invalid port tag"));
   2351             CommandComplete(iInputCommands, aCmd, PVMFErrArgument);
   2352             return;
   2353     }
   2354 
   2355     //Return the port pointer to the caller.
   2356     CommandComplete(iInputCommands, aCmd, PVMFSuccess, (OsclAny*)port);
   2357 }
   2358 
   2359 /////////////////////////////////////////////////////////////////////////////
   2360 void PVMFOMXAudioDecNode::DoReleasePort(PVMFOMXBaseDecNodeCommand& aCmd)
   2361 {
   2362     PVMFPortInterface* temp;
   2363     aCmd.PVMFOMXBaseDecNodeCommandBase::Parse(temp);
   2364 
   2365     PVMFOMXDecPort* port = (PVMFOMXDecPort*)temp;
   2366 
   2367     if (port != NULL && (port == iInPort || port == iOutPort))
   2368     {
   2369         if (port == iInPort)
   2370         {
   2371             OSCL_DELETE(((PVMFOMXDecPort*)iInPort));
   2372             iInPort = NULL;
   2373         }
   2374         else
   2375         {
   2376             OSCL_DELETE(((PVMFOMXDecPort*)iOutPort));
   2377             iOutPort = NULL;
   2378         }
   2379         //delete the port.
   2380         CommandComplete(iInputCommands, aCmd, PVMFSuccess);
   2381     }
   2382     else
   2383     {
   2384         //port not found.
   2385         CommandComplete(iInputCommands, aCmd, PVMFFailure);
   2386     }
   2387 }
   2388 
   2389 /////////////////////////////////////////////////////////////////////////////
   2390 PVMFStatus PVMFOMXAudioDecNode::DoGetNodeMetadataKey(PVMFOMXBaseDecNodeCommand& aCmd)
   2391 {
   2392     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2393                     (0, "PVMFOMXAudioDecNode::DoGetNodeMetadataKey() In"));
   2394 
   2395     PVMFMetadataList* keylistptr = NULL;
   2396     uint32 starting_index;
   2397     int32 max_entries;
   2398     char* query_key;
   2399 
   2400     aCmd.PVMFOMXBaseDecNodeCommand::Parse(keylistptr, starting_index, max_entries, query_key);
   2401 
   2402     // Check parameters
   2403     if (keylistptr == NULL)
   2404     {
   2405         // The list pointer is invalid
   2406         return PVMFErrArgument;
   2407     }
   2408 
   2409     if ((starting_index > (iAvailableMetadataKeys.size() - 1)) || max_entries == 0)
   2410     {
   2411         // Invalid starting index and/or max entries
   2412         return PVMFErrArgument;
   2413     }
   2414 
   2415     // Copy the requested keys
   2416     uint32 num_entries = 0;
   2417     int32 num_added = 0;
   2418     int32 leavecode = OsclErrNone;
   2419     for (uint32 lcv = 0; lcv < iAvailableMetadataKeys.size(); lcv++)
   2420     {
   2421         if (query_key == NULL)
   2422         {
   2423             // No query key so this key is counted
   2424             ++num_entries;
   2425             if (num_entries > starting_index)
   2426             {
   2427                 // Past the starting index so copy the key
   2428                 leavecode = OsclErrNone;
   2429                 leavecode = PushKVPKey(iAvailableMetadataKeys[lcv], keylistptr);
   2430                 if (OsclErrNone != leavecode)
   2431                 {
   2432                     return PVMFErrNoMemory;
   2433                 }
   2434 
   2435                 num_added++;
   2436             }
   2437         }
   2438         else
   2439         {
   2440             // Check if the key matche the query key
   2441             if (pv_mime_strcmp(iAvailableMetadataKeys[lcv].get_cstr(), query_key) >= 0)
   2442             {
   2443                 // This key is counted
   2444                 ++num_entries;
   2445                 if (num_entries > starting_index)
   2446                 {
   2447                     // Past the starting index so copy the key
   2448                     leavecode = OsclErrNone;
   2449                     leavecode = PushKVPKey(iAvailableMetadataKeys[lcv], keylistptr);
   2450                     if (OsclErrNone != leavecode)
   2451                     {
   2452                         return PVMFErrNoMemory;
   2453                     }
   2454 
   2455                     num_added++;
   2456                 }
   2457             }
   2458         }
   2459 
   2460         // Check if max number of entries have been copied
   2461         if (max_entries > 0 && num_added >= max_entries)
   2462         {
   2463             break;
   2464         }
   2465     }
   2466 
   2467     return PVMFSuccess;
   2468 }
   2469 
   2470 /////////////////////////////////////////////////////////////////////////////
   2471 PVMFStatus PVMFOMXAudioDecNode::DoGetNodeMetadataValue(PVMFOMXBaseDecNodeCommand& aCmd)
   2472 {
   2473     PVMFMetadataList* keylistptr = NULL;
   2474     Oscl_Vector<PvmiKvp, OsclMemAllocator>* valuelistptr = NULL;
   2475     uint32 starting_index;
   2476     int32 max_entries;
   2477 
   2478     aCmd.PVMFOMXBaseDecNodeCommand::Parse(keylistptr, valuelistptr, starting_index, max_entries);
   2479 
   2480     // Check the parameters
   2481     if (keylistptr == NULL || valuelistptr == NULL)
   2482     {
   2483         return PVMFErrArgument;
   2484     }
   2485 
   2486     uint32 numkeys = keylistptr->size();
   2487 
   2488     if (starting_index > (numkeys - 1) || numkeys <= 0 || max_entries == 0)
   2489     {
   2490         // Don't do anything
   2491         return PVMFErrArgument;
   2492     }
   2493 
   2494     uint32 numvalentries = 0;
   2495     int32 numentriesadded = 0;
   2496     for (uint32 lcv = 0; lcv < numkeys; lcv++)
   2497     {
   2498         int32 leavecode = OsclErrNone;
   2499         int32 leavecode1 = OsclErrNone;
   2500         PvmiKvp KeyVal;
   2501         KeyVal.key = NULL;
   2502         uint32 KeyLen = 0;
   2503 
   2504         if ((oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVOMXAUDIODECMETADATA_CODECINFO_AUDIO_CHANNELS_KEY) == 0))
   2505         {
   2506             // PCM output channels
   2507             if (iNumberOfAudioChannels > 0)
   2508             {
   2509                 // Increment the counter for the number of values found so far
   2510                 ++numvalentries;
   2511 
   2512                 // Create a value entry if past the starting index
   2513                 if (numvalentries > starting_index)
   2514                 {
   2515                     KeyLen = oscl_strlen(PVOMXAUDIODECMETADATA_CODECINFO_AUDIO_CHANNELS_KEY) + 1; // for "codec-info/audio/channels;"
   2516                     KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
   2517                     KeyLen += oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR) + 1; // for "uint32" and NULL terminator
   2518 
   2519                     // Allocate memory for the string
   2520                     leavecode = OsclErrNone;
   2521                     KeyVal.key = (char*) AllocateKVPKeyArray(leavecode, PVMI_KVPVALTYPE_CHARPTR, KeyLen);
   2522                     if (OsclErrNone == leavecode)
   2523                     {
   2524                         // Copy the key string
   2525                         oscl_strncpy(KeyVal.key, PVOMXAUDIODECMETADATA_CODECINFO_AUDIO_CHANNELS_KEY, oscl_strlen(PVOMXAUDIODECMETADATA_CODECINFO_AUDIO_CHANNELS_KEY) + 1);
   2526                         oscl_strncat(KeyVal.key, PVOMXAUDIODECMETADATA_SEMICOLON, oscl_strlen(PVOMXAUDIODECMETADATA_SEMICOLON));
   2527                         oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
   2528                         oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR));
   2529                         KeyVal.key[KeyLen-1] = NULL_TERM_CHAR;
   2530                         // Copy the value
   2531                         KeyVal.value.uint32_value = iNumberOfAudioChannels;
   2532                         // Set the length and capacity
   2533                         KeyVal.length = 1;
   2534                         KeyVal.capacity = 1;
   2535                     }
   2536                     else
   2537                     {
   2538                         // Memory allocation failed
   2539                         KeyVal.key = NULL;
   2540                         break;
   2541                     }
   2542                 }
   2543             }
   2544         }
   2545         else if ((oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVOMXAUDIODECMETADATA_CODECINFO_AUDIO_SAMPLERATE_KEY) == 0) &&
   2546                  (iPCMSamplingRate > 0))
   2547         {
   2548             // PCM output sampling rate
   2549             // Increment the counter for the number of values found so far
   2550             ++numvalentries;
   2551 
   2552             // Create a value entry if past the starting index
   2553             if (numvalentries > starting_index)
   2554             {
   2555                 KeyLen = oscl_strlen(PVOMXAUDIODECMETADATA_CODECINFO_AUDIO_SAMPLERATE_KEY) + 1; // for "codec-info/audio/sample-rate;"
   2556                 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
   2557                 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR) + 1; // for "uint32" and NULL terminator
   2558 
   2559                 // Allocate memory for the string
   2560                 leavecode = OsclErrNone;
   2561                 KeyVal.key = (char*) AllocateKVPKeyArray(leavecode, PVMI_KVPVALTYPE_CHARPTR, KeyLen);
   2562                 if (OsclErrNone == leavecode)
   2563                 {
   2564                     // Copy the key string
   2565                     oscl_strncpy(KeyVal.key, PVOMXAUDIODECMETADATA_CODECINFO_AUDIO_SAMPLERATE_KEY, oscl_strlen(PVOMXAUDIODECMETADATA_CODECINFO_AUDIO_SAMPLERATE_KEY) + 1);
   2566                     oscl_strncat(KeyVal.key, PVOMXAUDIODECMETADATA_SEMICOLON, oscl_strlen(PVOMXAUDIODECMETADATA_SEMICOLON));
   2567                     oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
   2568                     oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR));
   2569                     KeyVal.key[KeyLen-1] = NULL_TERM_CHAR;
   2570                     // Copy the value
   2571                     KeyVal.value.uint32_value = iPCMSamplingRate;
   2572                     // Set the length and capacity
   2573                     KeyVal.length = 1;
   2574                     KeyVal.capacity = 1;
   2575                 }
   2576                 else
   2577                 {
   2578                     // Memory allocation failed
   2579                     KeyVal.key = NULL;
   2580                     break;
   2581                 }
   2582             }
   2583         }
   2584         else if ((oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVOMXAUDIODECMETADATA_CODECINFO_AUDIO_FORMAT_KEY) == 0) &&
   2585                  iInPort != NULL)
   2586         {
   2587             // Format
   2588             if ((((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_LATM) ||
   2589                     (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_MPEG4_AUDIO) ||
   2590                     (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_3640) ||
   2591                     (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_ADIF) ||
   2592                     (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AAC_SIZEHDR) ||
   2593                     (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMR_IF2) ||
   2594                     (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMR_IETF) ||
   2595                     (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMR) ||
   2596                     (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMRWB_IETF) ||
   2597                     (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMRWB) ||
   2598                     (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_MP3) ||
   2599                     (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_WMA)
   2600 
   2601                )
   2602             {
   2603                 // Increment the counter for the number of values found so far
   2604                 ++numvalentries;
   2605 
   2606                 // Create a value entry if past the starting index
   2607                 if (numvalentries > starting_index)
   2608                 {
   2609                     KeyLen = oscl_strlen(PVOMXAUDIODECMETADATA_CODECINFO_AUDIO_FORMAT_KEY) + 1; // for "codec-info/audio/format;"
   2610                     KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
   2611                     KeyLen += oscl_strlen(PVMI_KVPVALTYPE_CHARPTR_STRING_CONSTCHAR) + 1; // for "char*" and NULL terminator
   2612 
   2613                     uint32 valuelen = 0;
   2614                     if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_LATM)
   2615                     {
   2616                         valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_LATM)) + 1; // Value string plus one for NULL terminator
   2617                     }
   2618                     else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_MPEG4_AUDIO)
   2619                     {
   2620                         valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_MPEG4_AUDIO)) + 1; // Value string plus one for NULL terminator
   2621                     }
   2622                     else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_3640)
   2623                     {
   2624                         valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_3640)) + 1; // Value string plus one for NULL terminator
   2625                     }
   2626                     else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_ADIF)
   2627                     {
   2628                         valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_ADIF)) + 1;
   2629                     }
   2630                     else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMR_IF2)
   2631                     {
   2632                         valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_AMR_IF2)) + 1;
   2633                     }
   2634                     else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMR_IETF)
   2635                     {
   2636                         valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_AMR_IETF)) + 1;
   2637                     }
   2638                     else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMR)
   2639                     {
   2640                         valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_AMR)) + 1;
   2641                     }
   2642                     else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMRWB_IETF)
   2643                     {
   2644                         valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_AMRWB_IETF)) + 1;
   2645                     }
   2646                     else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMRWB)
   2647                     {
   2648                         valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_AMRWB)) + 1;
   2649                     }
   2650                     else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_MP3)
   2651                     {
   2652                         valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_MP3)) + 1;
   2653                     }
   2654                     else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_WMA)
   2655                     {
   2656                         valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_WMA)) + 1;
   2657                     }
   2658                     else
   2659                     {
   2660                         // Should not enter here
   2661                         OSCL_ASSERT(false);
   2662                         valuelen = 1;
   2663                     }
   2664 
   2665                     // Allocate memory for the strings
   2666                     leavecode = OsclErrNone;
   2667                     KeyVal.key = (char*) AllocateKVPKeyArray(leavecode, PVMI_KVPVALTYPE_CHARPTR, KeyLen);
   2668                     if (OsclErrNone == leavecode)
   2669                     {
   2670                         KeyVal.value.pChar_value = (char*) AllocateKVPKeyArray(leavecode1, PVMI_KVPVALTYPE_CHARPTR, valuelen);
   2671                     }
   2672 
   2673                     if (OsclErrNone == leavecode && OsclErrNone == leavecode1)
   2674                     {
   2675                         // Copy the key string
   2676                         oscl_strncpy(KeyVal.key, PVOMXAUDIODECMETADATA_CODECINFO_AUDIO_FORMAT_KEY, oscl_strlen(PVOMXAUDIODECMETADATA_CODECINFO_AUDIO_FORMAT_KEY) + 1);
   2677                         oscl_strncat(KeyVal.key, PVOMXAUDIODECMETADATA_SEMICOLON, oscl_strlen(PVOMXAUDIODECMETADATA_SEMICOLON));
   2678                         oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
   2679                         oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_CHARPTR_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_CHARPTR_STRING_CONSTCHAR));
   2680                         KeyVal.key[KeyLen-1] = NULL_TERM_CHAR;
   2681                         // Copy the value
   2682                         if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_LATM)
   2683                         {
   2684                             oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_LATM), valuelen);
   2685                         }
   2686                         else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_MPEG4_AUDIO)
   2687                         {
   2688                             oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_MPEG4_AUDIO), valuelen);
   2689                         }
   2690                         else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_3640)
   2691                         {
   2692                             oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_3640), valuelen);
   2693                         }
   2694                         else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_ADIF)
   2695                         {
   2696                             oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_ADIF), valuelen);
   2697                         }
   2698                         else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMR_IF2)
   2699                         {
   2700                             oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_AMR_IF2), valuelen);
   2701                         }
   2702                         else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMR_IETF)
   2703                         {
   2704                             oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_AMR_IETF), valuelen);
   2705                         }
   2706                         else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMR)
   2707                         {
   2708                             oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_AMR), valuelen);
   2709                         }
   2710                         else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMRWB_IETF)
   2711                         {
   2712                             oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_AMRWB_IETF), valuelen);
   2713                         }
   2714                         else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMRWB)
   2715                         {
   2716                             oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_AMRWB), valuelen);
   2717                         }
   2718                         else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_MP3)
   2719                         {
   2720                             oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_MP3), valuelen);
   2721                         }
   2722                         else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_WMA)
   2723                         {
   2724                             oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_WMA), valuelen);
   2725                         }
   2726                         else
   2727                         {
   2728                             // Should not enter here
   2729                             OSCL_ASSERT(false);
   2730                         }
   2731                         KeyVal.value.pChar_value[valuelen-1] = NULL_TERM_CHAR;
   2732                         // Set the length and capacity
   2733                         KeyVal.length = valuelen;
   2734                         KeyVal.capacity = valuelen;
   2735                     }
   2736                     else
   2737                     {
   2738                         // Memory allocation failed so clean up
   2739                         if (KeyVal.key)
   2740                         {
   2741                             OSCL_ARRAY_DELETE(KeyVal.key);
   2742                             KeyVal.key = NULL;
   2743                         }
   2744                         if (KeyVal.value.pChar_value)
   2745                         {
   2746                             OSCL_ARRAY_DELETE(KeyVal.value.pChar_value);
   2747                         }
   2748                         break;
   2749                     }
   2750                 }
   2751             }
   2752         }
   2753 
   2754         if (KeyVal.key != NULL)
   2755         {
   2756             leavecode = OsclErrNone;
   2757             leavecode = PushKVP(KeyVal, *valuelistptr);
   2758             if (OsclErrNone != leavecode)
   2759             {
   2760                 switch (GetValTypeFromKeyString(KeyVal.key))
   2761                 {
   2762                     case PVMI_KVPVALTYPE_CHARPTR:
   2763                         if (KeyVal.value.pChar_value != NULL)
   2764                         {
   2765                             OSCL_ARRAY_DELETE(KeyVal.value.pChar_value);
   2766                             KeyVal.value.pChar_value = NULL;
   2767                         }
   2768                         break;
   2769 
   2770                     default:
   2771                         // Add more case statements if other value types are returned
   2772                         break;
   2773                 }
   2774 
   2775                 OSCL_ARRAY_DELETE(KeyVal.key);
   2776                 KeyVal.key = NULL;
   2777             }
   2778             else
   2779             {
   2780                 // Increment the counter for number of value entries added to the list
   2781                 ++numentriesadded;
   2782             }
   2783 
   2784             // Check if the max number of value entries were added
   2785             if (max_entries > 0 && numentriesadded >= max_entries)
   2786             {
   2787                 break;
   2788             }
   2789 
   2790         }
   2791 
   2792     }
   2793 
   2794     return PVMFSuccess;
   2795 
   2796 }
   2797 
   2798 /////////////////////////////////////////////////////////////////////////////
   2799 bool PVMFOMXAudioDecNode::ReleaseAllPorts()
   2800 {
   2801     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXAudioDecNode::ReleaseAllPorts() In"));
   2802 
   2803     if (iInPort)
   2804     {
   2805         iInPort->ClearMsgQueues();
   2806         iInPort->Disconnect();
   2807         OSCL_DELETE(((PVMFOMXDecPort*)iInPort));
   2808         iInPort = NULL;
   2809     }
   2810 
   2811     if (iOutPort)
   2812     {
   2813         iOutPort->ClearMsgQueues();
   2814         iOutPort->Disconnect();
   2815         OSCL_DELETE(((PVMFOMXDecPort*)iOutPort));
   2816         iOutPort = NULL;
   2817     }
   2818 
   2819     return true;
   2820 }
   2821 
   2822 /////////////////////////////////////////////////////////////////////////////
   2823 void PVMFOMXAudioDecNode::DoQueryUuid(PVMFOMXBaseDecNodeCommand& aCmd)
   2824 {
   2825     //This node supports Query UUID from any state
   2826 
   2827     OSCL_String* mimetype;
   2828     Oscl_Vector<PVUuid, OsclMemAllocator> *uuidvec;
   2829     bool exactmatch;
   2830     aCmd.PVMFOMXBaseDecNodeCommandBase::Parse(mimetype, uuidvec, exactmatch);
   2831 
   2832     //Try to match the input mimetype against any of
   2833     //the custom interfaces for this node
   2834 
   2835     //Match against custom interface1...
   2836     if (*mimetype == PVMF_OMX_BASE_DEC_NODE_CUSTOM1_MIMETYPE
   2837             //also match against base mimetypes for custom interface1,
   2838             //unless exactmatch is set.
   2839             || (!exactmatch && *mimetype == PVMF_OMX_AUDIO_DEC_NODE_MIMETYPE)
   2840             || (!exactmatch && *mimetype == PVMF_BASEMIMETYPE))
   2841     {
   2842 
   2843         PVUuid uuid(PVMF_OMX_BASE_DEC_NODE_CUSTOM1_UUID);
   2844         uuidvec->push_back(uuid);
   2845     }
   2846     CommandComplete(iInputCommands, aCmd, PVMFSuccess);
   2847 }
   2848 
   2849 PVMFStatus PVMFOMXAudioDecNode::CreateLATMParser()
   2850 {
   2851     PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFOMXAudioDecNode::CreateLATMParser() In"));
   2852 
   2853     // First clean up if necessary
   2854     DeleteLATMParser();
   2855 
   2856     // Instantiate the LATM parser
   2857     iLATMParser = OSCL_NEW(PV_LATM_Parser, ());
   2858     if (!iLATMParser)
   2859     {
   2860         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXAudioDecNode::CreateLATMParser() LATM parser instantiation failed"));
   2861         return PVMFErrNoMemory;
   2862     }
   2863 
   2864     PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFOMXAudioDecNode::CreateLATMParser() Out"));
   2865     return PVMFSuccess;
   2866 }
   2867 
   2868 PVMFStatus PVMFOMXAudioDecNode::DeleteLATMParser()
   2869 {
   2870     PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFOMXAudioDecNode::DeleteLATMParser() In"));
   2871 
   2872     // Delete LATM parser if there is one
   2873     if (iLATMParser)
   2874     {
   2875         OSCL_DELETE(iLATMParser);
   2876         iLATMParser = NULL;
   2877     }
   2878 
   2879     if (iLATMConfigBuffer)
   2880     {
   2881         oscl_free(iLATMConfigBuffer);
   2882         iLATMConfigBuffer = NULL;
   2883         iLATMConfigBufferSize = 0;
   2884     }
   2885 
   2886     PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFOMXAudioDecNode::DeleteLATMParser() Out"));
   2887     return PVMFSuccess;
   2888 }
   2889 
   2890 
   2891 
   2892 
   2893 
   2894 
   2895 /////////////////////////////////////////////////////////////////////////////
   2896 uint32 PVMFOMXAudioDecNode::GetNumMetadataKeys(char* aQueryKeyString)
   2897 {
   2898     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXAudioDecNode::GetNumMetadataKeys() called"));
   2899 
   2900     uint32 num_entries = 0;
   2901 
   2902     if (aQueryKeyString == NULL)
   2903     {
   2904         num_entries = iAvailableMetadataKeys.size();
   2905     }
   2906     else
   2907     {
   2908         for (uint32 i = 0; i < iAvailableMetadataKeys.size(); i++)
   2909         {
   2910             if (pv_mime_strcmp(iAvailableMetadataKeys[i].get_cstr(), aQueryKeyString) >= 0)
   2911             {
   2912                 num_entries++;
   2913             }
   2914         }
   2915     }
   2916     return num_entries; // Number of elements
   2917 
   2918 }
   2919 
   2920 /////////////////////////////////////////////////////////////////////////////
   2921 uint32 PVMFOMXAudioDecNode::GetNumMetadataValues(PVMFMetadataList& aKeyList)
   2922 {
   2923     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXAudioDecNode::GetNumMetadataValues() called"));
   2924 
   2925     uint32 numkeys = aKeyList.size();
   2926 
   2927     if (numkeys <= 0)
   2928     {
   2929         // Don't do anything
   2930         return 0;
   2931     }
   2932 
   2933     // Count the number of value entries for the provided key list
   2934     uint32 numvalentries = 0;
   2935     for (uint32 lcv = 0; lcv < numkeys; lcv++)
   2936     {
   2937         if ((oscl_strcmp(aKeyList[lcv].get_cstr(), PVOMXAUDIODECMETADATA_CODECINFO_AUDIO_CHANNELS_KEY) == 0))
   2938         {
   2939             // Channels
   2940             if (iNumberOfAudioChannels > 0)
   2941             {
   2942                 ++numvalentries;
   2943             }
   2944         }
   2945         else if ((oscl_strcmp(aKeyList[lcv].get_cstr(), PVOMXAUDIODECMETADATA_CODECINFO_AUDIO_SAMPLERATE_KEY) == 0) && (iPCMSamplingRate > 0))
   2946         {
   2947             // Sample rate
   2948             ++numvalentries;
   2949         }
   2950         else if ((oscl_strcmp(aKeyList[lcv].get_cstr(), PVOMXAUDIODECMETADATA_CODECINFO_AUDIO_FORMAT_KEY) == 0) &&
   2951                  iInPort != NULL)
   2952         {
   2953             // Format
   2954             if ((((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_LATM) ||
   2955                     (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_MPEG4_AUDIO) ||
   2956                     (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_3640) ||
   2957                     (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_ADIF) ||
   2958                     (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMR_IF2) ||
   2959                     (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMR_IETF) ||
   2960                     (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMR) ||
   2961                     (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMRWB_IETF) ||
   2962                     (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMRWB) ||
   2963                     (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_MP3) ||
   2964                     (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_WMA)
   2965 
   2966                )
   2967 
   2968             {
   2969                 ++numvalentries;
   2970             }
   2971         }
   2972     }
   2973 
   2974     return numvalentries;
   2975 }
   2976 
   2977 
   2978 // needed for WMA parameter verification
   2979 bool PVMFOMXAudioDecNode::VerifyParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters, int num_elements)
   2980 {
   2981     OSCL_UNUSED_ARG(aSession);
   2982     OSCL_UNUSED_ARG(num_elements);
   2983     if (pv_mime_strcmp(aParameters->key, PVMF_BITRATE_VALUE_KEY) == 0)
   2984     {
   2985         if (((PVMFOMXDecPort*)iOutPort)->verifyConnectedPortParametersSync(PVMF_BITRATE_VALUE_KEY, &(aParameters->value.uint32_value)) != PVMFSuccess)
   2986         {
   2987             return false;
   2988         }
   2989         return true;
   2990     }
   2991     else if (pv_mime_strcmp(aParameters->key, PVMF_FORMAT_SPECIFIC_INFO_KEY) < 0)
   2992     {
   2993         PVLOGGER_LOGMSG(PVLOGMSG_INST_REL, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXAudioDecNode::VerifyParametersSync() - Unsupported Key"));
   2994         OSCL_ASSERT(false);
   2995     }
   2996 
   2997     bool cap_exchange_status = false;
   2998 
   2999     pvAudioConfigParserInputs aInputs;
   3000     OMXConfigParserInputs aInputParameters;
   3001     AudioOMXConfigParserOutputs aOutputParameters;
   3002 
   3003     aInputs.inPtr = (uint8*)(aParameters->value.key_specific_value);
   3004     aInputs.inBytes = (int32)aParameters->capacity;
   3005     aInputs.iMimeType = PVMF_MIME_WMA;
   3006     aInputParameters.cComponentRole = (OMX_STRING)"audio_decoder.wma";
   3007     aInputParameters.inBytes = aInputs.inBytes;
   3008     aInputParameters.inPtr = aInputs.inPtr;
   3009 
   3010 
   3011     if (aInputs.inBytes == 0 || aInputs.inPtr == NULL)
   3012     {
   3013         return cap_exchange_status;
   3014     }
   3015 
   3016 
   3017     OMX_BOOL status = OMX_FALSE;
   3018     OMX_U32 num_comps = 0, ii;
   3019     OMX_STRING *CompOfRole;
   3020     //  uint32 ii;
   3021     // call once to find out the number of components that can fit the role
   3022     OMX_MasterGetComponentsOfRole(aInputParameters.cComponentRole, &num_comps, NULL);
   3023 
   3024     if (num_comps > 0)
   3025     {
   3026         CompOfRole = (OMX_STRING *)oscl_malloc(num_comps * sizeof(OMX_STRING));
   3027         for (ii = 0; ii < num_comps; ii++)
   3028             CompOfRole[ii] = (OMX_STRING) oscl_malloc(PV_OMX_MAX_COMPONENT_NAME_LENGTH * sizeof(OMX_U8));
   3029 
   3030         // call 2nd time to get the component names
   3031         OMX_MasterGetComponentsOfRole(aInputParameters.cComponentRole, &num_comps, (OMX_U8 **)CompOfRole);
   3032 
   3033         for (ii = 0; ii < num_comps; ii++)
   3034         {
   3035             aInputParameters.cComponentName = CompOfRole[ii];
   3036             status = OMX_MasterConfigParser(&aInputParameters, &aOutputParameters);
   3037             if (status == OMX_TRUE)
   3038             {
   3039                 break;
   3040             }
   3041             else
   3042             {
   3043                 status = OMX_FALSE;
   3044             }
   3045         }
   3046 
   3047         // whether successful or not, need to free CompOfRoles
   3048         for (ii = 0; ii < num_comps; ii++)
   3049         {
   3050             oscl_free(CompOfRole[ii]);
   3051             CompOfRole[ii] = NULL;
   3052         }
   3053 
   3054         oscl_free(CompOfRole);
   3055 
   3056     }
   3057     else
   3058     {
   3059         // if no components support the role, nothing else to do
   3060         return false;
   3061     }
   3062 
   3063     if (OMX_FALSE != status)
   3064     {
   3065         cap_exchange_status = true;
   3066 
   3067         iPCMSamplingRate = aOutputParameters.SamplesPerSec;
   3068         iNumberOfAudioChannels = aOutputParameters.Channels;
   3069 
   3070         if ((iNumberOfAudioChannels != 1 && iNumberOfAudioChannels != 2) ||
   3071                 (iPCMSamplingRate <= 0))
   3072         {
   3073             cap_exchange_status = false;
   3074         }
   3075     }
   3076 
   3077     return cap_exchange_status;
   3078 
   3079 }
   3080 
   3081 
   3082 PVMFStatus PVMFOMXAudioDecNode::DoCapConfigVerifyParameters(PvmiKvp* aParameters, int aNumElements)
   3083 {
   3084     OSCL_UNUSED_ARG(aNumElements);
   3085 
   3086     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3087                     (0, "PVMFOMXAudioDecNode::DoCapConfigVerifyParameters() In\n"));
   3088 
   3089     pvAudioConfigParserInputs aInputs;
   3090     OMXConfigParserInputs aInputParameters;
   3091     AudioOMXConfigParserOutputs aOutputParameters;
   3092 
   3093     aInputs.inPtr = (uint8*)(aParameters->value.key_specific_value);
   3094     aInputs.inBytes = (int32)aParameters->capacity;
   3095     aInputs.iMimeType = iNodeConfig.iMimeType;
   3096     aInputParameters.inBytes = aInputs.inBytes;
   3097     aInputParameters.inPtr = aInputs.inPtr;
   3098 
   3099     if (aInputs.inBytes == 0 || aInputs.inPtr == NULL)
   3100     {
   3101         // in case of following formats - config codec data is expected to
   3102         // be present in the query. If not, config parser cannot be called
   3103         if (aInputs.iMimeType == PVMF_MIME_WMA ||
   3104                 aInputs.iMimeType == PVMF_MIME_MPEG4_AUDIO ||
   3105                 aInputs.iMimeType == PVMF_MIME_3640 ||
   3106                 aInputs.iMimeType == PVMF_MIME_LATM ||
   3107                 aInputs.iMimeType == PVMF_MIME_ADIF ||
   3108                 aInputs.iMimeType == PVMF_MIME_ASF_MPEG4_AUDIO ||
   3109                 aInputs.iMimeType == PVMF_MIME_AAC_SIZEHDR)
   3110         {
   3111             if (aInputs.iMimeType == PVMF_MIME_LATM)
   3112             {
   3113                 return PVMFErrNotSupported;
   3114             }
   3115             else
   3116             {
   3117                 // DV TO_DO: remove this
   3118                 OSCL_LEAVE(OsclErrNotSupported);
   3119             }
   3120         }
   3121     }
   3122 
   3123 
   3124     if (aInputs.iMimeType == PVMF_MIME_MPEG4_AUDIO ||
   3125             aInputs.iMimeType == PVMF_MIME_3640 ||
   3126             aInputs.iMimeType == PVMF_MIME_LATM ||
   3127             aInputs.iMimeType == PVMF_MIME_ADIF ||
   3128             aInputs.iMimeType == PVMF_MIME_ASF_MPEG4_AUDIO ||
   3129             aInputs.iMimeType == PVMF_MIME_AAC_SIZEHDR)
   3130     {
   3131         aInputParameters.cComponentRole = (OMX_STRING)"audio_decoder.aac";
   3132     }
   3133     // AMR
   3134     else if (aInputs.iMimeType == PVMF_MIME_AMR_IF2 ||
   3135              aInputs.iMimeType == PVMF_MIME_AMR_IETF ||
   3136              aInputs.iMimeType == PVMF_MIME_AMR)
   3137     {
   3138         aInputParameters.cComponentRole = (OMX_STRING)"audio_decoder.amrnb";
   3139     }
   3140     else if (aInputs.iMimeType == PVMF_MIME_AMRWB_IETF ||
   3141              aInputs.iMimeType == PVMF_MIME_AMRWB)
   3142     {
   3143         aInputParameters.cComponentRole = (OMX_STRING)"audio_decoder.amrwb";
   3144     }
   3145     else if (aInputs.iMimeType == PVMF_MIME_MP3)
   3146     {
   3147         aInputParameters.cComponentRole = (OMX_STRING)"audio_decoder.mp3";
   3148     }
   3149     else if (aInputs.iMimeType ==  PVMF_MIME_WMA)
   3150     {
   3151         aInputParameters.cComponentRole = (OMX_STRING)"audio_decoder.wma";
   3152     }
   3153     else
   3154     {
   3155         // Illegal codec specified.
   3156         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "%s::PVMFOMXAudioDecNode::DoCapConfigVerifyParameters() Input port format other then codec type", iName.Str()));
   3157     }
   3158 
   3159     OMX_BOOL status = OMX_FALSE;
   3160     OMX_U32 num_comps = 0, ii;
   3161     OMX_STRING *CompOfRole;
   3162     //  uint32 ii;
   3163     // call once to find out the number of components that can fit the role
   3164     OMX_MasterGetComponentsOfRole(aInputParameters.cComponentRole, &num_comps, NULL);
   3165 
   3166     if (num_comps > 0)
   3167     {
   3168         CompOfRole = (OMX_STRING *)oscl_malloc(num_comps * sizeof(OMX_STRING));
   3169         for (ii = 0; ii < num_comps; ii++)
   3170             CompOfRole[ii] = (OMX_STRING) oscl_malloc(PV_OMX_MAX_COMPONENT_NAME_LENGTH * sizeof(OMX_U8));
   3171 
   3172         // call 2nd time to get the component names
   3173         OMX_MasterGetComponentsOfRole(aInputParameters.cComponentRole, &num_comps, (OMX_U8 **)CompOfRole);
   3174 
   3175         for (ii = 0; ii < num_comps; ii++)
   3176         {
   3177             aInputParameters.cComponentName = CompOfRole[ii];
   3178             status = OMX_MasterConfigParser(&aInputParameters, &aOutputParameters);
   3179             if (status == OMX_TRUE)
   3180             {
   3181                 break;
   3182             }
   3183             else
   3184             {
   3185                 status = OMX_FALSE;
   3186             }
   3187         }
   3188 
   3189         // whether successful or not, need to free CompOfRoles
   3190         for (ii = 0; ii < num_comps; ii++)
   3191         {
   3192             oscl_free(CompOfRole[ii]);
   3193             CompOfRole[ii] = NULL;
   3194         }
   3195 
   3196         oscl_free(CompOfRole);
   3197 
   3198     }
   3199     else
   3200     {
   3201         // if no component supports the role, nothing else to do
   3202         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3203                         (0, "PVMFOMXAudioDecNode::DoCapConfigVerifyParameters() No omx component supports this role PVMFErrNotSupported\n"));
   3204         return PVMFErrNotSupported;
   3205     }
   3206 
   3207     if (status == OMX_FALSE)
   3208     {
   3209         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3210                         (0, "PVMFOMXAudioDecNode::DoCapConfigVerifyParameters() ->OMXConfigParser() PVMFErrNotSupported\n"));
   3211         return PVMFErrNotSupported;
   3212     }
   3213 
   3214     if (aInputs.iMimeType == PVMF_MIME_WMA)
   3215     {
   3216         iNumberOfAudioChannels = aOutputParameters.Channels;
   3217         iPCMSamplingRate = aOutputParameters.SamplesPerSec;
   3218     }
   3219     else if (aInputs.iMimeType == PVMF_MIME_MPEG4_AUDIO ||
   3220              aInputs.iMimeType == PVMF_MIME_3640 ||
   3221              aInputs.iMimeType == PVMF_MIME_LATM ||
   3222              aInputs.iMimeType == PVMF_MIME_ADIF ||
   3223              aInputs.iMimeType == PVMF_MIME_ASF_MPEG4_AUDIO ||
   3224              aInputs.iMimeType == PVMF_MIME_AAC_SIZEHDR)
   3225     {
   3226         iNumberOfAudioChannels = aOutputParameters.Channels;
   3227     }
   3228 
   3229     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3230                     (0, "PVMFOMXAudioDecNode::DoCapConfigVerifyParameters() Out\n"));
   3231     return PVMFSuccess;
   3232 }
   3233 
   3234 void PVMFOMXAudioDecNode::DoCapConfigSetParameters(PvmiKvp* aParameters, int aNumElements, PvmiKvp* &aRetKVP)
   3235 {
   3236     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3237                     (0, "PVMFOMXAudioDecNode::DoCapConfigSetParameters() In\n"));
   3238     OSCL_UNUSED_ARG(aNumElements);
   3239     OSCL_UNUSED_ARG(aRetKVP);
   3240 
   3241     // find out if the audio dec format key is used for the query
   3242     if (pv_mime_strcmp(aParameters->key, PVMF_AUDIO_DEC_FORMAT_TYPE_VALUE_KEY) == 0)
   3243     {
   3244         // set the mime type if audio format is being used
   3245         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3246                         (0, "PVMFOMXAudioDecNode::DoCapConfigSetParameters() set audio dec format type to %s\n", aParameters->value.pChar_value));
   3247 
   3248         iNodeConfig.iMimeType = aParameters->value.pChar_value;
   3249     }
   3250 
   3251     else
   3252     {
   3253         // For now, ignore other queries
   3254         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3255                         (0, "PVMFOMXAudioDecNode::DoCapConfigSetParameters() Key not used"));
   3256 
   3257         // indicate "error" by setting return KVP to the original
   3258         aRetKVP = aParameters;
   3259     }
   3260 
   3261 
   3262 
   3263 
   3264     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   3265                     (0, "PVMFOMXAudioDecNode::DoCapConfigSetParameters() Out\n"));
   3266 }
   3267 
   3268 
   3269 
   3270