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_amrffparser_node.h"
     19 #include "pvmf_amrffparser_defs.h"
     20 #include "amr_parsernode_tunables.h"
     21 #include "pvmf_amrffparser_port.h"
     22 #include "amrfileparser.h"
     23 #include "media_clock_converter.h"
     24 #include "pv_gau.h"
     25 #include "pvlogger.h"
     26 #include "oscl_error_codes.h"
     27 #include "pvmf_fileformat_events.h"
     28 #include "pvmf_basic_errorinfomessage.h"
     29 #include "pvmf_errorinfomessage_extension.h"
     30 #include "pvmf_media_cmd.h"
     31 #include "pvmf_media_msg_format_ids.h"
     32 #include "pv_mime_string_utils.h"
     33 #include "oscl_snprintf.h"
     34 #include "pvmf_local_data_source.h"
     35 #include "pvmi_kvp_util.h"
     36 #include "pvmf_amrffparser_events.h"
     37 #include "oscl_exclusive_ptr.h"
     38 #include "pvmf_source_context_data.h"
     39 
     40 static const char PVAMR_ALL_METADATA_KEY[] = "all";
     41 static const char PVAMRMETADATA_DURATION_KEY[] = "duration";
     42 static const char PVAMRMETADATA_NUMTRACKS_KEY[] = "num-tracks";
     43 static const char PVAMRMETADATA_TRACKINFO_BITRATE_KEY[] = "track-info/bit-rate";
     44 static const char PVAMRMETADATA_TRACKINFO_AUDIO_FORMAT_KEY[] = "track-info/audio/format";
     45 static const char PVAMRMETADATA_CLIP_TYPE_KEY[] = "clip-type";
     46 static const char PVAMRMETADATA_RANDOM_ACCESS_DENIED_KEY[] = "random-access-denied";
     47 static const char PVAMRMETADATA_SEMICOLON[] = ";";
     48 static const char PVAMRMETADATA_TIMESCALE[] = "timescale=";
     49 static const char PVAMRMETADATA_INDEX0[] = "index=0";
     50 
     51 #define AMR_SAMPLE_DURATION 20
     52 
     53 
     54 
     55 PVMFAMRFFParserNode::PVMFAMRFFParserNode(int32 aPriority) :
     56         OsclTimerObject(aPriority, "PVAMRFFParserNode"),
     57         iOutPort(NULL),
     58         iLogger(NULL),
     59         iAMRParser(NULL),
     60         iExtensionRefCount(0)
     61 {
     62     iFileHandle                = NULL;
     63     iLogger                    = NULL;
     64     iDataPathLogger            = NULL;
     65     iClockLogger               = NULL;
     66     iDownloadComplete          = false;
     67 
     68     iFileSizeLastConvertedToTime = 0;
     69     iLastNPTCalcInConvertSizeToTime = 0;
     70 
     71     iExtensionRefCount         = 0;
     72     iUseCPMPluginRegistry      = false;
     73 
     74     iCPM                       = NULL;
     75     iCPMSessionID              = 0xFFFFFFFF;
     76     iCPMContentType            = PVMF_CPM_CONTENT_FORMAT_UNKNOWN;
     77     iCPMContentAccessFactory   = NULL;
     78     iCPMInitCmdId              = 0;
     79     iCPMOpenSessionCmdId       = 0;
     80     iCPMRegisterContentCmdId   = 0;
     81     iCPMGetLicenseInterfaceCmdId = 0;
     82     iCPMRequestUsageId         = 0;
     83     iCPMUsageCompleteCmdId     = 0;
     84     iCPMCloseSessionCmdId      = 0;
     85     iCPMResetCmdId             = 0;
     86     iCPMCancelGetLicenseCmdId  = 0;
     87     iRequestedUsage.key        = NULL;
     88     iApprovedUsage.key         = NULL;
     89     iAuthorizationDataKvp.key  = NULL;
     90     iCPMMetaDataExtensionInterface = NULL;
     91     iCPMGetMetaDataKeysCmdId       = 0;
     92     iCPMGetMetaDataValuesCmdId     = 0;
     93     iAMRParserNodeMetadataValueCount = 0;
     94 
     95     iDownloadProgressInterface = NULL;
     96     iDownloadFileSize          = 0;
     97     iAMRHeaderSize             = AMR_HEADER_SIZE;
     98     iDataStreamInterface       = NULL;
     99     iDataStreamFactory         = NULL;
    100     iDataStreamReadCapacityObserver = NULL;
    101     iAutoPaused                = false;
    102 
    103     iStreamID                  = 0;
    104 
    105     oSourceIsCurrent           = false;
    106     iInterfaceState = EPVMFNodeCreated;
    107 
    108     iUseCPMPluginRegistry = false;
    109     iFileHandle = NULL;
    110 
    111     iCountToClaculateRDATimeInterval = 1;
    112     int32 err;
    113     OSCL_TRY(err,
    114 
    115              //Create the input command queue.  Use a reserve to avoid lots of dynamic memory allocation.
    116              iInputCommands.Construct(PVMF_AMRFFPARSER_NODE_COMMAND_ID_START, PVMF_AMRFFPARSER_NODE_COMMAND_VECTOR_RESERVE);
    117 
    118              //Create the "current command" queue.  It will only contain one
    119              //command at a time, so use a reserve of 1.
    120              iCurrentCommand.Construct(0, 1);
    121              iCancelCommand.Construct(0, 1);
    122 
    123              iSelectedTrackList.reserve(1);
    124 
    125              //Set the node capability data.
    126              //This node can support an unlimited number of ports.
    127              iCapability.iCanSupportMultipleInputPorts = false;
    128              iCapability.iCanSupportMultipleOutputPorts = false;
    129              iCapability.iHasMaxNumberOfPorts = true;
    130              iCapability.iMaxNumberOfPorts = 1;
    131              iCapability.iOutputFormatCapability.push_back(PVMF_MIME_AMR_IETF);
    132              iCapability.iOutputFormatCapability.push_back(PVMF_MIME_AMR_IF2);
    133              iCapability.iOutputFormatCapability.push_back(PVMF_MIME_AMRWB_IETF);
    134             );
    135 
    136     if (err != OsclErrNone)
    137     {
    138         //if a leave happened, cleanup and re-throw the error
    139         iInputCommands.clear();
    140         iCurrentCommand.clear();
    141         iCancelCommand.clear();
    142         iCapability.iInputFormatCapability.clear();
    143         iCapability.iOutputFormatCapability.clear();
    144         OSCL_CLEANUP_BASE_CLASS(PVMFNodeInterface);
    145         OSCL_CLEANUP_BASE_CLASS(OsclTimerObject);
    146         OSCL_LEAVE(err);
    147     }
    148 
    149     Construct();
    150 }
    151 
    152 PVMFAMRFFParserNode::~PVMFAMRFFParserNode()
    153 {
    154     if (iRequestedUsage.key)
    155     {
    156         OSCL_ARRAY_DELETE(iRequestedUsage.key);
    157         iRequestedUsage.key = NULL;
    158     }
    159     if (iApprovedUsage.key)
    160     {
    161         OSCL_ARRAY_DELETE(iApprovedUsage.key);
    162         iApprovedUsage.key = NULL;
    163     }
    164     if (iAuthorizationDataKvp.key)
    165     {
    166         OSCL_ARRAY_DELETE(iAuthorizationDataKvp.key);
    167         iAuthorizationDataKvp.key = NULL;
    168     }
    169 
    170     if (iCPM != NULL)
    171     {
    172         iCPM->ThreadLogoff();
    173         PVMFCPMFactory::DestroyContentPolicyManager(iCPM);
    174         iCPM = NULL;
    175     }
    176     if (iDownloadProgressInterface != NULL)
    177     {
    178         iDownloadProgressInterface->cancelResumeNotification();
    179     }
    180     //Cleanup commands
    181     //The command queues are self-deleting, but we want to
    182     //notify the observer of unprocessed commands.
    183     while (!iCurrentCommand.empty())
    184     {
    185         CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFFailure);
    186     }
    187     while (!iCancelCommand.empty())
    188     {
    189         CommandComplete(iCancelCommand, iCancelCommand.front(), PVMFFailure);
    190     }
    191     while (!iInputCommands.empty())
    192     {
    193         CommandComplete(iInputCommands, iInputCommands.front(), PVMFFailure);
    194     }
    195     if (iExtensionRefCount > 0)
    196     {
    197         OSCL_ASSERT(false);
    198     }
    199     Cancel();
    200 
    201     //Cleanup allocated ports
    202     ReleaseAllPorts();
    203     CleanupFileSource();
    204     iFileServer.Close();
    205 }
    206 
    207 PVMFStatus PVMFAMRFFParserNode::ThreadLogon()
    208 {
    209     PVMF_AMRPARSERNODE_LOGSTACKTRACE((0, "PVMFAMRParserNode::ThreadLogon() Called"));
    210     if (iInterfaceState == EPVMFNodeCreated)
    211     {
    212         if (!IsAdded())
    213         {
    214             AddToScheduler();
    215         }
    216         iLogger = PVLogger::GetLoggerObject("PVMFAMRParserNode");
    217         iDataPathLogger = PVLogger::GetLoggerObject("datapath.sourcenode.amrparsernode");
    218         iClockLogger = PVLogger::GetLoggerObject("clock");
    219         iFileServer.Connect();
    220         SetState(EPVMFNodeIdle);
    221         return PVMFSuccess;
    222     }
    223     PVMF_AMRPARSERNODE_LOGERROR((0, "PVMFAMRParserNode::ThreadLogon() - Invalid State"));
    224     return PVMFErrInvalidState;
    225 }
    226 
    227 PVMFStatus PVMFAMRFFParserNode::GetCapability(PVMFNodeCapability& aNodeCapability)
    228 {
    229 
    230     PVMF_AMRPARSERNODE_LOGSTACKTRACE((0, "PVMFAMRParserNode::GetCapability() called"));
    231     // TODO: Return the appropriate format capability
    232     aNodeCapability = iCapability;
    233     return PVMFSuccess;
    234 }
    235 
    236 
    237 PVMFPortIter* PVMFAMRFFParserNode::GetPorts(const PVMFPortFilter* aFilter)
    238 {
    239     PVMF_AMRPARSERNODE_LOGSTACKTRACE((0, "PVMFASFParserNode::GetPorts() called"));
    240     OSCL_UNUSED_ARG(aFilter);
    241     PVMF_AMRPARSERNODE_LOGERROR((0, "PVMFASFParserNode::GetPorts() Not Implemented"));
    242     // TODO: Return the currently available ports
    243     return NULL;
    244 }
    245 
    246 PVMFCommandId PVMFAMRFFParserNode::QueryUUID(PVMFSessionId s, const PvmfMimeString& aMimeType,
    247         Oscl_Vector<PVUuid, OsclMemAllocator>& aUuids,
    248         bool aExactUuidsOnly, const OsclAny* aContext)
    249 {
    250     PVMF_AMRPARSERNODE_LOGSTACKTRACE((0, "PVMFAMRParserNode::QueryUUID called"));
    251     PVMFAMRFFNodeCommand cmd;
    252     cmd.PVMFAMRFFNodeCommandBase::Construct(s,
    253                                             PVMF_AMR_PARSER_NODE_QUERYUUID,
    254                                             aMimeType,
    255                                             aUuids,
    256                                             aExactUuidsOnly,
    257                                             aContext);
    258     return QueueCommandL(cmd);
    259 }
    260 
    261 PVMFCommandId PVMFAMRFFParserNode::QueryInterface(PVMFSessionId s, const PVUuid& aUuid,
    262         PVInterface*& aInterfacePtr,
    263         const OsclAny* aContext)
    264 {
    265     PVMF_AMRPARSERNODE_LOGSTACKTRACE((0, "PVMFAMRParserNode::QueryInterface called"));
    266     PVMFAMRFFNodeCommand cmd;
    267     cmd.PVMFAMRFFNodeCommandBase::Construct(s,
    268                                             PVMF_AMR_PARSER_NODE_QUERYINTERFACE,
    269                                             aUuid,
    270                                             aInterfacePtr,
    271                                             aContext);
    272     return QueueCommandL(cmd);
    273 }
    274 
    275 PVMFCommandId PVMFAMRFFParserNode::RequestPort(PVMFSessionId s, int32 aPortTag, const PvmfMimeString* aPortConfig, const OsclAny* aContext)
    276 {
    277     PVMF_AMRPARSERNODE_LOGSTACKTRACE((0, "PVMFAMRParserNode::RequestPort called"));
    278     PVMFAMRFFNodeCommand cmd;
    279     cmd.PVMFAMRFFNodeCommandBase::Construct(s,
    280                                             PVMF_AMR_PARSER_NODE_REQUESTPORT,
    281                                             aPortTag,
    282                                             aPortConfig,
    283                                             aContext);
    284     return QueueCommandL(cmd);
    285 }
    286 
    287 PVMFCommandId PVMFAMRFFParserNode::ReleasePort(PVMFSessionId s, PVMFPortInterface& aPort, const OsclAny* aContext)
    288 {
    289     PVMF_AMRPARSERNODE_LOGSTACKTRACE((0, "PVMFAMRParserNode::ReleasePort called"));
    290     PVMFAMRFFNodeCommand cmd;
    291     cmd.PVMFAMRFFNodeCommandBase::Construct(s, PVMF_AMR_PARSER_NODE_RELEASEPORT, aPort, aContext);
    292     return QueueCommandL(cmd);
    293 }
    294 
    295 PVMFCommandId PVMFAMRFFParserNode::Init(PVMFSessionId s, const OsclAny* aContext)
    296 {
    297     PVMF_AMRPARSERNODE_LOGSTACKTRACE((0, "PVMFAMRParserNode::Init called"));
    298     PVMFAMRFFNodeCommand cmd;
    299     cmd.PVMFAMRFFNodeCommandBase::Construct(s, PVMF_AMR_PARSER_NODE_INIT, aContext);
    300     return QueueCommandL(cmd);
    301 }
    302 
    303 PVMFCommandId PVMFAMRFFParserNode::Prepare(PVMFSessionId s, const OsclAny* aContext)
    304 {
    305     PVMF_AMRPARSERNODE_LOGSTACKTRACE((0, "PVMFAMRParserNode::Prepare called"));
    306     PVMFAMRFFNodeCommand cmd;
    307     cmd.PVMFAMRFFNodeCommandBase::Construct(s, PVMF_AMR_PARSER_NODE_PREPARE, aContext);
    308     return QueueCommandL(cmd);
    309 }
    310 
    311 PVMFCommandId PVMFAMRFFParserNode::Start(PVMFSessionId s, const OsclAny* aContext)
    312 {
    313     PVMF_AMRPARSERNODE_LOGSTACKTRACE((0, "PVMFAMRParserNode::Start called"));
    314     PVMFAMRFFNodeCommand cmd;
    315     cmd.PVMFAMRFFNodeCommandBase::Construct(s, PVMF_AMR_PARSER_NODE_START, aContext);
    316     return QueueCommandL(cmd);
    317 }
    318 
    319 PVMFCommandId PVMFAMRFFParserNode::Stop(PVMFSessionId s, const OsclAny* aContext)
    320 {
    321     PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFAMRFFParserNode:Stop"));
    322     PVMFAMRFFNodeCommand cmd;
    323     cmd.PVMFAMRFFNodeCommandBase::Construct(s, PVMF_AMR_PARSER_NODE_STOP, aContext);
    324     return QueueCommandL(cmd);
    325 }
    326 
    327 PVMFCommandId PVMFAMRFFParserNode::Pause(PVMFSessionId s, const OsclAny* aContext)
    328 {
    329     PVMF_AMRPARSERNODE_LOGSTACKTRACE((0, "PVMFAMRParserNode::Stop called"));
    330     PVMFAMRFFNodeCommand cmd;
    331     cmd.PVMFAMRFFNodeCommandBase::Construct(s, PVMF_AMR_PARSER_NODE_PAUSE, aContext);
    332     return QueueCommandL(cmd);
    333 }
    334 
    335 PVMFCommandId PVMFAMRFFParserNode::Flush(PVMFSessionId s, const OsclAny* aContext)
    336 {
    337     PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFAMRFFParserNode:Flush"));
    338     PVMFAMRFFNodeCommand cmd;
    339     cmd.PVMFAMRFFNodeCommandBase::Construct(s, PVMF_AMR_PARSER_NODE_FLUSH, aContext);
    340     return QueueCommandL(cmd);
    341 }
    342 
    343 PVMFCommandId PVMFAMRFFParserNode::Reset(PVMFSessionId s, const OsclAny* aContext)
    344 {
    345     PVMF_AMRPARSERNODE_LOGSTACKTRACE((0, "PVMFAMRParserNode::Flush called"));
    346     PVMFAMRFFNodeCommand cmd;
    347     cmd.PVMFAMRFFNodeCommandBase::Construct(s, PVMF_AMR_PARSER_NODE_RESET, aContext);
    348     return QueueCommandL(cmd);
    349 }
    350 
    351 PVMFCommandId PVMFAMRFFParserNode::CancelAllCommands(PVMFSessionId s, const OsclAny* aContext)
    352 {
    353     PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFAMRFFParserNode:CancelAllCommands"));
    354     PVMFAMRFFNodeCommand cmd;
    355     cmd.PVMFAMRFFNodeCommandBase::Construct(s, PVMF_AMR_PARSER_NODE_CANCELALLCOMMANDS, aContext);
    356     return QueueCommandL(cmd);
    357 }
    358 
    359 PVMFCommandId PVMFAMRFFParserNode::CancelCommand(PVMFSessionId s, PVMFCommandId aCmdId, const OsclAny* aContext)
    360 {
    361     PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFAMRFFParserNode:CancelCommand"));
    362     PVMFAMRFFNodeCommand cmd;
    363     cmd.PVMFAMRFFNodeCommandBase::Construct(s, PVMF_AMR_PARSER_NODE_CANCELCOMMAND, aCmdId, aContext);
    364     return QueueCommandL(cmd);
    365 }
    366 
    367 void PVMFAMRFFParserNode::Construct()
    368 {
    369     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFAMRFFParserNode::Construct()"));
    370     iFileServer.Connect();
    371     iAvailableMetadataKeys.reserve(4);
    372     iAvailableMetadataKeys.clear();
    373 }
    374 
    375 void PVMFAMRFFParserNode::Run()
    376 {
    377     if (!iInputCommands.empty())
    378     {
    379         if (ProcessCommand())
    380         {
    381             /*
    382              * note: need to check the state before re-scheduling
    383              * since the node could have been reset in the ProcessCommand
    384              * call.
    385              */
    386             if (iInterfaceState != EPVMFNodeCreated)
    387             {
    388                 RunIfNotReady();
    389             }
    390             return;
    391         }
    392     }
    393     // Send outgoing messages
    394     if (iInterfaceState == EPVMFNodeStarted || FlushPending())
    395     {
    396         PVAMRFFNodeTrackPortInfo* trackPortInfoPtr = NULL;
    397 
    398         if (!GetTrackInfo(iOutPort, trackPortInfoPtr))
    399         {
    400             PVMF_AMRPARSERNODE_LOGERROR((0, "PVAMRParserNode::Run: Error - GetTrackInfo failed"));
    401             return;
    402         }
    403 
    404         ProcessPortActivity(trackPortInfoPtr);
    405 
    406         if (CheckForPortRescheduling())
    407         {
    408             /*
    409              * Re-schedule since there is atleast one port that needs processing
    410              */
    411             RunIfNotReady();
    412         }
    413     }
    414 
    415     if (FlushPending()
    416             && iOutPort
    417             && iOutPort->OutgoingMsgQueueSize() == 0)
    418     {
    419         SetState(EPVMFNodePrepared);
    420         iOutPort->ResumeInput();
    421         CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFSuccess);
    422     }
    423 }
    424 
    425 PVMFStatus  PVMFAMRFFParserNode::ProcessOutgoingMsg(PVAMRFFNodeTrackPortInfo* aTrackInfoPtr)
    426 {
    427     /*
    428      * Called by the AO to process one message off the outgoing
    429      * message queue for the given port.  This routine will
    430      * try to send the data to the connected port.
    431     */
    432     PVMF_AMRPARSERNODE_LOGSTACKTRACE((0, "PVMFAMRParserNode::ProcessOutgoingMsg() Called aPort=0x%x", aTrackInfoPtr->iPort));
    433     PVMFStatus status = aTrackInfoPtr->iPort->Send();
    434     if (status == PVMFErrBusy)
    435     {
    436         /* Connected port is busy */
    437         aTrackInfoPtr->oProcessOutgoingMessages = false;
    438         PVMF_AMRPARSERNODE_LOGDATATRAFFIC((0, "PVMFAMRParserNode::ProcessOutgoingMsg() Connected port is in busy state"));
    439     }
    440     else if (status != PVMFSuccess)
    441     {
    442         PVMF_AMRPARSERNODE_LOGERROR((0, "PVMFAMRParserNode::ProcessOutgoingMsg() - aTrackInfoPtr->iPort->Send() Failed"));
    443     }
    444     return status;
    445 }
    446 
    447 PVMFStatus PVMFAMRFFParserNode::DoGetMetadataKeys(PVMFAMRFFNodeCommand& aCmd)
    448 {
    449     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFAMRFFParserNode::DoGetNodeMetadataKeys() In"));
    450 
    451     /* Get Metadata keys from CPM for protected content only */
    452     if ((iCPMMetaDataExtensionInterface != NULL))
    453 
    454     {
    455         GetCPMMetaDataKeys();
    456         return PVMFPending;
    457     }
    458     return (CompleteGetMetadataKeys(aCmd));
    459 }
    460 
    461 PVMFStatus
    462 PVMFAMRFFParserNode::CompleteGetMetadataKeys(PVMFAMRFFNodeCommand& aCmd)
    463 {
    464     PVMF_AMRPARSERNODE_LOGSTACKTRACE((0, "PVMFAMRParserNode::CompleteGetMetadataKeys Called"));
    465     PVMFMetadataList* keylistptr = NULL;
    466     uint32 starting_index;
    467     int32 max_entries;
    468     char* query_key;
    469 
    470     aCmd.PVMFAMRFFNodeCommand::Parse(keylistptr, starting_index, max_entries, query_key);
    471     if (keylistptr == NULL)
    472     {
    473         return PVMFErrArgument;
    474     }
    475 
    476     if ((starting_index > (iAvailableMetadataKeys.size() - 1)) || max_entries == 0)
    477     {
    478         return PVMFErrArgument;
    479     }
    480 
    481     uint32 num_entries = 0;
    482     int32 num_added = 0;
    483     uint32 lcv = 0;
    484     for (lcv = 0; lcv < iAvailableMetadataKeys.size(); lcv++)
    485     {
    486         if (query_key == NULL)
    487         {
    488             ++num_entries;
    489             if (num_entries > starting_index)
    490             {
    491                 // Past the starting index so copy the key
    492                 PVMFStatus status = PushValueToList(iAvailableMetadataKeys, keylistptr, lcv);
    493                 if (PVMFErrNoMemory == status)
    494                 {
    495                     return status;
    496                 }
    497                 num_added++;
    498             }
    499         }
    500         else
    501         {
    502             // Check if the key matches the query key
    503             if (pv_mime_strcmp(iAvailableMetadataKeys[lcv].get_cstr(), query_key) >= 0)
    504             {
    505                 // This key is counted
    506                 ++num_entries;
    507                 if (num_entries > starting_index)
    508                 {
    509                     // Past the starting index so copy the key
    510                     PVMFStatus status = PushValueToList(iAvailableMetadataKeys, keylistptr, lcv);
    511                     if (PVMFErrNoMemory == status)
    512                     {
    513                         return status;
    514                     }
    515                     num_added++;
    516                 }
    517             }
    518         }
    519 
    520         // Check if max number of entries have been copied
    521         if (max_entries > 0 && num_added >= max_entries)
    522         {
    523             break;
    524         }
    525     }
    526     for (lcv = 0; lcv < iCPMMetadataKeys.size(); lcv++)
    527     {
    528         if (query_key == NULL)
    529         {
    530             /* No query key so this key is counted */
    531             ++num_entries;
    532             if (num_entries > (uint32)starting_index)
    533             {
    534                 /* Past the starting index so copy the key */
    535 
    536                 PVMFStatus status = PushValueToList(iCPMMetadataKeys, keylistptr, lcv);
    537                 if (PVMFErrNoMemory == status)
    538                 {
    539                     return status;
    540                 }
    541                 num_added++;
    542             }
    543         }
    544         else
    545         {
    546             /* Check if the key matches the query key */
    547             if (pv_mime_strcmp(iCPMMetadataKeys[lcv].get_cstr(), query_key) >= 0)
    548             {
    549                 ++num_entries;
    550                 if (num_entries > (uint32)starting_index)
    551                 {
    552                     /* Past the starting index so copy the key */
    553 
    554                     PVMFStatus status = PushValueToList(iCPMMetadataKeys, keylistptr, lcv);
    555                     if (PVMFErrNoMemory == status)
    556                     {
    557                         return status;
    558                     }
    559                     num_added++;
    560                 }
    561             }
    562         }
    563         /* Check if max number of entries have been copied */
    564         if ((max_entries > 0) && (num_added >= max_entries))
    565         {
    566             break;
    567         }
    568     }
    569 
    570 
    571 
    572 
    573     return PVMFSuccess;
    574 }
    575 
    576 PVMFStatus PVMFAMRFFParserNode::DoGetMetadataValues(PVMFAMRFFNodeCommand& aCmd)
    577 {
    578     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFAMRFFParserNode::DoGetMetadataValues() In"));
    579 
    580     // File must be parsed
    581     if (!iAMRParser)
    582     {
    583         return PVMFErrInvalidState;
    584     }
    585 
    586     PVMFMetadataList* keylistptr_in = NULL;
    587     PVMFMetadataList* keylistptr = NULL;
    588     Oscl_Vector<PvmiKvp, OsclMemAllocator>* valuelistptr = NULL;
    589     uint32 starting_index;
    590     int32 max_entries;
    591 
    592     aCmd.PVMFAMRFFNodeCommand::Parse(keylistptr_in, valuelistptr, starting_index, max_entries);
    593 
    594     if (keylistptr_in == NULL || valuelistptr == NULL)
    595     {
    596         return PVMFErrArgument;
    597     }
    598 
    599     keylistptr = keylistptr_in;
    600     //If numkeys is one, just check to see if the request
    601     //is for ALL metadata
    602     if (keylistptr_in->size() == 1)
    603     {
    604         if (oscl_strncmp((*keylistptr)[0].get_cstr(),
    605                          PVAMR_ALL_METADATA_KEY,
    606                          oscl_strlen(PVAMR_ALL_METADATA_KEY)) == 0)
    607         {
    608             //use the complete metadata key list
    609             keylistptr = &iAvailableMetadataKeys;
    610         }
    611     }
    612 
    613     uint32 numkeys = keylistptr->size();
    614 
    615     if (starting_index > (numkeys - 1) || numkeys == 0 || max_entries == 0)
    616     {
    617         // Don't do anything
    618         return PVMFErrArgument;
    619     }
    620 
    621     uint32 numvalentries = 0;
    622     int32 numentriesadded = 0;
    623     for (uint32 lcv = 0; lcv < numkeys; lcv++)
    624     {
    625         int32 leavecode = 0;
    626         PvmiKvp KeyVal;
    627         KeyVal.key = NULL;
    628 
    629         if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVAMRMETADATA_DURATION_KEY) == 0 &&
    630                 iAMRFileInfo.iDuration > 0)
    631         {
    632             // Movie Duration
    633             // Increment the counter for the number of values found so far
    634             ++numvalentries;
    635 
    636             // Create a value entry if past the starting index
    637             if (numvalentries > starting_index)
    638             {
    639                 char timescalestr[20];
    640                 oscl_snprintf(timescalestr, 20, ";%s%d", PVAMRMETADATA_TIMESCALE, iAMRFileInfo.iTimescale);
    641                 timescalestr[19] = '\0';
    642                 uint32 duration = Oscl_Int64_Utils::get_uint64_lower32(iAMRFileInfo.iDuration);
    643                 int32 retval =
    644                     PVMFCreateKVPUtils::CreateKVPForUInt32Value(KeyVal,
    645                             PVAMRMETADATA_DURATION_KEY,
    646                             duration,
    647                             timescalestr);
    648                 if (retval != PVMFSuccess && retval != PVMFErrArgument)
    649                 {
    650                     break;
    651                 }
    652             }
    653         }
    654         else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVAMRMETADATA_NUMTRACKS_KEY) == 0)
    655         {
    656             // Number of tracks
    657             // Increment the counter for the number of values found so far
    658             ++numvalentries;
    659             // Create a value entry if past the starting index
    660             if (numvalentries > starting_index)
    661             {
    662                 uint32 numtracks = 1;
    663                 PVMFStatus retval = PVMFCreateKVPUtils::CreateKVPForUInt32Value(KeyVal, PVAMRMETADATA_NUMTRACKS_KEY, numtracks);
    664                 if (retval != PVMFSuccess && retval != PVMFErrArgument)
    665                 {
    666                     break;
    667                 }
    668             }
    669         }
    670         else if ((oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVAMRMETADATA_TRACKINFO_BITRATE_KEY) == 0) &&
    671                  iAMRFileInfo.iBitrate > 0)
    672         {
    673             // Bitrate
    674             // Increment the counter for the number of values found so far
    675             ++numvalentries;
    676             int32 retval = 0;
    677             // Create a value entry if past the starting index
    678             if (numvalentries > starting_index)
    679             {
    680                 char indexparam[16];
    681                 oscl_snprintf(indexparam, 16, ";%s", PVAMRMETADATA_INDEX0);
    682                 indexparam[15] = '\0';
    683                 uint32 bitrate = iAMRFileInfo.iBitrate;
    684                 retval = PVMFCreateKVPUtils::CreateKVPForUInt32Value(KeyVal, PVAMRMETADATA_TRACKINFO_BITRATE_KEY, bitrate, indexparam);
    685             }
    686             if (retval != PVMFSuccess && retval != PVMFErrArgument)
    687             {
    688                 break;
    689             }
    690 
    691         }
    692         else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVAMRMETADATA_RANDOM_ACCESS_DENIED_KEY) == 0)
    693         {
    694             /*
    695              * Random Access
    696              * Increment the counter for the number of values found so far
    697              */
    698             ++numvalentries;
    699 
    700             /* Create a value entry if past the starting index */
    701             if (numvalentries > (uint32)starting_index)
    702             {
    703                 bool random_access_denied = false;
    704 
    705                 PVMFStatus retval =
    706                     PVMFCreateKVPUtils::CreateKVPForBoolValue(KeyVal,
    707                             PVAMRMETADATA_RANDOM_ACCESS_DENIED_KEY,
    708                             random_access_denied,
    709                             NULL);
    710                 if (retval != PVMFSuccess && retval != PVMFErrArgument)
    711                 {
    712                     break;
    713                 }
    714             }
    715         }
    716         else if (oscl_strncmp((*keylistptr)[lcv].get_cstr(), PVAMRMETADATA_CLIP_TYPE_KEY, oscl_strlen(PVAMRMETADATA_CLIP_TYPE_KEY)) == 0)
    717         {
    718             /*
    719              * Clip Type
    720              * Increment the counter for the number of values found so far
    721              */
    722             ++numvalentries;
    723 
    724             /* Create a value entry if past the starting index */
    725             if (numvalentries > (uint32)starting_index)
    726             {
    727                 uint32 len = 0;
    728                 char* clipType = NULL;
    729                 {
    730                     len = oscl_strlen("local");
    731                     clipType = OSCL_ARRAY_NEW(char, len + 1);
    732                     oscl_memset(clipType, 0, len + 1);
    733                     oscl_strncpy(clipType, ("local"), len);
    734                 }
    735 
    736                 PVMFStatus retval =
    737                     PVMFCreateKVPUtils::CreateKVPForCharStringValue(KeyVal,
    738                             PVAMRMETADATA_CLIP_TYPE_KEY,
    739                             clipType);
    740 
    741                 OSCL_ARRAY_DELETE(clipType);
    742                 if (retval != PVMFSuccess && retval != PVMFErrArgument)
    743                 {
    744                     break;
    745                 }
    746 
    747             }
    748         }
    749         else if ((oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVAMRMETADATA_TRACKINFO_AUDIO_FORMAT_KEY) == 0) &&
    750                  iAMRFileInfo.iAmrFormat != EAMRUnrecognized)
    751         {
    752             // Format
    753             // Increment the counter for the number of values found so far
    754             ++numvalentries;
    755             int32 retval = 0;
    756 
    757             // Create a value entry if past the starting index
    758             if (numvalentries > starting_index)
    759             {
    760                 char indexparam[16];
    761                 oscl_snprintf(indexparam, 16, ";%s", PVAMRMETADATA_INDEX0);
    762                 indexparam[15] = '\0';
    763 
    764                 switch (iAMRFileInfo.iAmrFormat)
    765                 {
    766                     case EAMRIF2:
    767                         retval = PVMFCreateKVPUtils::CreateKVPForCharStringValue(KeyVal, PVAMRMETADATA_TRACKINFO_AUDIO_FORMAT_KEY, _STRLIT_CHAR(PVMF_MIME_AMR_IF2), indexparam);
    768                         break;
    769 
    770                     case EAMRETS:
    771                     case EAMRIETF_SingleNB:
    772                     case EAMRIETF_MultiNB:
    773                     case EAMRIETF_SingleWB:
    774                     case EAMRIETF_MultiWB:
    775                     case EAMRWMF:
    776                         retval = PVMFCreateKVPUtils::CreateKVPForCharStringValue(KeyVal, PVAMRMETADATA_TRACKINFO_AUDIO_FORMAT_KEY, _STRLIT_CHAR(PVMF_MIME_AMR_IETF), indexparam);
    777                         break;
    778 
    779                     case EAMRUnrecognized:
    780                     default:
    781                         // Should not enter here
    782                         OSCL_ASSERT(false);
    783                         break;
    784                 }
    785                 if (retval != PVMFSuccess && retval != PVMFErrArgument)
    786                 {
    787                     break;
    788                 }
    789             }
    790         }
    791 
    792         if (KeyVal.key != NULL)
    793         {
    794             // Add the entry to the list
    795             leavecode = PushBackKeyVal(valuelistptr, KeyVal);
    796             if (leavecode != 0)
    797             {
    798                 switch (GetValTypeFromKeyString(KeyVal.key))
    799                 {
    800                     case PVMI_KVPVALTYPE_CHARPTR:
    801                         if (KeyVal.value.pChar_value != NULL)
    802                         {
    803                             OSCL_ARRAY_DELETE(KeyVal.value.pChar_value);
    804                             KeyVal.value.pChar_value = NULL;
    805                         }
    806                         break;
    807 
    808                     default:
    809                         // Add more case statements if other value types are returned
    810                         break;
    811                 }
    812 
    813                 OSCL_ARRAY_DELETE(KeyVal.key);
    814                 KeyVal.key = NULL;
    815             }
    816             else
    817             {
    818                 // Increment the counter for number of value entries added to the list
    819                 ++numentriesadded;
    820             }
    821 
    822             // Check if the max number of value entries were added
    823             if (max_entries > 0 && numentriesadded >= max_entries)
    824             {
    825                 // Maximum number of values added so break out of the loop
    826                 break;
    827             }
    828         }
    829     }
    830 
    831     iAMRParserNodeMetadataValueCount = (*valuelistptr).size();
    832 
    833     if ((iCPMMetaDataExtensionInterface != NULL))
    834 
    835     {
    836         iCPMGetMetaDataValuesCmdId =
    837             iCPMMetaDataExtensionInterface->GetNodeMetadataValues(iCPMSessionID,
    838                     (*keylistptr_in),
    839                     (*valuelistptr),
    840                     0);
    841         return PVMFPending;
    842     }
    843     return PVMFSuccess;
    844 }
    845 
    846 PVMFStatus PVMFAMRFFParserNode::DoSetDataSourcePosition(PVMFAMRFFNodeCommand& aCmd)
    847 {
    848     //file must be parsed
    849     if (!iAMRParser)
    850     {
    851         return PVMFErrInvalidState;
    852     }
    853 
    854     if (iSelectedTrackList.size() == 0)
    855     {
    856         return PVMFErrInvalidState;
    857     }
    858 
    859     uint32 targetNPT = 0;
    860     uint32* actualNPT = NULL;
    861     uint32* actualMediaDataTS = NULL;
    862     bool seektosyncpoint = false;
    863     uint32 streamID = 0;
    864 
    865     aCmd.PVMFAMRFFNodeCommand::Parse(targetNPT, actualNPT, actualMediaDataTS, seektosyncpoint, streamID);
    866 
    867     Oscl_Vector<PVAMRFFNodeTrackPortInfo, PVMFAMRParserNodeAllocator>::iterator it;
    868     for (it = iSelectedTrackList.begin(); it != iSelectedTrackList.end(); it++)
    869     {
    870         it->iSendBOS = true;
    871     }
    872 
    873     //save the stream id for next media segment
    874     iStreamID = streamID;
    875 
    876     *actualNPT = 0;
    877     *actualMediaDataTS = 0;
    878 
    879 
    880     // Peek the next sample to get the duration of the last sample
    881     uint32 timestamp;
    882     int32 result = iAMRParser->PeekNextTimestamp(&timestamp);
    883     if (result != bitstreamObject::EVERYTHING_OK)
    884     {
    885         return PVMFErrResource;
    886     }
    887 
    888     // get media data TS (should be equal to iContinuousTimeStamp)
    889     uint32 millisecTS = iSelectedTrackList[0].iClockConverter->get_converted_ts(1000);
    890     *actualMediaDataTS = millisecTS;
    891 
    892     // see if targetNPT is greater or equal than clip duration.
    893     uint32 durationms = 0;
    894     uint32 duration = durationms = Oscl_Int64_Utils::get_uint64_lower32(iAMRFileInfo.iDuration);
    895     uint32 timescale = iAMRFileInfo.iTimescale;
    896     if (timescale > 0 && timescale != 1000)
    897     {
    898         // Convert to milliseconds
    899         MediaClockConverter mcc(timescale);
    900         mcc.update_clock(duration);
    901         durationms = mcc.get_converted_ts(1000);
    902     }
    903     if (targetNPT >= durationms)
    904     {
    905         // report EOS for the track.
    906         for (uint32 i = 0; i < iSelectedTrackList.size(); ++i)
    907         {
    908             iSelectedTrackList[i].iSeqNum = 0;
    909             iSelectedTrackList[i].oEOSReached = true;
    910             iSelectedTrackList[i].oQueueOutgoingMessages = true;
    911             iSelectedTrackList[i].oEOSSent = false;
    912         }
    913         result = iAMRParser->ResetPlayback(0);
    914         if (result != bitstreamObject::EVERYTHING_OK)
    915         {
    916             return PVMFErrResource;
    917         }
    918 
    919         *actualNPT = durationms;
    920         return PVMFSuccess;
    921     }
    922 
    923 
    924     // Reposition
    925     // If new position is past the end of clip, AMR FF should set the position to the last frame
    926     result = iAMRParser->ResetPlayback(targetNPT);
    927     if (result != bitstreamObject::EVERYTHING_OK)
    928     {
    929         if (bitstreamObject::END_OF_FILE == result)
    930         {
    931             for (uint32 i = 0; i < iSelectedTrackList.size(); ++i)
    932             {
    933                 iSelectedTrackList[i].iSeqNum = 0;
    934                 iSelectedTrackList[i].oEOSReached = true;
    935                 iSelectedTrackList[i].oQueueOutgoingMessages = true;
    936                 iSelectedTrackList[i].oEOSSent = false;
    937             }
    938             result = iAMRParser->ResetPlayback(0);
    939             if (result != bitstreamObject::EVERYTHING_OK)
    940             {
    941                 return PVMFErrResource;
    942             }
    943 
    944             *actualNPT = result;
    945             return PVMFSuccess;
    946         }
    947         else if (bitstreamObject::DATA_INSUFFICIENT == result)
    948         {
    949             // This condition could mean 2 things
    950             // 1) End Of File reached for a local content
    951             // 2) Insufficient data condition met for PDL use-case
    952             // For 1 treat it as End of File and send End of Track
    953             // For 2 we dont support reposition until the clip is fully downloaded,
    954             // if the clip is fully downloaded and then we get Insufficient data condition
    955             // treat it as End Of File.
    956             if (iDownloadProgressInterface != NULL)
    957             {
    958                 // Check if the file is completely Downloaded or not
    959                 if (!iDownloadComplete)
    960                 {
    961                     // File not downloaded completely, return not Supported
    962                     return PVMFErrNotSupported;
    963                 }
    964             }
    965 
    966             // Here either file is completely downlaoded if doing PDL or it is a local file,
    967             // treat it as End of File in both cases
    968             for (uint32 i = 0; i < iSelectedTrackList.size(); ++i)
    969             {
    970                 iSelectedTrackList[i].iSeqNum = 0;
    971                 iSelectedTrackList[i].oEOSReached = true;
    972                 iSelectedTrackList[i].oQueueOutgoingMessages = true;
    973                 iSelectedTrackList[i].oEOSSent = false;
    974             }
    975             result = iAMRParser->ResetPlayback(0);
    976             if (result != bitstreamObject::EVERYTHING_OK)
    977             {
    978                 return PVMFErrResource;
    979             }
    980 
    981             *actualNPT = result;
    982             return PVMFSuccess;
    983         }
    984         else
    985         {
    986             return PVMFErrResource;
    987         }
    988     }
    989 
    990     //Peek new position to get the actual new timestamp
    991     uint32 newtimestamp;
    992     result = iAMRParser->PeekNextTimestamp(&newtimestamp);
    993     if (result != bitstreamObject::EVERYTHING_OK)
    994     {
    995         return PVMFErrResource;
    996     }
    997     *actualNPT = newtimestamp;
    998 
    999 
   1000     ResetAllTracks();
   1001     return PVMFSuccess;
   1002 }
   1003 
   1004 
   1005 PVMFStatus PVMFAMRFFParserNode::DoQueryDataSourcePosition(PVMFAMRFFNodeCommand& aCmd)
   1006 {
   1007     //file must be parsed
   1008     if (!iAMRParser)
   1009     {
   1010         return PVMFErrInvalidState;
   1011     }
   1012 
   1013     if (iSelectedTrackList.size() == 0)
   1014     {
   1015         return PVMFErrInvalidState;
   1016     }
   1017 
   1018     uint32 targetNPT = 0;
   1019     uint32* actualNPT = NULL;
   1020     bool seektosyncpoint = false;
   1021 
   1022     aCmd.PVMFAMRFFNodeCommand::Parse(targetNPT, actualNPT, seektosyncpoint);
   1023     if (actualNPT == NULL)
   1024     {
   1025         return PVMFErrArgument;
   1026     }
   1027 
   1028     // Query
   1029     // If new position is past the end of clip, AMR FF should set the position to the last frame
   1030     *actualNPT = iAMRParser->SeekPointFromTimestamp(targetNPT);
   1031 
   1032     return PVMFSuccess;
   1033 }
   1034 
   1035 PVMFStatus PVMFAMRFFParserNode::DoSetDataSourceRate(PVMFAMRFFNodeCommand& aCmd)
   1036 {
   1037     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFAMRFFParserNode::DoSetDataSourceRate() In"));
   1038     OSCL_UNUSED_ARG(aCmd);
   1039     return PVMFSuccess;
   1040 }
   1041 
   1042 bool PVMFAMRFFParserNode::SendEndOfTrackCommand(PVAMRFFNodeTrackPortInfo& aTrackPortInfo)
   1043 {
   1044     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFAMRFFParserNode::SendEndOfTrackCommand() "));
   1045 
   1046     PVMFSharedMediaCmdPtr sharedMediaCmdPtr = PVMFMediaCmd::createMediaCmd();
   1047     sharedMediaCmdPtr->setFormatID(PVMF_MEDIA_CMD_EOS_FORMAT_ID);
   1048 
   1049     sharedMediaCmdPtr->setStreamID(iStreamID);
   1050 
   1051     uint32 timestamp = Oscl_Int64_Utils::get_uint64_lower32(aTrackPortInfo.iContinuousTimeStamp);
   1052 
   1053     sharedMediaCmdPtr->setTimestamp(timestamp);
   1054     sharedMediaCmdPtr->setSeqNum(aTrackPortInfo.iSeqNum++);
   1055 
   1056     PVMFSharedMediaMsgPtr mediaMsgOut;
   1057     convertToPVMFMediaCmdMsg(mediaMsgOut, sharedMediaCmdPtr);
   1058 
   1059     if (aTrackPortInfo.iPort->QueueOutgoingMsg(mediaMsgOut) != PVMFSuccess)
   1060     {
   1061         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFAMRFFParserNode::SendEndOfTrackCommand() Failed-- Busy "));
   1062         return false;
   1063     }
   1064     aTrackPortInfo.oQueueOutgoingMessages = false;
   1065     aTrackPortInfo.oProcessOutgoingMessages = true;
   1066 
   1067     return true;
   1068 }
   1069 
   1070 void PVMFAMRFFParserNode::HandlePortActivity(const PVMFPortActivity &aActivity)
   1071 {
   1072 
   1073     switch (aActivity.iType)
   1074     {
   1075         case PVMF_PORT_ACTIVITY_OUTGOING_MSG:
   1076             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1077                             (0, "PVMFAMRFFParserNode::PortActivity: Outgoing Msg"));
   1078             RunIfNotReady();
   1079             break;
   1080 
   1081         case PVMF_PORT_ACTIVITY_INCOMING_MSG:
   1082             break;
   1083 
   1084         case PVMF_PORT_ACTIVITY_CONNECT:
   1085             break;
   1086 
   1087         case PVMF_PORT_ACTIVITY_DISCONNECT:
   1088             //nothing needed.
   1089 
   1090         case PVMF_PORT_ACTIVITY_CONNECTED_PORT_READY:
   1091             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1092                             (0, "PVMFAMRFFParserNode::PortActivity: Connected port ready"));
   1093             //This message is send by destination port to notify that the earlier Send
   1094             //call that failed due to its busy status can be resumed now.
   1095             if (iOutPort
   1096                     && iOutPort->OutgoingMsgQueueSize() > 0)
   1097             {
   1098                 RunIfNotReady();
   1099             }
   1100             break;
   1101 
   1102         case PVMF_PORT_ACTIVITY_OUTGOING_QUEUE_READY:
   1103             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1104                             (0, "PVMFAMRFFParserNode::PortActivity: Outgoing Queue ready"));
   1105             //this message is sent by the OutgoingQueue when it recovers from
   1106             //the queue full status
   1107             RunIfNotReady();
   1108             break;
   1109 
   1110         default:
   1111             break;
   1112     }
   1113 }
   1114 
   1115 bool PVMFAMRFFParserNode::ProcessCommand()
   1116 {
   1117     //This call will process the first node command in the input queue.
   1118     //Can't do anything when an asynchronous cancel is in progress-- just
   1119     //need to wait on completion.
   1120     if (!iCancelCommand.empty())
   1121         return false;
   1122 
   1123     //If a command is in progress, only a hi-pri command can interrupt it.
   1124     if (!iCurrentCommand.empty()  && !iInputCommands.front().hipri() && iInputCommands.front().iCmd != PVMF_AMR_PARSER_NODE_CMD_CANCEL_GET_LICENSE)
   1125     {
   1126         return false;
   1127     }
   1128 
   1129     //The newest or highest pri command is in the front of the queue.
   1130     OSCL_ASSERT(!iInputCommands.empty());
   1131     PVMFAMRFFNodeCommand& aCmd = iInputCommands.front();
   1132 
   1133     PVMFStatus cmdstatus;
   1134     OsclAny* eventdata = NULL;
   1135     if (aCmd.hipri())
   1136     {
   1137         switch (aCmd.iCmd)
   1138         {
   1139             case PVMF_AMR_PARSER_NODE_CANCELALLCOMMANDS:
   1140                 DoCancelAllCommands(aCmd);
   1141                 break;
   1142 
   1143             case PVMF_AMR_PARSER_NODE_CANCELCOMMAND:
   1144                 DoCancelCommand(aCmd);
   1145                 break;
   1146 
   1147             default:
   1148                 CommandComplete(iInputCommands, aCmd, PVMFErrNotSupported);
   1149                 break;
   1150         }
   1151 
   1152         //If completion is pending, move the command from
   1153         //the input queue to the cancel queue.
   1154         //This is necessary since the input queue could get
   1155         //rearranged by new commands coming in.
   1156     }
   1157     else
   1158     {
   1159         //Process the normal pri commands.
   1160         switch (aCmd.iCmd)
   1161         {
   1162             case PVMF_AMR_PARSER_NODE_QUERYUUID:
   1163                 DoQueryUuid(aCmd);
   1164                 break;
   1165 
   1166             case PVMF_AMR_PARSER_NODE_QUERYINTERFACE:
   1167                 DoQueryInterface(aCmd);
   1168                 break;
   1169 
   1170             case PVMF_AMR_PARSER_NODE_REQUESTPORT:
   1171             {
   1172                 PVMFPortInterface*port;
   1173                 DoRequestPort(aCmd, port);
   1174                 eventdata = (OsclAny*)port;
   1175             }
   1176             break;
   1177 
   1178             case PVMF_AMR_PARSER_NODE_RELEASEPORT:
   1179                 DoReleasePort(aCmd);
   1180                 break;
   1181 
   1182             case PVMF_AMR_PARSER_NODE_INIT:
   1183                 cmdstatus = DoInit(aCmd);
   1184                 if (cmdstatus != PVMFPending)
   1185                 {
   1186                     CommandComplete(iInputCommands, aCmd, cmdstatus);
   1187                 }
   1188                 else
   1189                 {
   1190                     MoveCmdToCurrentQueue(aCmd);
   1191                 }
   1192                 break;
   1193 
   1194             case PVMF_AMR_PARSER_NODE_PREPARE:
   1195                 DoPrepare(aCmd);
   1196                 break;
   1197 
   1198             case PVMF_AMR_PARSER_NODE_START:
   1199                 DoStart(aCmd);
   1200                 break;
   1201 
   1202             case PVMF_AMR_PARSER_NODE_STOP:
   1203                 DoStop(aCmd);
   1204                 break;
   1205 
   1206             case PVMF_AMR_PARSER_NODE_FLUSH:
   1207                 DoFlush(aCmd);
   1208                 break;
   1209 
   1210             case PVMF_AMR_PARSER_NODE_PAUSE:
   1211                 DoPause(aCmd);
   1212                 break;
   1213 
   1214             case PVMF_AMR_PARSER_NODE_RESET:
   1215                 DoReset(aCmd);
   1216                 break;
   1217 
   1218             case PVMF_AMR_PARSER_NODE_GETNODEMETADATAKEYS:
   1219             {
   1220                 cmdstatus = DoGetMetadataKeys(aCmd);
   1221                 if (cmdstatus != PVMFPending)
   1222                 {
   1223                     CommandComplete(iInputCommands, aCmd, cmdstatus);
   1224                 }
   1225                 else
   1226                 {
   1227                     MoveCmdToCurrentQueue(aCmd);
   1228                 }
   1229             }
   1230             break;
   1231 
   1232             case PVMF_AMR_PARSER_NODE_GETNODEMETADATAVALUES:
   1233             {
   1234                 cmdstatus = DoGetMetadataValues(aCmd);
   1235                 if (cmdstatus != PVMFPending)
   1236                 {
   1237                     CommandComplete(iInputCommands, aCmd, cmdstatus);
   1238                 }
   1239                 else
   1240                 {
   1241                     MoveCmdToCurrentQueue(aCmd);
   1242                 }
   1243             }
   1244             break;
   1245 
   1246             case PVMF_AMR_PARSER_NODE_SET_DATASOURCE_POSITION:
   1247             {
   1248                 cmdstatus = DoSetDataSourcePosition(aCmd);
   1249                 if (cmdstatus != PVMFPending)
   1250                 {
   1251                     CommandComplete(iInputCommands, aCmd, cmdstatus);
   1252                 }
   1253                 else
   1254                 {
   1255                     MoveCmdToCurrentQueue(aCmd);
   1256                 }
   1257             }
   1258             break;
   1259 
   1260             case PVMF_AMR_PARSER_NODE_QUERY_DATASOURCE_POSITION:
   1261             {
   1262                 cmdstatus = DoQueryDataSourcePosition(aCmd);
   1263                 if (cmdstatus != PVMFPending)
   1264                 {
   1265                     CommandComplete(iInputCommands, aCmd, cmdstatus);
   1266                 }
   1267                 else
   1268                 {
   1269                     MoveCmdToCurrentQueue(aCmd);
   1270                 }
   1271             }
   1272             break;
   1273 
   1274             case PVMF_AMR_PARSER_NODE_SET_DATASOURCE_RATE:
   1275             {
   1276                 PVMFStatus status = DoSetDataSourceRate(aCmd);
   1277                 CommandComplete(iInputCommands, aCmd, status);
   1278             }
   1279             break;
   1280 
   1281             case PVMF_AMR_PARSER_NODE_GET_LICENSE_W:
   1282             {
   1283                 PVMFStatus status = DoGetLicense(aCmd, true);
   1284                 if (status == PVMFPending)
   1285                 {
   1286                     MoveCmdToCurrentQueue(aCmd);
   1287                 }
   1288                 else
   1289                 {
   1290                     CommandComplete(iInputCommands, aCmd, status);
   1291                 }
   1292             }
   1293             break;
   1294 
   1295             case PVMF_AMR_PARSER_NODE_GET_LICENSE:
   1296             {
   1297                 PVMFStatus status = DoGetLicense(aCmd);
   1298                 if (status == PVMFPending)
   1299                 {
   1300                     MoveCmdToCurrentQueue(aCmd);
   1301                 }
   1302                 else
   1303                 {
   1304                     CommandComplete(iInputCommands, aCmd, status);
   1305                 }
   1306             }
   1307             break;
   1308 
   1309             case PVMF_AMR_PARSER_NODE_CMD_CANCEL_GET_LICENSE:
   1310                 cmdstatus = DoCancelGetLicense(aCmd);
   1311                 switch (cmdstatus)
   1312                 {
   1313                     case PVMFPending:
   1314                         MoveCmdToCancelQueue(aCmd);
   1315                         //wait on CPM callback.
   1316                         break;
   1317                     default:
   1318                         CommandComplete(iInputCommands, aCmd, cmdstatus);
   1319                         break;
   1320                 }
   1321                 break;
   1322 
   1323             default:
   1324                 OSCL_ASSERT(false);
   1325                 CommandComplete(iInputCommands, aCmd, PVMFFailure);
   1326                 break;
   1327         }
   1328     }
   1329     return true;
   1330 }
   1331 
   1332 void PVMFAMRFFParserNode::SetState(TPVMFNodeInterfaceState s)
   1333 {
   1334     PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFAMRFFParserNode:SetState"));
   1335     PVMFNodeInterface::SetState(s);
   1336 }
   1337 
   1338 void PVMFAMRFFParserNode::ReportErrorEvent(PVMFEventType aEventType, OsclAny* aEventData, PVUuid* aEventUUID, int32* aEventCode)
   1339 {
   1340     PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFAMRFFParserNode:ReportErrorEvent Type %d Data %d"
   1341                     , aEventType, aEventData));
   1342 
   1343     if (aEventUUID && aEventCode)
   1344     {
   1345         PVMFBasicErrorInfoMessage* eventmsg;
   1346         PVMF_AMR_PARSER_NODE_NEW(NULL,
   1347                                  PVMFBasicErrorInfoMessage,
   1348                                  (*aEventCode, *aEventUUID, NULL),
   1349                                  eventmsg);
   1350         PVMFAsyncEvent asyncevent(PVMFErrorEvent,
   1351                                   aEventType,
   1352                                   NULL,
   1353                                   OSCL_STATIC_CAST(PVInterface*, eventmsg),
   1354                                   aEventData,
   1355                                   NULL,
   1356                                   0);
   1357         PVMFNodeInterface::ReportErrorEvent(asyncevent);
   1358         eventmsg->removeRef();
   1359     }
   1360     else
   1361     {
   1362         PVMFNodeInterface::ReportErrorEvent(aEventType, aEventData);
   1363     }
   1364     /* Transition the node to an error state */
   1365     iInterfaceState = EPVMFNodeError;
   1366 }
   1367 
   1368 void PVMFAMRFFParserNode::ReportInfoEvent(PVMFEventType aEventType, OsclAny* aEventData, PVUuid* aEventUUID, int32* aEventCode)
   1369 {
   1370     PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFAMRFFParserNode:ReportInfoEvent Type %d Data %d"
   1371                     , aEventType, aEventData));
   1372 
   1373     if (aEventUUID && aEventCode)
   1374     {
   1375         PVMFBasicErrorInfoMessage* eventmsg;
   1376         PVMF_AMR_PARSER_NODE_NEW(NULL,
   1377                                  PVMFBasicErrorInfoMessage,
   1378                                  (*aEventCode, *aEventUUID, NULL),
   1379                                  eventmsg);
   1380         PVMFAsyncEvent asyncevent(PVMFInfoEvent,
   1381                                   aEventType,
   1382                                   NULL,
   1383                                   OSCL_STATIC_CAST(PVInterface*, eventmsg),
   1384                                   aEventData,
   1385                                   NULL,
   1386                                   0);
   1387         PVMFNodeInterface::ReportInfoEvent(asyncevent);
   1388         eventmsg->removeRef();
   1389     }
   1390     else
   1391     {
   1392         PVMFNodeInterface::ReportInfoEvent(aEventType, aEventData);
   1393     }
   1394 }
   1395 
   1396 void PVMFAMRFFParserNode::DoQueryUuid(PVMFAMRFFNodeCommand& aCmd)
   1397 {
   1398     OSCL_String* mimetype;
   1399     Oscl_Vector<PVUuid, OsclMemAllocator> *uuidvec;
   1400     bool exactmatch;
   1401     aCmd.PVMFAMRFFNodeCommandBase::Parse(mimetype, uuidvec, exactmatch);
   1402 
   1403     if (*mimetype == PVMF_DATA_SOURCE_INIT_INTERFACE_MIMETYPE)
   1404     {
   1405         PVUuid uuid(PVMF_DATA_SOURCE_INIT_INTERFACE_UUID);
   1406         uuidvec->push_back(uuid);
   1407     }
   1408     else if (*mimetype == PVMF_TRACK_SELECTION_INTERFACE_MIMETYPE)
   1409     {
   1410         PVUuid uuid(PVMF_TRACK_SELECTION_INTERFACE_UUID);
   1411         uuidvec->push_back(uuid);
   1412     }
   1413     else if (*mimetype == PVMF_DATA_SOURCE_PLAYBACK_CONTROL_INTERFACE_MIMETYPE)
   1414     {
   1415         PVUuid uuid(PvmfDataSourcePlaybackControlUuid);
   1416         uuidvec->push_back(uuid);
   1417     }
   1418     else if (*mimetype == PVMF_META_DATA_EXTENSION_INTERFACE_MIMETYPE)
   1419     {
   1420         PVUuid uuid(KPVMFMetadataExtensionUuid);
   1421         uuidvec->push_back(uuid);
   1422     }
   1423 
   1424     CommandComplete(iInputCommands, aCmd, PVMFSuccess);
   1425     return;
   1426 }
   1427 
   1428 void PVMFAMRFFParserNode::DoQueryInterface(PVMFAMRFFNodeCommand&  aCmd)
   1429 {
   1430     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1431                     (0, "PVMFAMRFFParserNode::DoQueryInterface"));
   1432 
   1433     PVUuid* uuid;
   1434     PVInterface** ptr;
   1435     aCmd.PVMFAMRFFNodeCommandBase::Parse(uuid, ptr);
   1436 
   1437     if (queryInterface(*uuid, *ptr))
   1438     {
   1439         (*ptr)->addRef();
   1440         CommandComplete(iInputCommands, aCmd, PVMFSuccess);
   1441     }
   1442     else
   1443     {
   1444         *ptr = NULL;
   1445         CommandComplete(iInputCommands, aCmd, PVMFErrNotSupported);
   1446     }
   1447     return;
   1448 }
   1449 
   1450 PVMFStatus PVMFAMRFFParserNode::DoInit(PVMFAMRFFNodeCommand& aCmd)
   1451 {
   1452     OSCL_UNUSED_ARG(aCmd);
   1453     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFAMRFFParserNode::DoInitNode() In"));
   1454 
   1455     if (iInterfaceState != EPVMFNodeIdle)
   1456     {
   1457         return PVMFErrInvalidState;
   1458     }
   1459     if (iCPM)
   1460     {
   1461         /*
   1462          * Go thru CPM commands before parsing the file in case
   1463          * of a new source file.
   1464          * - Init CPM
   1465          * - Open Session
   1466          * - Register Content
   1467          * - Get Content Type
   1468          * - Approve Usage
   1469          * In case the source file has already been parsed skip to
   1470          * - Approve Usage
   1471          */
   1472         if (oSourceIsCurrent == false)
   1473         {
   1474             InitCPM();
   1475         }
   1476         else
   1477         {
   1478             RequestUsage();
   1479         }
   1480         return PVMFPending;
   1481     }
   1482     else
   1483     {
   1484         if (CheckForAMRHeaderAvailability() == PVMFSuccess)
   1485         {
   1486             ParseAMRFile();
   1487             SetState(EPVMFNodeInitialized);
   1488             return PVMFSuccess;
   1489         }
   1490     }
   1491     return PVMFSuccess;
   1492 }
   1493 
   1494 PVMFStatus PVMFAMRFFParserNode::ParseAMRFile()
   1495 {
   1496     iAMRParser = OSCL_NEW(CAMRFileParser, ());
   1497     if (!iAMRParser)
   1498     {
   1499         return PVMFErrNoMemory;
   1500     }
   1501 
   1502     PVMFDataStreamFactory* dsFactory = iCPMContentAccessFactory;
   1503     bool calcDuration = true;
   1504     if ((dsFactory == NULL) && (iDataStreamFactory != NULL))
   1505     {
   1506         dsFactory = iDataStreamFactory;
   1507         calcDuration = false;
   1508     }
   1509 
   1510     if (iAMRParser->InitAMRFile(iSourceURL, calcDuration, &iFileServer, dsFactory, iFileHandle, iCountToClaculateRDATimeInterval))
   1511     {
   1512         iAvailableMetadataKeys.clear();
   1513         if (iAMRParser->RetrieveFileInfo(iAMRFileInfo))
   1514         {
   1515             PVMFStatus status = InitMetaData();
   1516             if (status == PVMFSuccess)
   1517             {
   1518                 return PVMFSuccess;
   1519             }
   1520             else
   1521             {
   1522                 CleanupFileSource();
   1523 
   1524                 PVMF_AMRPARSERNODE_LOGERROR((0, "PVMFAMRParserNode::ParseAMRFile() - InitMetaData Failed"));
   1525 
   1526                 CommandComplete(iCurrentCommand,
   1527                                 iCurrentCommand.front(),
   1528                                 status
   1529                                );
   1530             }
   1531 
   1532         }
   1533         else
   1534         {
   1535             return PVMFErrResource;
   1536         }
   1537     }
   1538     else
   1539     {
   1540         //cleanup if failure
   1541         OSCL_DELETE(iAMRParser);
   1542         iAMRParser = NULL;
   1543         return PVMFErrResource;
   1544     }
   1545     return PVMFSuccess;
   1546 }
   1547 
   1548 void PVMFAMRFFParserNode::DoPrepare(PVMFAMRFFNodeCommand& aCmd)
   1549 {
   1550     if (iInterfaceState != EPVMFNodeInitialized)
   1551     {
   1552         CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
   1553         return;
   1554     }
   1555     SetState(EPVMFNodePrepared);
   1556     CommandComplete(iInputCommands, aCmd, PVMFSuccess);
   1557     return;
   1558 }
   1559 
   1560 void PVMFAMRFFParserNode::DoStart(PVMFAMRFFNodeCommand& aCmd)
   1561 {
   1562     if (iInterfaceState != EPVMFNodePrepared &&
   1563             iInterfaceState != EPVMFNodePaused)
   1564     {
   1565         CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
   1566         return;
   1567     }
   1568     SetState(EPVMFNodeStarted);
   1569     CommandComplete(iInputCommands, aCmd, PVMFSuccess);
   1570     return;
   1571 }
   1572 
   1573 void PVMFAMRFFParserNode::DoStop(PVMFAMRFFNodeCommand& aCmd)
   1574 {
   1575     iStreamID = 0;
   1576 
   1577     if (iInterfaceState != EPVMFNodeStarted &&
   1578             iInterfaceState != EPVMFNodePaused)
   1579     {
   1580         CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
   1581         return;
   1582     }
   1583     if (iDataStreamInterface != NULL)
   1584     {
   1585         PVInterface* iFace = OSCL_STATIC_CAST(PVInterface*, iDataStreamInterface);
   1586         PVUuid uuid = PVMIDataStreamSyncInterfaceUuid;
   1587         iDataStreamFactory->DestroyPVMFCPMPluginAccessInterface(uuid, iFace);
   1588         iDataStreamInterface = NULL;
   1589     }
   1590     // stop and reset position to beginning
   1591     ResetAllTracks();
   1592 
   1593     // Reset the AMR FF to beginning
   1594     if (iAMRParser)
   1595     {
   1596         iAMRParser->ResetPlayback(0);
   1597     }
   1598 
   1599     //clear msg queue
   1600     if (iOutPort)
   1601     {
   1602         iOutPort->ClearMsgQueues();
   1603     }
   1604     SetState(EPVMFNodePrepared);
   1605     CommandComplete(iInputCommands, aCmd, PVMFSuccess);
   1606     return;
   1607 }
   1608 
   1609 void PVMFAMRFFParserNode::DoPause(PVMFAMRFFNodeCommand& aCmd)
   1610 {
   1611     if (iInterfaceState != EPVMFNodeStarted)
   1612     {
   1613         CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
   1614         return;
   1615     }
   1616     SetState(EPVMFNodePaused);
   1617     CommandComplete(iInputCommands, aCmd, PVMFSuccess);
   1618     return;
   1619 
   1620 }
   1621 
   1622 void PVMFAMRFFParserNode::DoFlush(PVMFAMRFFNodeCommand& aCmd)
   1623 {
   1624 
   1625     if (iInterfaceState != EPVMFNodeStarted &&
   1626             iInterfaceState != EPVMFNodePaused)
   1627     {
   1628         CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
   1629         return;
   1630     }
   1631 
   1632     /*
   1633      * the flush is asynchronous.  move the command from
   1634      * the input command queue to the current command, where
   1635      * it will remain until the flush completes.
   1636      */
   1637     MoveCmdToCurrentQueue(aCmd);
   1638     return;
   1639 
   1640 }
   1641 
   1642 bool PVMFAMRFFParserNode::FlushPending()
   1643 {
   1644     return (iCurrentCommand.size() > 0
   1645             && iCurrentCommand.front().iCmd == PVMF_AMR_PARSER_NODE_FLUSH);
   1646 }
   1647 
   1648 void PVMFAMRFFParserNode::DoReset(PVMFAMRFFNodeCommand& aCmd)
   1649 {
   1650 
   1651     PVMF_AMRPARSERNODE_LOGSTACKTRACE((0, "PVMFAMRParserNode::DoReset() Called"));
   1652 
   1653     if (iDownloadProgressInterface != NULL)
   1654     {
   1655         iDownloadProgressInterface->cancelResumeNotification();
   1656     }
   1657     MoveCmdToCurrentQueue(aCmd);
   1658     if ((iAMRParser) && (iCPM))
   1659     {
   1660         SendUsageComplete();
   1661     }
   1662     else
   1663     {
   1664         /*
   1665          * Reset without init completing, so just reset the parser node,
   1666          * no CPM stuff necessary
   1667          */
   1668         CompleteReset();
   1669     }
   1670 }
   1671 
   1672 void
   1673 PVMFAMRFFParserNode::MoveCmdToCurrentQueue(PVMFAMRFFNodeCommand& aCmd)
   1674 {
   1675     int32 err;
   1676     OSCL_TRY(err, iCurrentCommand.StoreL(aCmd););
   1677     if (err != OsclErrNone)
   1678     {
   1679         CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
   1680         return;
   1681     }
   1682     iInputCommands.Erase(&aCmd);
   1683     return;
   1684 }
   1685 void
   1686 PVMFAMRFFParserNode::MoveCmdToCancelQueue(PVMFAMRFFNodeCommand& aCmd)
   1687 {
   1688     /*
   1689      * note: the StoreL cannot fail since the queue is never more than 1 deep
   1690      * and we reserved space.
   1691      */
   1692     iCancelCommand.StoreL(aCmd);
   1693     iInputCommands.Erase(&aCmd);
   1694 }
   1695 
   1696 void PVMFAMRFFParserNode::DoCancelAllCommands(PVMFAMRFFNodeCommand& aCmd)
   1697 {
   1698     while (!iCurrentCommand.empty())
   1699     {
   1700         MoveCmdToCancelQueue(aCmd);
   1701     }
   1702 
   1703     //next cancel all queued commands
   1704     //start at element 1 since this cancel command is element 0.
   1705     while (iInputCommands.size() > 1)
   1706     {
   1707         CommandComplete(iInputCommands, iInputCommands[1], PVMFErrCancelled);
   1708     }
   1709 
   1710     //finally, report cancel complete.
   1711     CommandComplete(iInputCommands, iInputCommands[0], PVMFSuccess);
   1712     return;
   1713 
   1714 }
   1715 
   1716 void PVMFAMRFFParserNode::DoCancelCommand(PVMFAMRFFNodeCommand& aCmd)
   1717 {
   1718     PVMFCommandId id;
   1719     aCmd.PVMFAMRFFNodeCommandBase::Parse(id);
   1720     {
   1721         PVMFAMRFFNodeCommand* cmd = iCurrentCommand.FindById(id);
   1722         if (cmd)
   1723         {
   1724             //cancel the queued command
   1725 
   1726             MoveCmdToCancelQueue(*cmd);
   1727             CommandComplete(iInputCommands, aCmd, PVMFSuccess);
   1728             return;
   1729         }
   1730     }
   1731 
   1732     {
   1733         PVMFAMRFFNodeCommand* cmd = iInputCommands.FindById(id, 1);
   1734         if (cmd)
   1735         {
   1736             //cancel the queued command
   1737             CommandComplete(iInputCommands, *cmd, PVMFErrCancelled);
   1738 
   1739             CommandComplete(iInputCommands, aCmd, PVMFSuccess);
   1740             return;
   1741         }
   1742     }
   1743     CommandComplete(iInputCommands, aCmd, PVMFErrArgument);
   1744     return;
   1745 }
   1746 
   1747 void PVMFAMRFFParserNode::DoRequestPort(PVMFAMRFFNodeCommand& aCmd, PVMFPortInterface*&aPort)
   1748 {
   1749     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFAMRFFParserNode::DoRequestPort() In"));
   1750     aPort = NULL;
   1751 
   1752     if ((iInterfaceState != EPVMFNodePrepared) || (!iAMRParser))
   1753     {
   1754         PVMF_AMRPARSERNODE_LOGERROR((0, "PVMFASFParserNode::DoRequestPort() - Invalid State"));
   1755         CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
   1756         return;
   1757     }
   1758 
   1759     int32 tag = 0;
   1760     OSCL_String* mime_string;
   1761     aCmd.PVMFAMRFFNodeCommandBase::Parse(tag, mime_string);
   1762 
   1763     if (tag != PVMF_AMRFFPARSER_NODE_PORT_TYPE_SOURCE)
   1764     {
   1765         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   1766                         (0, "PVMFAMRFFParserNode::DoRequestPort: Error - Invalid port tag"));
   1767         CommandComplete(iInputCommands, aCmd, PVMFFailure);
   1768         return;
   1769     }
   1770 
   1771     if (iOutPort)
   1772     {
   1773         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1774                         (0, "PVMFAMRFFParserNode::DoRequestPort: Error - port already exists"));
   1775         CommandComplete(iInputCommands, aCmd, PVMFFailure);
   1776         return;
   1777     }
   1778 
   1779     if ((int32)aCmd.iParam1 == PVMF_AMRFFPARSER_NODE_PORT_TYPE_SOURCE)
   1780     {
   1781 
   1782         iOutPort = OSCL_NEW(PVMFAMRFFParserOutPort, (PVMF_AMRFFPARSER_NODE_PORT_TYPE_SOURCE, this));
   1783         if (!iOutPort)
   1784         {
   1785             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1786                             (0, "PVMFAMRFFParserNode::DoRequestPort: Error - no memory"));
   1787             CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
   1788             return;
   1789         }
   1790         if (mime_string)
   1791         {
   1792             PVMFFormatType fmt = mime_string->get_str();
   1793             if (!iOutPort->IsFormatSupported(fmt))
   1794             {
   1795                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1796                                 (0, "PVMFAMRFFParserNode::DoRequestPort: Error - format not supported"));
   1797                 OSCL_DELETE(iOutPort);
   1798                 iOutPort = NULL;
   1799                 CommandComplete(iInputCommands, aCmd, PVMFFailure);
   1800                 return;
   1801             }
   1802         }
   1803 
   1804         MediaClockConverter* clockconv = NULL;
   1805         OsclMemPoolFixedChunkAllocator* trackdatamempool = NULL;
   1806         PVMFSimpleMediaBufferCombinedAlloc* mediadataimplalloc = NULL;
   1807         PVMFMemPoolFixedChunkAllocator* mediadatamempool = NULL;
   1808         int32 leavecode = 0;
   1809         OSCL_TRY(leavecode,
   1810                  clockconv = OSCL_NEW(MediaClockConverter, (iAMRFileInfo.iTimescale));
   1811                  trackdatamempool = OSCL_NEW(OsclMemPoolFixedChunkAllocator, (PVAMRFF_MEDIADATA_POOLNUM));
   1812                  mediadataimplalloc = OSCL_NEW(PVMFSimpleMediaBufferCombinedAlloc, (trackdatamempool));
   1813                  mediadatamempool = OSCL_NEW(PVMFMemPoolFixedChunkAllocator, ("AmrFFPar", PVAMRFF_MEDIADATA_POOLNUM, PVAMRFF_MEDIADATA_CHUNKSIZE));
   1814                 );
   1815 
   1816         if (leavecode || !clockconv || !trackdatamempool || !mediadataimplalloc || !mediadatamempool)
   1817         {
   1818             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1819                             (0, "PVMFAMRFFParserNode::DoRequestPort: Error - unable to create clockconv, trackdatamempool, mediadataimplalloc, and mediadatamempool"));
   1820             if (iOutPort)
   1821             {
   1822                 OSCL_DELETE(iOutPort);
   1823                 iOutPort = NULL;
   1824             }
   1825             if (clockconv)
   1826             {
   1827                 OSCL_DELETE(clockconv);
   1828             }
   1829             if (trackdatamempool)
   1830             {
   1831                 OSCL_DELETE(trackdatamempool);
   1832             }
   1833             if (mediadataimplalloc)
   1834             {
   1835                 OSCL_DELETE(mediadataimplalloc);
   1836             }
   1837             if (mediadatamempool)
   1838             {
   1839                 OSCL_DELETE(mediadatamempool);
   1840             }
   1841 
   1842             CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
   1843             return;
   1844         }
   1845 
   1846         mediadatamempool->enablenullpointerreturn();
   1847 
   1848         PVAMRFFNodeTrackPortInfo trackportinfo;
   1849 
   1850         trackportinfo.iTrackId = 0;  // Only support 1 channel so far
   1851         trackportinfo.iTag = PVMF_AMRFFPARSER_NODE_PORT_TYPE_SOURCE;
   1852         trackportinfo.iPort = iOutPort;
   1853 
   1854         trackportinfo.iClockConverter = clockconv;
   1855         trackportinfo.iTrackDataMemoryPool = trackdatamempool;
   1856         trackportinfo.iMediaDataImplAlloc = mediadataimplalloc;
   1857         trackportinfo.iMediaDataMemPool = mediadatamempool;
   1858 
   1859         aPort = iOutPort;
   1860 
   1861         OsclMemPoolResizableAllocator* trackDataResizableMemPool = NULL;
   1862         trackportinfo.iResizableDataMemoryPoolSize = PVMF_AMR_PARSER_NODE_MAX_AUDIO_DATA_MEM_POOL_SIZE;
   1863         PVMF_AMR_PARSER_NODE_NEW(NULL,
   1864                                  OsclMemPoolResizableAllocator,
   1865                                  (trackportinfo.iResizableDataMemoryPoolSize,
   1866                                   PVMF_AMR_PARSER_NODE_DATA_MEM_POOL_GROWTH_LIMIT),
   1867                                  trackDataResizableMemPool);
   1868 
   1869         PVUuid eventuuid = PVMFAMRParserNodeEventTypesUUID;
   1870         int32   errcode = PVMFAMRFFParserErrTrackMediaMsgAllocatorCreationFailed;
   1871 
   1872         PVMFResizableSimpleMediaMsgAlloc* resizableSimpleMediaDataImplAlloc = NULL;
   1873         OsclExclusivePtr<PVMFResizableSimpleMediaMsgAlloc> resizableSimpleMediaDataImplAllocAutoPtr;
   1874         PVMF_AMR_PARSER_NODE_NEW(NULL,
   1875                                  PVMFResizableSimpleMediaMsgAlloc,
   1876                                  (trackDataResizableMemPool),
   1877                                  resizableSimpleMediaDataImplAlloc);
   1878 
   1879         if (trackDataResizableMemPool == NULL)
   1880         {
   1881             PVMF_AMRPARSERNODE_LOGERROR((0, "PVMFAMRParserNode::DoRequestPort() - trackDataResizableMemPool Alloc Failed"));
   1882             CommandComplete(iInputCommands,
   1883                             aCmd,
   1884                             PVMFErrNoMemory,
   1885                             NULL,
   1886                             &eventuuid,
   1887                             &errcode);
   1888             return;
   1889         }
   1890 
   1891         trackDataResizableMemPool->enablenullpointerreturn();
   1892 
   1893         trackportinfo.iResizableSimpleMediaMsgAlloc = resizableSimpleMediaDataImplAlloc;
   1894         trackportinfo.iResizableDataMemoryPool = trackDataResizableMemPool;
   1895         trackportinfo.iNode = this;
   1896         uint8* typeSpecificInfoBuff = iAMRParser->getCodecSpecificInfo();
   1897         uint32 typeSpecificDataLength = MAX_NUM_PACKED_INPUT_BYTES;
   1898         if ((int32)typeSpecificDataLength > 0)
   1899         {
   1900             OsclMemAllocDestructDealloc<uint8> my_alloc;
   1901             OsclRefCounter* my_refcnt;
   1902             uint aligned_refcnt_size =
   1903                 oscl_mem_aligned_size(sizeof(OsclRefCounterSA< OsclMemAllocDestructDealloc<uint8> >));
   1904             uint aligned_type_specific_info_size =
   1905                 oscl_mem_aligned_size(typeSpecificDataLength);
   1906             uint8* my_ptr = NULL;
   1907             int32 errcode = 0;
   1908             OSCL_TRY(errcode,
   1909                      my_ptr = (uint8*) my_alloc.ALLOCATE(aligned_refcnt_size + aligned_type_specific_info_size));
   1910 
   1911             if (errcode != OsclErrNone)
   1912             {
   1913                 PVMF_AMRPARSERNODE_LOGERROR((0, "PVMFAMRParserNode::PopulateTrackInfoVec - Unable to Allocate Memory"));
   1914             }
   1915 
   1916             my_refcnt = OSCL_PLACEMENT_NEW(my_ptr, OsclRefCounterSA< OsclMemAllocDestructDealloc<uint8> >(my_ptr));
   1917             my_ptr += aligned_refcnt_size;
   1918 
   1919             OsclMemoryFragment memfrag;
   1920             memfrag.len = typeSpecificDataLength;
   1921             memfrag.ptr = typeSpecificInfoBuff;
   1922 
   1923             OsclRefCounterMemFrag tmpRefcntMemFrag(memfrag, my_refcnt, memfrag.len);
   1924             trackportinfo.iFormatSpecificConfig = tmpRefcntMemFrag;
   1925         }
   1926 
   1927         iSelectedTrackList.push_back(trackportinfo);
   1928 
   1929 
   1930         CommandComplete(iInputCommands, aCmd, PVMFSuccess, (OsclAny*)aPort);
   1931         return;
   1932     }
   1933     else
   1934     {
   1935         // don't support other types yet
   1936         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1937                         (0, "PVMFAMRFFParserNode::DoRequestPort: Error - type not supported"));
   1938         CommandComplete(iInputCommands, aCmd, PVMFFailure);
   1939         return;
   1940     }
   1941 
   1942 }
   1943 
   1944 void PVMFAMRFFParserNode::DoReleasePort(PVMFAMRFFNodeCommand& aCmd)
   1945 {
   1946 
   1947     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1948                     (0, "PVMFAMRFFParserNode::DoReleasePort"));
   1949 
   1950     // search for the matching port address
   1951     // disconnect it, if needed
   1952     // cleanup the buffers associated with it
   1953     // delete the port
   1954     // set the address to NULL
   1955 
   1956     // Remove the selected track from the track list
   1957     for (uint32 i = 0; i < iSelectedTrackList.size(); i++)
   1958     {
   1959         if (iSelectedTrackList[i].iPort == aCmd.iParam1)
   1960         {
   1961             // Found the element. So erase it
   1962             iSelectedTrackList[i].iMediaData.Unbind();
   1963             OSCL_DELETE(((PVMFAMRFFParserOutPort*)iSelectedTrackList[i].iPort));
   1964             iSelectedTrackList[i].iPort = NULL;
   1965             iOutPort = NULL;
   1966             if (iSelectedTrackList[i].iClockConverter)
   1967             {
   1968                 OSCL_DELETE(iSelectedTrackList[i].iClockConverter);
   1969             }
   1970             if (iSelectedTrackList[i].iTrackDataMemoryPool)
   1971             {
   1972                 iSelectedTrackList[i].iTrackDataMemoryPool->removeRef();
   1973                 iSelectedTrackList[i].iTrackDataMemoryPool = NULL;
   1974             }
   1975             if (iSelectedTrackList[i].iMediaDataImplAlloc)
   1976             {
   1977                 OSCL_DELETE(iSelectedTrackList[i].iMediaDataImplAlloc);
   1978             }
   1979             if (iSelectedTrackList[i].iMediaDataMemPool)
   1980             {
   1981                 iSelectedTrackList[i].iMediaDataMemPool->CancelFreeChunkAvailableCallback();
   1982                 iSelectedTrackList[i].iMediaDataMemPool->removeRef();
   1983                 iSelectedTrackList[i].iMediaDataMemPool = NULL;
   1984             }
   1985 
   1986             if (iSelectedTrackList[i].iResizableSimpleMediaMsgAlloc != NULL)
   1987             {
   1988                 PVMF_AMR_PARSER_NODE_DELETE(NULL,
   1989                                             PVMFResizableSimpleMediaMsgAlloc,
   1990                                             iSelectedTrackList[i].iResizableSimpleMediaMsgAlloc);
   1991                 iSelectedTrackList[i].iResizableSimpleMediaMsgAlloc = NULL;
   1992             }
   1993             if (iSelectedTrackList[i].iResizableDataMemoryPool != NULL)
   1994             {
   1995                 iSelectedTrackList[i].iResizableDataMemoryPool->removeRef();
   1996                 iSelectedTrackList[i].iResizableDataMemoryPool = NULL;
   1997             }
   1998             iSelectedTrackList.erase(&iSelectedTrackList[i]);
   1999             CommandComplete(iInputCommands, aCmd, PVMFSuccess);
   2000             return;
   2001         }
   2002     }
   2003 
   2004     //if we get here the track was not found
   2005     CommandComplete(iInputCommands, aCmd, PVMFErrBadHandle);
   2006     return;
   2007 
   2008 }
   2009 
   2010 void PVMFAMRFFParserNode::ResetAllTracks()
   2011 {
   2012     for (uint32 i = 0; i < iSelectedTrackList.size(); ++i)
   2013     {
   2014         iSelectedTrackList[i].iMediaData.Unbind();
   2015         iSelectedTrackList[i].iSeqNum = 0;
   2016         iSelectedTrackList[i].iFirstFrame = true;
   2017 
   2018         iSelectedTrackList[i].oEOSSent = false;
   2019         iSelectedTrackList[i].oEOSReached = false;
   2020         iSelectedTrackList[i].oQueueOutgoingMessages = true;
   2021     }
   2022 }
   2023 
   2024 bool PVMFAMRFFParserNode::ReleaseAllPorts()
   2025 {
   2026     while (!iSelectedTrackList.empty())
   2027     {
   2028         iSelectedTrackList[0].iPort->Disconnect();
   2029         iSelectedTrackList[0].iMediaData.Unbind();
   2030         OSCL_DELETE(((PVMFAMRFFParserOutPort*)iSelectedTrackList[0].iPort));
   2031         if (iSelectedTrackList[0].iClockConverter)
   2032         {
   2033             OSCL_DELETE(iSelectedTrackList[0].iClockConverter);
   2034         }
   2035         if (iSelectedTrackList[0].iTrackDataMemoryPool)
   2036         {
   2037             iSelectedTrackList[0].iTrackDataMemoryPool->removeRef();
   2038             iSelectedTrackList[0].iTrackDataMemoryPool = NULL;
   2039         }
   2040         if (iSelectedTrackList[0].iMediaDataImplAlloc)
   2041         {
   2042             OSCL_DELETE(iSelectedTrackList[0].iMediaDataImplAlloc);
   2043         }
   2044         if (iSelectedTrackList[0].iMediaDataMemPool)
   2045         {
   2046             iSelectedTrackList[0].iMediaDataMemPool->CancelFreeChunkAvailableCallback();
   2047             iSelectedTrackList[0].iMediaDataMemPool->removeRef();
   2048             iSelectedTrackList[0].iMediaDataMemPool = NULL;
   2049         }
   2050         iOutPort = NULL;
   2051 
   2052         if (iSelectedTrackList[0].iResizableSimpleMediaMsgAlloc != NULL)
   2053         {
   2054             PVMF_AMR_PARSER_NODE_DELETE(NULL,
   2055                                         PVMFResizableSimpleMediaMsgAlloc,
   2056                                         iSelectedTrackList[0].iResizableSimpleMediaMsgAlloc);
   2057             iSelectedTrackList[0].iResizableSimpleMediaMsgAlloc = NULL;
   2058         }
   2059         if (iSelectedTrackList[0].iResizableDataMemoryPool != NULL)
   2060         {
   2061             iSelectedTrackList[0].iResizableDataMemoryPool->removeRef();
   2062             iSelectedTrackList[0].iResizableDataMemoryPool = NULL;
   2063         }
   2064         iSelectedTrackList.erase(iSelectedTrackList.begin());
   2065     }
   2066     return true;
   2067 }
   2068 
   2069 void PVMFAMRFFParserNode::CleanupFileSource()
   2070 {
   2071     iAvailableMetadataKeys.clear();
   2072 
   2073     if (iAMRParser)
   2074     {
   2075         OSCL_DELETE(iAMRParser);
   2076     }
   2077     iAMRParser = NULL;
   2078 
   2079     iUseCPMPluginRegistry = false;
   2080     iCPMSourceData.iFileHandle = NULL;
   2081     iAMRParserNodeMetadataValueCount = 0;
   2082 
   2083     if (iCPMContentAccessFactory != NULL)
   2084     {
   2085         iCPMContentAccessFactory->removeRef();
   2086         iCPMContentAccessFactory = NULL;
   2087     }
   2088     if (iDataStreamFactory != NULL)
   2089     {
   2090         iDataStreamFactory->removeRef();
   2091         iDataStreamFactory = NULL;
   2092     }
   2093     iCPMContentType = PVMF_CPM_CONTENT_FORMAT_UNKNOWN;
   2094     iPreviewMode = false;
   2095     oSourceIsCurrent = false;
   2096     if (iFileHandle)
   2097     {
   2098         OSCL_DELETE(iFileHandle);
   2099     }
   2100     iFileHandle = NULL;
   2101 }
   2102 
   2103 void PVMFAMRFFParserNode::CommandComplete(PVMFAMRFFNodeCmdQ& aCmdQ, PVMFAMRFFNodeCommand& aCmd, PVMFStatus aStatus, PVInterface*aExtMsg, OsclAny* aEventData)
   2104 {
   2105     PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFAMRFFParserNode:CommandComplete Id %d Cmd %d Status %d Context %d Data %d"
   2106                     , aCmd.iId, aCmd.iCmd, aStatus, aCmd.iContext, aEventData));
   2107 
   2108     PVInterface* extif = NULL;
   2109     PVMFBasicErrorInfoMessage* errormsg = NULL;
   2110     if (aExtMsg)
   2111     {
   2112         extif = aExtMsg;
   2113     }
   2114 
   2115     PVMFCmdResp resp(aCmd.iId, aCmd.iContext, aStatus, extif, aEventData);
   2116     PVMFSessionId session = aCmd.iSession;
   2117 
   2118     /* Erase the command from the queue. */
   2119     aCmdQ.Erase(&aCmd);
   2120 
   2121     /* Report completion to the session observer.*/
   2122     ReportCmdCompleteEvent(session, resp);
   2123 
   2124     if (errormsg)
   2125     {
   2126         errormsg->removeRef();
   2127     }
   2128 }
   2129 
   2130 void PVMFAMRFFParserNode::CommandComplete(PVMFAMRFFNodeCmdQ& aCmdQ,
   2131         PVMFAMRFFNodeCommand& aCmd,
   2132         PVMFStatus aStatus,
   2133         OsclAny* aEventData,
   2134         PVUuid* aEventUUID,
   2135         int32* aEventCode,
   2136         PVInterface* aExtMsg)
   2137 {
   2138     PVMF_AMRPARSERNODE_LOGSTACKTRACE((0, "PVMFAMRParserNode::CommandComplete() In Id %d Cmd %d Status %d Context %d Data %d",
   2139                                       aCmd.iId, aCmd.iCmd, aStatus, aCmd.iContext, aEventData));
   2140 
   2141     PVInterface* extif = NULL;
   2142     PVMFBasicErrorInfoMessage* errormsg = NULL;
   2143     if (aExtMsg)
   2144     {
   2145         extif = aExtMsg;
   2146     }
   2147     else if (aEventUUID && aEventCode)
   2148     {
   2149         errormsg =
   2150             OSCL_NEW(PVMFBasicErrorInfoMessage, (*aEventCode, *aEventUUID, NULL));
   2151         extif = OSCL_STATIC_CAST(PVInterface*, errormsg);
   2152     }
   2153 
   2154     PVMFCmdResp resp(aCmd.iId, aCmd.iContext, aStatus, extif, aEventData);
   2155     PVMFSessionId session = aCmd.iSession;
   2156 
   2157     /* Erase the command from the queue. */
   2158     if (!aCmdQ.empty())
   2159     {
   2160         aCmdQ.Erase(&aCmd);
   2161     }
   2162 
   2163     /* Report completion to the session observer.*/
   2164     ReportCmdCompleteEvent(session, resp);
   2165 
   2166     if (errormsg)
   2167     {
   2168         errormsg->removeRef();
   2169     }
   2170 }
   2171 
   2172 PVMFCommandId PVMFAMRFFParserNode::QueueCommandL(PVMFAMRFFNodeCommand& aCmd)
   2173 {
   2174     if (IsAdded())
   2175     {
   2176         PVMFCommandId id;
   2177         id = iInputCommands.AddL(aCmd);
   2178         /* Wakeup the AO */
   2179         RunIfNotReady();
   2180         return id;
   2181     }
   2182     OSCL_LEAVE(OsclErrInvalidState);
   2183     return -1;
   2184 }
   2185 
   2186 void PVMFAMRFFParserNode::addRef()
   2187 {
   2188     ++iExtensionRefCount;
   2189 }
   2190 
   2191 void PVMFAMRFFParserNode::removeRef()
   2192 {
   2193     --iExtensionRefCount;
   2194 }
   2195 
   2196 PVMFStatus PVMFAMRFFParserNode::QueryInterfaceSync(PVMFSessionId aSession,
   2197         const PVUuid& aUuid,
   2198         PVInterface*& aInterfacePtr)
   2199 {
   2200     OSCL_UNUSED_ARG(aSession);
   2201     aInterfacePtr = NULL;
   2202     if (queryInterface(aUuid, aInterfacePtr))
   2203     {
   2204         aInterfacePtr->addRef();
   2205         return PVMFSuccess;
   2206     }
   2207     return PVMFErrNotSupported;
   2208 }
   2209 
   2210 bool PVMFAMRFFParserNode::queryInterface(const PVUuid& uuid, PVInterface*& iface)
   2211 {
   2212     if (uuid == PVMF_DATA_SOURCE_INIT_INTERFACE_UUID)
   2213     {
   2214         PVMFDataSourceInitializationExtensionInterface* myInterface = OSCL_STATIC_CAST(PVMFDataSourceInitializationExtensionInterface*, this);
   2215         iface = OSCL_STATIC_CAST(PVInterface*, myInterface);
   2216     }
   2217     else if (uuid == PVMF_TRACK_SELECTION_INTERFACE_UUID)
   2218     {
   2219         PVMFTrackSelectionExtensionInterface* myInterface = OSCL_STATIC_CAST(PVMFTrackSelectionExtensionInterface*, this);
   2220         iface = OSCL_STATIC_CAST(PVInterface*, myInterface);
   2221     }
   2222     else if (uuid == KPVMFMetadataExtensionUuid)
   2223     {
   2224         PVMFMetadataExtensionInterface* myInterface = OSCL_STATIC_CAST(PVMFMetadataExtensionInterface*, this);
   2225         iface = OSCL_STATIC_CAST(PVInterface*, myInterface);
   2226     }
   2227     else if (uuid == PvmfDataSourcePlaybackControlUuid)
   2228     {
   2229         PvmfDataSourcePlaybackControlInterface* myInterface = OSCL_STATIC_CAST(PvmfDataSourcePlaybackControlInterface*, this);
   2230         iface = OSCL_STATIC_CAST(PVInterface*, myInterface);
   2231     }
   2232     else if (uuid == PVMIDatastreamuserInterfaceUuid)
   2233     {
   2234         PVMIDatastreamuserInterface* myInterface = OSCL_STATIC_CAST(PVMIDatastreamuserInterface*, this);
   2235         iface = OSCL_STATIC_CAST(PVInterface*, myInterface);
   2236     }
   2237     else if (uuid == PVMF_FF_PROGDOWNLOAD_SUPPORT_INTERFACE_UUID)
   2238     {
   2239         PVMFFormatProgDownloadSupportInterface* myInterface = OSCL_STATIC_CAST(PVMFFormatProgDownloadSupportInterface*, this);
   2240         iface = OSCL_STATIC_CAST(PVInterface*, myInterface);
   2241     }
   2242     else if (uuid == PVMFCPMPluginLicenseInterfaceUuid)
   2243     {
   2244         PVMFCPMPluginLicenseInterface* myInterface = OSCL_STATIC_CAST(PVMFCPMPluginLicenseInterface*, this);
   2245         iface = OSCL_STATIC_CAST(PVInterface*, myInterface);
   2246     }
   2247     else
   2248     {
   2249         return false;
   2250     }
   2251     return true;
   2252 }
   2253 
   2254 
   2255 PVMFStatus PVMFAMRFFParserNode::SetSourceInitializationData(OSCL_wString& aSourceURL, PVMFFormatType& aSourceFormat, OsclAny* aSourceData)
   2256 {
   2257     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFAMRFFParserNode::SetSourceInitializationData() called"));
   2258     if (aSourceFormat == PVMF_MIME_AMRFF)
   2259     {
   2260         /* Clean up any previous sources */
   2261         CleanupFileSource();
   2262 
   2263         iSourceFormat = aSourceFormat;
   2264         iSourceURL = aSourceURL;
   2265         if (aSourceData)
   2266         {
   2267             // Old context object? query for local datasource availability
   2268             PVInterface* pvInterface =
   2269                 OSCL_STATIC_CAST(PVInterface*, aSourceData);
   2270 
   2271             PVInterface* localDataSrc = NULL;
   2272             PVUuid localDataSrcUuid(PVMF_LOCAL_DATASOURCE_UUID);
   2273 
   2274             if (pvInterface->queryInterface(localDataSrcUuid, localDataSrc))
   2275             {
   2276                 PVMFLocalDataSource* context =
   2277                     OSCL_STATIC_CAST(PVMFLocalDataSource*, localDataSrc);
   2278 
   2279                 iPreviewMode = context->iPreviewMode;
   2280                 if (context->iFileHandle)
   2281                 {
   2282 
   2283                     PVMF_AMR_PARSER_NODE_NEW(NULL,
   2284                                              OsclFileHandle,
   2285                                              (*(context->iFileHandle)),
   2286                                              iFileHandle);
   2287 
   2288                     iCPMSourceData.iFileHandle = iFileHandle;
   2289                 }
   2290                 iCPMSourceData.iPreviewMode = iPreviewMode;
   2291                 iCPMSourceData.iIntent = context->iIntent;
   2292 
   2293             }
   2294             else
   2295             {
   2296                 // New context object ?
   2297                 PVInterface* sourceDataContext = NULL;
   2298                 PVInterface* commonDataContext = NULL;
   2299                 PVUuid sourceContextUuid(PVMF_SOURCE_CONTEXT_DATA_UUID);
   2300                 PVUuid commonContextUuid(PVMF_SOURCE_CONTEXT_DATA_COMMON_UUID);
   2301                 if (pvInterface->queryInterface(sourceContextUuid, sourceDataContext) &&
   2302                         sourceDataContext->queryInterface(commonContextUuid, commonDataContext))
   2303                 {
   2304                     PVMFSourceContextDataCommon* context =
   2305                         OSCL_STATIC_CAST(PVMFSourceContextDataCommon*, commonDataContext);
   2306 
   2307                     iPreviewMode = context->iPreviewMode;
   2308                     if (context->iFileHandle)
   2309                     {
   2310 
   2311                         PVMF_AMR_PARSER_NODE_NEW(NULL,
   2312                                                  OsclFileHandle,
   2313                                                  (*(context->iFileHandle)),
   2314                                                  iFileHandle);
   2315 
   2316                         iCPMSourceData.iFileHandle = iFileHandle;
   2317                     }
   2318                     iCPMSourceData.iPreviewMode = iPreviewMode;
   2319                     iCPMSourceData.iIntent = context->iIntent;
   2320                 }
   2321             }
   2322         }
   2323         /*
   2324          * create a CPM object here...
   2325          */
   2326         iUseCPMPluginRegistry = true;
   2327         {
   2328             //cleanup any prior instance
   2329             if (iCPM)
   2330             {
   2331                 iCPM->ThreadLogoff();
   2332                 PVMFCPMFactory::DestroyContentPolicyManager(iCPM);
   2333                 iCPM = NULL;
   2334             }
   2335             iCPM = PVMFCPMFactory::CreateContentPolicyManager(*this);
   2336             //thread logon may leave if there are no plugins
   2337             int32 err;
   2338             OSCL_TRY(err, iCPM->ThreadLogon(););
   2339             OSCL_FIRST_CATCH_ANY(err,
   2340                                  iCPM->ThreadLogoff();
   2341                                  PVMFCPMFactory::DestroyContentPolicyManager(iCPM);
   2342                                  iCPM = NULL;
   2343                                  iUseCPMPluginRegistry = false;
   2344                                 );
   2345         }
   2346         return PVMFSuccess;
   2347     }
   2348     PVMF_AMRPARSERNODE_LOGERROR((0, "PVMFAMRParserNode::SetSourceInitializationData - Unsupported Format"));
   2349     return PVMFFailure;
   2350 }
   2351 
   2352 PVMFStatus PVMFAMRFFParserNode::SetClientPlayBackClock(PVMFMediaClock* aClientClock)
   2353 {
   2354     OSCL_UNUSED_ARG(aClientClock);
   2355     return PVMFSuccess;
   2356 }
   2357 
   2358 PVMFStatus PVMFAMRFFParserNode::SetEstimatedServerClock(PVMFMediaClock* aClientClock)
   2359 {
   2360     OSCL_UNUSED_ARG(aClientClock);
   2361     return PVMFSuccess;
   2362 }
   2363 
   2364 PVMFStatus PVMFAMRFFParserNode::GetMediaPresentationInfo(PVMFMediaPresentationInfo& aInfo)
   2365 {
   2366     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFAMRFFParserNode::GetMediaPresentationInfo() called"));
   2367 
   2368     if (!iAMRParser)
   2369     {
   2370         return PVMFFailure;
   2371     }
   2372 
   2373     aInfo.setDurationValue(iAMRFileInfo.iDuration);
   2374     // Current version of AAC parser is limited to 1 channel
   2375     PVMFTrackInfo tmpTrackInfo;
   2376     tmpTrackInfo.setPortTag(PVMF_AMRFFPARSER_NODE_PORT_TYPE_SOURCE);
   2377     tmpTrackInfo.setTrackID(0);
   2378     TPVAmrFileInfo amrinfo;
   2379     if (!iAMRParser->RetrieveFileInfo(amrinfo)) return PVMFErrNotSupported;
   2380 
   2381     switch (amrinfo.iAmrFormat)
   2382     {
   2383             // Supported formats
   2384         case EAMRIF2:       // IF2
   2385         case EAMRIETF_SingleNB: // IETF
   2386         case EAMRIETF_SingleWB:
   2387             break;
   2388 
   2389             // Everything else is not supported
   2390         case EAMRETS:
   2391         case EAMRIETF_MultiNB:
   2392         case EAMRIETF_MultiWB:
   2393         case EAMRWMF:
   2394         case EAMRUnrecognized:
   2395         default:
   2396             return PVMFErrNotSupported;
   2397     }
   2398     tmpTrackInfo.setTrackBitRate(amrinfo.iBitrate);
   2399     tmpTrackInfo.setTrackDurationTimeScale((uint64)amrinfo.iTimescale);
   2400     tmpTrackInfo.setTrackDurationValue(amrinfo.iDuration);
   2401     OSCL_FastString mime_type = _STRLIT_CHAR(PVMF_MIME_AMR_IETF);
   2402     if (amrinfo.iAmrFormat == EAMRIF2)
   2403     {
   2404         mime_type = _STRLIT_CHAR(PVMF_MIME_AMR_IF2);
   2405     }
   2406     else if (EAMRIETF_SingleWB == amrinfo.iAmrFormat)
   2407         mime_type = _STRLIT_CHAR(PVMF_MIME_AMRWB_IETF);
   2408 
   2409 
   2410     tmpTrackInfo.setTrackMimeType(mime_type);
   2411     aInfo.addTrackInfo(tmpTrackInfo);
   2412     return PVMFSuccess;
   2413 }
   2414 
   2415 
   2416 PVMFStatus PVMFAMRFFParserNode::SelectTracks(PVMFMediaPresentationInfo& aInfo)
   2417 {
   2418     OSCL_UNUSED_ARG(aInfo);
   2419     return PVMFSuccess;
   2420 }
   2421 
   2422 uint32 PVMFAMRFFParserNode::GetNumMetadataKeys(char* aQueryKeyString)
   2423 {
   2424     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFAMRFFParserNode::GetNumMetadataKeys() called"));
   2425 
   2426     uint32 num_entries = 0;
   2427 
   2428     if (aQueryKeyString == NULL)
   2429     {
   2430         // No query key so just return all the available keys
   2431         num_entries = iAvailableMetadataKeys.size();
   2432     }
   2433     else
   2434     {
   2435         // Determine the number of metadata keys based on the query key string provided
   2436         for (uint32 i = 0; i < iAvailableMetadataKeys.size(); i++)
   2437         {
   2438             // Check if the key matches the query key
   2439             if (pv_mime_strcmp(iAvailableMetadataKeys[i].get_cstr(), aQueryKeyString) >= 0)
   2440             {
   2441                 num_entries++;
   2442             }
   2443         }
   2444     }
   2445     for (uint32 i = 0; i < iCPMMetadataKeys.size(); i++)
   2446     {
   2447         if (pv_mime_strcmp(iCPMMetadataKeys[i].get_cstr(),
   2448                            aQueryKeyString) >= 0)
   2449         {
   2450             num_entries++;
   2451         }
   2452     }
   2453 
   2454     if ((iCPMMetaDataExtensionInterface != NULL))
   2455     {
   2456         num_entries +=
   2457             iCPMMetaDataExtensionInterface->GetNumMetadataKeys(aQueryKeyString);
   2458     }
   2459     return num_entries;
   2460 }
   2461 
   2462 uint32 PVMFAMRFFParserNode::GetNumMetadataValues(PVMFMetadataList& aKeyList)
   2463 {
   2464     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFAMRFFParserNode::GetNumMetadataValues() called"));
   2465 
   2466     uint32 numkeys = aKeyList.size();
   2467     if (!iAMRParser || numkeys == 0)
   2468     {
   2469         return 0;
   2470     }
   2471 
   2472     // Count the number of metadata value entries based on the key list provided
   2473     uint32 numvalentries = 0;
   2474     for (uint32 lcv = 0; lcv < numkeys; lcv++)
   2475     {
   2476         if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVAMRMETADATA_DURATION_KEY) == 0 &&
   2477                 iAMRFileInfo.iDuration > 0)
   2478         {
   2479             // Movie Duration
   2480             ++numvalentries;
   2481         }
   2482         else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVAMRMETADATA_NUMTRACKS_KEY) == 0)
   2483         {
   2484             // Number of tracks
   2485             ++numvalentries;
   2486         }
   2487         else if ((oscl_strcmp(aKeyList[lcv].get_cstr(), PVAMRMETADATA_TRACKINFO_BITRATE_KEY) == 0) &&
   2488                  iAMRFileInfo.iBitrate > 0)
   2489         {
   2490             // Bitrate
   2491             ++numvalentries;
   2492         }
   2493         else if ((oscl_strcmp(aKeyList[lcv].get_cstr(), PVAMRMETADATA_TRACKINFO_AUDIO_FORMAT_KEY) == 0) &&
   2494                  iAMRFileInfo.iAmrFormat != EAMRUnrecognized)
   2495         {
   2496             // Format
   2497             ++numvalentries;
   2498         }
   2499         else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVAMRMETADATA_RANDOM_ACCESS_DENIED_KEY) == 0)
   2500         {
   2501             /*
   2502              * Random Access
   2503              * Increment the counter for the number of values found so far
   2504              */
   2505             ++numvalentries;
   2506         }
   2507         else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVAMRMETADATA_CLIP_TYPE_KEY) == 0)
   2508         {
   2509             /*
   2510              * clip-type
   2511              * Increment the counter for the number of values found so far
   2512              */
   2513             ++numvalentries;
   2514         }
   2515 
   2516 
   2517     }
   2518 
   2519     if ((iCPMMetaDataExtensionInterface != NULL))
   2520     {
   2521         numvalentries +=
   2522             iCPMMetaDataExtensionInterface->GetNumMetadataValues(aKeyList);
   2523     }
   2524     return numvalentries;
   2525 }
   2526 
   2527 PVMFCommandId PVMFAMRFFParserNode::GetNodeMetadataKeys(PVMFSessionId aSessionId, PVMFMetadataList& aKeyList
   2528         , uint32 aStartingKeyIndex, int32 aMaxKeyEntries, char* aQueryKeyString, const OsclAny* aContext)
   2529 {
   2530     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFAMRFFParserNode::GetNodeMetadataKeys() called"));
   2531 
   2532     PVMFAMRFFNodeCommand cmd;
   2533     cmd.PVMFAMRFFNodeCommand::Construct(aSessionId, PVMF_AMR_PARSER_NODE_GETNODEMETADATAKEYS, aKeyList, aStartingKeyIndex, aMaxKeyEntries, aQueryKeyString, aContext);
   2534     return QueueCommandL(cmd);
   2535 }
   2536 
   2537 PVMFCommandId PVMFAMRFFParserNode::GetNodeMetadataValues(PVMFSessionId aSessionId, PVMFMetadataList& aKeyList, Oscl_Vector<PvmiKvp, OsclMemAllocator>& aValueList
   2538         , uint32 aStartingValueIndex, int32 aMaxValueEntries, const OsclAny* aContext)
   2539 {
   2540     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFAMRFFParserNode::GetNodeMetadataValue() called"));
   2541 
   2542     PVMFAMRFFNodeCommand cmd;
   2543     cmd.PVMFAMRFFNodeCommand::Construct(aSessionId, PVMF_AMR_PARSER_NODE_GETNODEMETADATAVALUES, aKeyList, aValueList, aStartingValueIndex, aMaxValueEntries, aContext);
   2544     return QueueCommandL(cmd);
   2545 }
   2546 
   2547 PVMFStatus PVMFAMRFFParserNode::ReleaseNodeMetadataKeys(PVMFMetadataList& , uint32 , uint32)
   2548 {
   2549     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFAMRFFParserNode::ReleaseNodeMetadataKeys() called"));
   2550     return PVMFSuccess;
   2551 }
   2552 
   2553 PVMFStatus PVMFAMRFFParserNode::ReleaseNodeMetadataValues(Oscl_Vector<PvmiKvp, OsclMemAllocator>& aValueList, uint32 start, uint32 end)
   2554 {
   2555     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFAMRFFParserNode::ReleaseNodeMetadataValues() called"));
   2556 
   2557     if (start > end || aValueList.size() == 0)
   2558     {
   2559         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFAMRFFParserNode::ReleaseNodeMetadataValues() Invalid start/end index"));
   2560         return PVMFErrArgument;
   2561     }
   2562 
   2563     end = OSCL_MIN(aValueList.size(), iAMRParserNodeMetadataValueCount);
   2564 
   2565     for (uint32 i = start; i < end; i++)
   2566     {
   2567         if (aValueList[i].key != NULL)
   2568         {
   2569             switch (GetValTypeFromKeyString(aValueList[i].key))
   2570             {
   2571                 case PVMI_KVPVALTYPE_CHARPTR:
   2572                     if (aValueList[i].value.pChar_value != NULL)
   2573                     {
   2574                         OSCL_ARRAY_DELETE(aValueList[i].value.pChar_value);
   2575                         aValueList[i].value.pChar_value = NULL;
   2576                     }
   2577                     break;
   2578 
   2579                 case PVMI_KVPVALTYPE_UINT32:
   2580                 case PVMI_KVPVALTYPE_UINT8:
   2581                     // No memory to free for these valtypes
   2582                     break;
   2583 
   2584                 default:
   2585                     // Should not get a value that wasn't created from here
   2586                     break;
   2587             }
   2588 
   2589             OSCL_ARRAY_DELETE(aValueList[i].key);
   2590             aValueList[i].key = NULL;
   2591         }
   2592     }
   2593 
   2594     return PVMFSuccess;
   2595 }
   2596 
   2597 PVMFCommandId PVMFAMRFFParserNode::SetDataSourcePosition(PVMFSessionId aSessionId
   2598         , PVMFTimestamp aTargetNPT
   2599         , PVMFTimestamp& aActualNPT
   2600         , PVMFTimestamp& aActualMediaDataTS
   2601         , bool aSeekToSyncPoint
   2602         , uint32 aStreamID
   2603         , OsclAny* aContext)
   2604 {
   2605     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2606                     (0, "PVMFAMRFFParserNode::SetDataSourcePosition: aTargetNPT=%d, aSeekToSyncPoint=%d, aContext=0x%x",
   2607                      aTargetNPT, aSeekToSyncPoint, aContext));
   2608 
   2609     PVMFAMRFFNodeCommand cmd;
   2610     cmd.PVMFAMRFFNodeCommand::Construct(aSessionId, PVMF_AMR_PARSER_NODE_SET_DATASOURCE_POSITION, aTargetNPT, aActualNPT,
   2611                                         aActualMediaDataTS, aSeekToSyncPoint, aStreamID, aContext);
   2612     return QueueCommandL(cmd);
   2613 }
   2614 
   2615 PVMFCommandId PVMFAMRFFParserNode::QueryDataSourcePosition(PVMFSessionId aSessionId
   2616         , PVMFTimestamp aTargetNPT
   2617         , PVMFTimestamp& aActualNPT
   2618         , bool aSeekToSyncPoint
   2619         , OsclAny* aContext)
   2620 {
   2621     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2622                     (0, "PVMFAMRFFParserNode::QueryDataSourcePosition: aTargetNPT=%d, aSeekToSyncPoint=%d, aContext=0x%x",
   2623                      aTargetNPT, aSeekToSyncPoint, aContext));
   2624 
   2625     PVMFAMRFFNodeCommand cmd;
   2626     cmd.PVMFAMRFFNodeCommand::Construct(aSessionId, PVMF_AMR_PARSER_NODE_QUERY_DATASOURCE_POSITION, aTargetNPT, aActualNPT,
   2627                                         aSeekToSyncPoint, aContext);
   2628     return QueueCommandL(cmd);
   2629 }
   2630 
   2631 PVMFCommandId PVMFAMRFFParserNode::QueryDataSourcePosition(PVMFSessionId aSessionId
   2632         , PVMFTimestamp aTargetNPT
   2633         , PVMFTimestamp& aSeekPointBeforeTargetNPT
   2634         , PVMFTimestamp& aSeekPointAfterTargetNPT
   2635         , OsclAny* aContext
   2636         , bool aSeekToSyncPoint)
   2637 {
   2638     OSCL_UNUSED_ARG(aSeekPointAfterTargetNPT);
   2639     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2640                     (0, "PVMFAMRFFParserNode::QueryDataSourcePosition: aTargetNPT=%d, aSeekToSyncPoint=%d, aContext=0x%x",
   2641                      aTargetNPT, aSeekToSyncPoint, aContext));
   2642 
   2643     PVMFAMRFFNodeCommand cmd;
   2644     // Construct not changed,aSeekPointBeforeTargetNPT has replace aActualtNPT
   2645     cmd.PVMFAMRFFNodeCommand::Construct(aSessionId, PVMF_AMR_PARSER_NODE_QUERY_DATASOURCE_POSITION, aTargetNPT, aSeekPointBeforeTargetNPT,
   2646                                         aSeekToSyncPoint, aContext);
   2647     return QueueCommandL(cmd);
   2648 }
   2649 
   2650 PVMFCommandId PVMFAMRFFParserNode::SetDataSourceRate(PVMFSessionId aSessionId
   2651         , int32 aRate
   2652         , PVMFTimebase* aTimebase
   2653         , OsclAny* aContext)
   2654 {
   2655     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFAMRFFParserNode::SetDataSourceRate() called"));
   2656 
   2657     PVMFAMRFFNodeCommand cmd;
   2658     cmd.PVMFAMRFFNodeCommand::Construct(aSessionId, PVMF_AMR_PARSER_NODE_SET_DATASOURCE_RATE, aRate, aTimebase, aContext);
   2659     return QueueCommandL(cmd);
   2660 }
   2661 
   2662 
   2663 PVMFStatus PVMFAMRFFParserNode::CheckForAMRHeaderAvailability()
   2664 {
   2665     if (iDataStreamInterface != NULL)
   2666     {
   2667         /*
   2668          * First check if we have minimum number of bytes to recognize
   2669          * the file and determine the header size.
   2670          */
   2671         uint32 currCapacity = 0;
   2672         iDataStreamInterface->QueryReadCapacity(iDataStreamSessionID,
   2673                                                 currCapacity);
   2674 
   2675         if (currCapacity <  AMR_MIN_DATA_SIZE_FOR_RECOGNITION)
   2676         {
   2677             iRequestReadCapacityNotificationID =
   2678                 iDataStreamInterface->RequestReadCapacityNotification(iDataStreamSessionID,
   2679                         *this,
   2680                         AMR_MIN_DATA_SIZE_FOR_RECOGNITION);
   2681             return PVMFPending;
   2682         }
   2683 
   2684 
   2685         uint32 headerSize32 =
   2686             Oscl_Int64_Utils::get_uint64_lower32(iAMRHeaderSize);
   2687 
   2688         if (currCapacity < headerSize32)
   2689         {
   2690             iRequestReadCapacityNotificationID =
   2691                 iDataStreamInterface->RequestReadCapacityNotification(iDataStreamSessionID,
   2692                         *this,
   2693                         headerSize32);
   2694             return PVMFPending;
   2695         }
   2696     }
   2697     return PVMFSuccess;
   2698 }
   2699 
   2700 
   2701 bool PVMFAMRFFParserNode::GetTrackInfo(PVMFPortInterface* aPort,
   2702                                        PVAMRFFNodeTrackPortInfo*& aTrackInfoPtr)
   2703 {
   2704     Oscl_Vector<PVAMRFFNodeTrackPortInfo, PVMFAMRParserNodeAllocator>::iterator it;
   2705     for (it = iSelectedTrackList.begin(); it != iSelectedTrackList.end(); it++)
   2706     {
   2707         if (it->iPort == aPort)
   2708         {
   2709             aTrackInfoPtr = it;
   2710             return true;
   2711         }
   2712     }
   2713     return false;
   2714 }
   2715 
   2716 bool PVMFAMRFFParserNode::GetTrackInfo(int32 aTrackID,
   2717                                        PVAMRFFNodeTrackPortInfo*& aTrackInfoPtr)
   2718 {
   2719     Oscl_Vector<PVAMRFFNodeTrackPortInfo, PVMFAMRParserNodeAllocator>::iterator it;
   2720     for (it = iSelectedTrackList.begin(); it != iSelectedTrackList.end(); it++)
   2721     {
   2722         if (it->iTrackId == aTrackID)
   2723         {
   2724             aTrackInfoPtr = it;
   2725             return true;
   2726         }
   2727     }
   2728     return false;
   2729 }
   2730 
   2731 
   2732 bool PVMFAMRFFParserNode::ProcessPortActivity(PVAMRFFNodeTrackPortInfo* aTrackInfoPtr)
   2733 {
   2734     /*
   2735      * called by the AO to process a port activity message
   2736      */
   2737     PVMF_AMRPARSERNODE_LOGSTACKTRACE((0, "PVMFAMRParserNode::ProcessPortActivity() Called"));
   2738 
   2739     PVMFStatus status;
   2740     if (aTrackInfoPtr->oQueueOutgoingMessages)
   2741     {
   2742         status = QueueMediaSample(aTrackInfoPtr);
   2743 
   2744         if ((status != PVMFErrBusy) &&
   2745                 (status != PVMFSuccess) &&
   2746                 (status != PVMFErrInvalidState))
   2747         {
   2748             PVMF_AMRPARSERNODE_LOGERROR((0, "PVMFAMRParserNode::ProcessPortActivity() QueueMediaSample Failed - Err=%d", status));
   2749             return false;
   2750         }
   2751         if (iAutoPaused == true)
   2752         {
   2753             aTrackInfoPtr->oQueueOutgoingMessages = false;
   2754             PVMF_AMRPARSERNODE_LOGDATATRAFFIC((0, "PVMFAMRParserNode::QueueMediaSample() - Auto Paused"));
   2755             return PVMFErrBusy;
   2756         }
   2757         if (aTrackInfoPtr->iPort->IsOutgoingQueueBusy())
   2758         {
   2759             aTrackInfoPtr->oQueueOutgoingMessages = false;
   2760             PVMF_AMRPARSERNODE_LOGDATATRAFFIC((0, "PVMFAMRParserNode::QueueMediaSample() Port Outgoing Queue Busy"));
   2761             return PVMFErrBusy;
   2762         }
   2763 
   2764     }
   2765     if (aTrackInfoPtr->oProcessOutgoingMessages)
   2766     {
   2767         if (aTrackInfoPtr->iPort->OutgoingMsgQueueSize() > 0)
   2768         {
   2769             status = ProcessOutgoingMsg(aTrackInfoPtr);
   2770             /*
   2771              * Report any unexpected failure in port processing...
   2772              * (the InvalidState error happens when port input is suspended,
   2773              * so don't report it.)
   2774              */
   2775             if ((status != PVMFErrBusy) &&
   2776                     (status != PVMFSuccess) &&
   2777                     (status != PVMFErrInvalidState))
   2778             {
   2779                 PVMF_AMRPARSERNODE_LOGERROR((0, "PVMFASFParserNode::ProcessPortActivity() ProcessOutgoingMsg Failed - Err=%d", status));
   2780                 ReportErrorEvent(PVMFErrPortProcessing);
   2781             }
   2782         }
   2783         else
   2784         {
   2785             /* Nothing to send - wait for more data */
   2786             aTrackInfoPtr->oProcessOutgoingMessages = false;
   2787         }
   2788     }
   2789     return true;
   2790 }
   2791 
   2792 bool PVMFAMRFFParserNode::CheckForPortRescheduling()
   2793 {
   2794     PVAMRFFNodeTrackPortInfo* trackInfoPtr = NULL;
   2795     if (!GetTrackInfo(iOutPort, trackInfoPtr))
   2796     {
   2797         PVMF_AMRPARSERNODE_LOGERROR((0, "PVMFAMRParserNode::CheckForPortRescheduling: Error - GetPortContainer failed"));
   2798         return false;
   2799     }
   2800 
   2801     if ((trackInfoPtr->oProcessOutgoingMessages) ||
   2802             (trackInfoPtr->oQueueOutgoingMessages))
   2803     {
   2804         /*
   2805          * Found a port that has outstanding activity and
   2806          * is not busy.
   2807          */
   2808         return true;
   2809     }
   2810     /*
   2811      * No port processing needed - either all port activity queues are empty
   2812      * or the ports are backed up due to flow control.
   2813      */
   2814     return false;
   2815 }
   2816 
   2817 PVMFStatus PVMFAMRFFParserNode::InitMetaData()
   2818 {
   2819     if (iAMRFileInfo.iFileSize > 0)
   2820     {
   2821         // Populate the metadata key vector based on info available
   2822         PushToAvailableMetadataKeysList(PVAMRMETADATA_NUMTRACKS_KEY);
   2823         if (iAMRFileInfo.iDuration > 0)
   2824         {
   2825             PushToAvailableMetadataKeysList(PVAMRMETADATA_DURATION_KEY);
   2826 
   2827         }
   2828         if (iAMRFileInfo.iBitrate > 0)
   2829         {
   2830             PushToAvailableMetadataKeysList(PVAMRMETADATA_TRACKINFO_BITRATE_KEY);
   2831 
   2832         }
   2833         if (iAMRFileInfo.iAmrFormat != EAMRUnrecognized)
   2834         {
   2835             PushToAvailableMetadataKeysList(PVAMRMETADATA_TRACKINFO_AUDIO_FORMAT_KEY);
   2836 
   2837         }
   2838         PushToAvailableMetadataKeysList(PVAMRMETADATA_RANDOM_ACCESS_DENIED_KEY);
   2839         PushToAvailableMetadataKeysList(PVAMRMETADATA_CLIP_TYPE_KEY);
   2840 
   2841         //set clip duration on download progress interface
   2842         //applicable to PDL sessions
   2843         {
   2844             if ((iDownloadProgressInterface != NULL) && (iAMRFileInfo.iDuration != 0))
   2845             {
   2846                 iDownloadProgressInterface->setClipDuration(OSCL_CONST_CAST(uint32, iAMRFileInfo.iDuration));
   2847             }
   2848         }
   2849 
   2850         return PVMFSuccess;
   2851     }
   2852     else
   2853         return PVMFFailure;
   2854 
   2855 }
   2856 
   2857 void PVMFAMRFFParserNode::PushToAvailableMetadataKeysList(const char* aKeystr, char* aOptionalParam)
   2858 {
   2859     if (aKeystr == NULL)
   2860     {
   2861         return;
   2862     }
   2863     int32 leavecode = 0;
   2864     if (aOptionalParam)
   2865     {
   2866         OSCL_TRY(leavecode, iAvailableMetadataKeys.push_front(aKeystr);
   2867                  iAvailableMetadataKeys[0] += aOptionalParam;);
   2868     }
   2869     else
   2870     {
   2871         OSCL_TRY(leavecode, iAvailableMetadataKeys.push_front(aKeystr));
   2872     }
   2873 }
   2874 
   2875 void PVMFAMRFFParserNode::InitCPM()
   2876 {
   2877     iCPMInitCmdId = iCPM->Init();
   2878 }
   2879 
   2880 void PVMFAMRFFParserNode::OpenCPMSession()
   2881 {
   2882     iCPMOpenSessionCmdId = iCPM->OpenSession(iCPMSessionID);
   2883 }
   2884 
   2885 void PVMFAMRFFParserNode::CPMRegisterContent()
   2886 {
   2887     iCPMRegisterContentCmdId = iCPM->RegisterContent(iCPMSessionID,
   2888                                iSourceURL,
   2889                                iSourceFormat,
   2890                                (OsclAny*) & iCPMSourceData);
   2891 }
   2892 
   2893 void PVMFAMRFFParserNode::GetCPMLicenseInterface()
   2894 {
   2895     iCPMLicenseInterfacePVI = NULL;
   2896     iCPMGetLicenseInterfaceCmdId =
   2897         iCPM->QueryInterface(iCPMSessionID,
   2898                              PVMFCPMPluginLicenseInterfaceUuid,
   2899                              iCPMLicenseInterfacePVI);
   2900 }
   2901 
   2902 bool PVMFAMRFFParserNode::GetCPMContentAccessFactory()
   2903 {
   2904     PVMFStatus status = iCPM->GetContentAccessFactory(iCPMSessionID,
   2905                         iCPMContentAccessFactory);
   2906     if (status != PVMFSuccess)
   2907     {
   2908         return false;
   2909     }
   2910     return true;
   2911 }
   2912 
   2913 bool PVMFAMRFFParserNode::GetCPMMetaDataExtensionInterface()
   2914 {
   2915     PVInterface* temp = NULL;
   2916     bool retVal =
   2917         iCPM->queryInterface(KPVMFMetadataExtensionUuid, temp);
   2918     iCPMMetaDataExtensionInterface = OSCL_STATIC_CAST(PVMFMetadataExtensionInterface*, temp);
   2919     return retVal;
   2920 }
   2921 
   2922 void PVMFAMRFFParserNode::RequestUsage()
   2923 {
   2924     PopulateDRMInfo();
   2925 
   2926     if (iDataStreamReadCapacityObserver != NULL)
   2927     {
   2928         iCPMContentAccessFactory->SetStreamReadCapacityObserver(iDataStreamReadCapacityObserver);
   2929     }
   2930 
   2931     iCPMRequestUsageId = iCPM->ApproveUsage(iCPMSessionID,
   2932                                             iRequestedUsage,
   2933                                             iApprovedUsage,
   2934                                             iAuthorizationDataKvp,
   2935                                             iUsageID,
   2936                                             iCPMContentAccessFactory);
   2937 
   2938     oSourceIsCurrent = true;
   2939 }
   2940 
   2941 void PVMFAMRFFParserNode::PopulateDRMInfo()
   2942 {
   2943     if (iRequestedUsage.key)
   2944     {
   2945         OSCL_ARRAY_DELETE(iRequestedUsage.key);
   2946         iRequestedUsage.key = NULL;
   2947     }
   2948 
   2949     if (iApprovedUsage.key)
   2950     {
   2951         OSCL_ARRAY_DELETE(iApprovedUsage.key);
   2952         iApprovedUsage.key = NULL;
   2953     }
   2954 
   2955     if (iAuthorizationDataKvp.key)
   2956     {
   2957         OSCL_ARRAY_DELETE(iAuthorizationDataKvp.key);
   2958         iAuthorizationDataKvp.key = NULL;
   2959     }
   2960 
   2961     if ((iCPMContentType == PVMF_CPM_FORMAT_OMA1) ||
   2962             (iCPMContentType == PVMF_CPM_FORMAT_AUTHORIZE_BEFORE_ACCESS))
   2963     {
   2964         int32 UseKeyLen = oscl_strlen(_STRLIT_CHAR(PVMF_CPM_REQUEST_USE_KEY_STRING));
   2965         int32 AuthKeyLen = oscl_strlen(_STRLIT_CHAR(PVMF_CPM_AUTHORIZATION_DATA_KEY_STRING));
   2966         int32 leavecode = 0;
   2967 
   2968         OSCL_TRY(leavecode,
   2969                  iRequestedUsage.key = OSCL_ARRAY_NEW(char, UseKeyLen + 1);
   2970                  iApprovedUsage.key = OSCL_ARRAY_NEW(char, UseKeyLen + 1);
   2971                  iAuthorizationDataKvp.key = OSCL_ARRAY_NEW(char, AuthKeyLen + 1);
   2972                 );
   2973         if (leavecode || !iRequestedUsage.key || !iApprovedUsage.key || !iAuthorizationDataKvp.key)
   2974         {
   2975             if (iRequestedUsage.key)
   2976             {
   2977                 OSCL_ARRAY_DELETE(iRequestedUsage.key);
   2978                 iRequestedUsage.key = NULL;
   2979             }
   2980             if (iApprovedUsage.key)
   2981             {
   2982                 OSCL_ARRAY_DELETE(iApprovedUsage.key);
   2983                 iApprovedUsage.key = NULL;
   2984             }
   2985             if (iAuthorizationDataKvp.key)
   2986             {
   2987                 OSCL_ARRAY_DELETE(iAuthorizationDataKvp.key);
   2988                 iAuthorizationDataKvp.key = NULL;
   2989             }
   2990 
   2991             return;
   2992         }
   2993 
   2994         oscl_strncpy(iRequestedUsage.key,
   2995                      _STRLIT_CHAR(PVMF_CPM_REQUEST_USE_KEY_STRING),
   2996                      UseKeyLen);
   2997         iRequestedUsage.key[UseKeyLen] = 0;
   2998         iRequestedUsage.length = 0;
   2999         iRequestedUsage.capacity = 0;
   3000         if (iPreviewMode)
   3001         {
   3002             iRequestedUsage.value.uint32_value =
   3003                 (BITMASK_PVMF_CPM_DRM_INTENT_PREVIEW |
   3004                  BITMASK_PVMF_CPM_DRM_INTENT_PAUSE |
   3005                  BITMASK_PVMF_CPM_DRM_INTENT_SEEK_FORWARD |
   3006                  BITMASK_PVMF_CPM_DRM_INTENT_SEEK_BACK);
   3007         }
   3008         else
   3009         {
   3010             iRequestedUsage.value.uint32_value =
   3011                 (BITMASK_PVMF_CPM_DRM_INTENT_PLAY |
   3012                  BITMASK_PVMF_CPM_DRM_INTENT_PAUSE |
   3013                  BITMASK_PVMF_CPM_DRM_INTENT_SEEK_FORWARD |
   3014                  BITMASK_PVMF_CPM_DRM_INTENT_SEEK_BACK);
   3015         }
   3016         oscl_strncpy(iApprovedUsage.key,
   3017                      _STRLIT_CHAR(PVMF_CPM_REQUEST_USE_KEY_STRING),
   3018                      UseKeyLen);
   3019         iApprovedUsage.key[UseKeyLen] = 0;
   3020         iApprovedUsage.length = 0;
   3021         iApprovedUsage.capacity = 0;
   3022         iApprovedUsage.value.uint32_value = 0;
   3023 
   3024         oscl_strncpy(iAuthorizationDataKvp.key,
   3025                      _STRLIT_CHAR(PVMF_CPM_AUTHORIZATION_DATA_KEY_STRING),
   3026                      AuthKeyLen);
   3027         iAuthorizationDataKvp.key[AuthKeyLen] = 0;
   3028         iAuthorizationDataKvp.length = 0;
   3029         iAuthorizationDataKvp.capacity = 0;
   3030         iAuthorizationDataKvp.value.pUint8_value = NULL;
   3031     }
   3032     else
   3033     {
   3034         //Error
   3035         OSCL_ASSERT(false);
   3036     }
   3037 }
   3038 
   3039 void PVMFAMRFFParserNode::SendUsageComplete()
   3040 {
   3041     iCPMUsageCompleteCmdId = iCPM->UsageComplete(iCPMSessionID, iUsageID);
   3042 }
   3043 
   3044 void PVMFAMRFFParserNode::CloseCPMSession()
   3045 {
   3046     iCPMCloseSessionCmdId = iCPM->CloseSession(iCPMSessionID);
   3047 }
   3048 
   3049 void PVMFAMRFFParserNode::ResetCPM()
   3050 {
   3051     iCPMResetCmdId = iCPM->Reset();
   3052 }
   3053 
   3054 void PVMFAMRFFParserNode::GetCPMMetaDataKeys()
   3055 {
   3056     if (iCPMMetaDataExtensionInterface != NULL)
   3057     {
   3058         iCPMMetadataKeys.clear();
   3059         iCPMGetMetaDataKeysCmdId =
   3060             iCPMMetaDataExtensionInterface->GetNodeMetadataKeys(iCPMSessionID,
   3061                     iCPMMetadataKeys,
   3062                     0,
   3063                     PVMF_AMR_PARSER_NODE_MAX_CPM_METADATA_KEYS);
   3064     }
   3065 }
   3066 
   3067 void PVMFAMRFFParserNode::CPMCommandCompleted(const PVMFCmdResp& aResponse)
   3068 {
   3069     PVMFCommandId id = aResponse.GetCmdId();
   3070     PVMFStatus status = aResponse.GetCmdStatus();
   3071     if (id == iCPMCancelGetLicenseCmdId)
   3072     {
   3073         /*
   3074          * if this command is CancelGetLicense, we will return success or fail here.
   3075          */
   3076         PVMF_AMRPARSERNODE_LOGDATATRAFFIC((0, "PVMFAMRFFParserNode::CPMCommandCompleted -  CPM CancelGetLicense complete"));
   3077         OSCL_ASSERT(!iCancelCommand.empty());
   3078         CommandComplete(iCancelCommand,
   3079                         iCancelCommand.front(),
   3080                         status);
   3081         return;
   3082     }
   3083     //if CPM comes back as PVMFErrNotSupported then by pass rest of the CPM
   3084     //sequence. Fake success here so that node doesnt treat this as an error
   3085     else if (id == iCPMRegisterContentCmdId && status == PVMFErrNotSupported)
   3086     {
   3087         /* Unsupported format - Treat it like unprotected content */
   3088         PVMF_AMRPARSERNODE_LOGINFO((0, "PVMFAMRParserNode::CPMCommandCompleted - Unknown CPM Format - Ignoring CPM"));
   3089         if (CheckForAMRHeaderAvailability() == PVMFSuccess)
   3090         {
   3091             if (ParseAMRFile())
   3092             {
   3093                 /* End of Node Init sequence. */
   3094                 OSCL_ASSERT(!iCurrentCommand.empty());
   3095                 OSCL_ASSERT(iCurrentCommand.front().iCmd == PVMF_AMR_PARSER_NODE_INIT);
   3096                 CompleteInit();
   3097             }
   3098         }
   3099         return;
   3100     }
   3101 
   3102     if (status != PVMFSuccess)
   3103     {
   3104         /*
   3105          * If any command fails, the sequence fails.
   3106          */
   3107         CommandComplete(iCurrentCommand,
   3108                         iCurrentCommand.front(),
   3109                         aResponse.GetCmdStatus(),
   3110                         NULL,
   3111                         NULL,
   3112                         NULL,
   3113                         aResponse.GetEventExtensionInterface());
   3114     }
   3115     else
   3116     {
   3117         /*
   3118          * process the response, and issue the next command in
   3119          * the sequence.
   3120          */
   3121 
   3122         if (id == iCPMInitCmdId)
   3123         {
   3124             OpenCPMSession();
   3125         }
   3126         else if (id == iCPMOpenSessionCmdId)
   3127         {
   3128             CPMRegisterContent();
   3129         }
   3130         else if (id == iCPMRegisterContentCmdId)
   3131         {
   3132             GetCPMLicenseInterface();
   3133         }
   3134         else if (id == iCPMGetLicenseInterfaceCmdId)
   3135         {
   3136             iCPMLicenseInterface = OSCL_STATIC_CAST(PVMFCPMPluginLicenseInterface*, iCPMLicenseInterfacePVI);
   3137             iCPMLicenseInterfacePVI = NULL;
   3138             iCPMContentType = iCPM->GetCPMContentType(iCPMSessionID);
   3139 
   3140             if ((iCPMContentType == PVMF_CPM_FORMAT_AUTHORIZE_BEFORE_ACCESS)
   3141                     || (iCPMContentType == PVMF_CPM_FORMAT_OMA1))
   3142             {
   3143                 GetCPMContentAccessFactory();
   3144                 GetCPMMetaDataExtensionInterface();
   3145                 if (CheckForAMRHeaderAvailability() == PVMFSuccess)
   3146                 {
   3147                     if (ParseAMRFile())
   3148                     {
   3149                         RequestUsage();
   3150                     }
   3151                 }
   3152             }
   3153             else
   3154             {
   3155                 /* Unsupported format - Treat it like unprotected content */
   3156                 PVMF_AMRPARSERNODE_LOGINFO((0, "PVMFAMRParserNode::CPMCommandCompleted - Unknown CPM Format - Ignoring CPM"));
   3157                 if (CheckForAMRHeaderAvailability() == PVMFSuccess)
   3158                 {
   3159                     if (ParseAMRFile())
   3160                     {
   3161                         OSCL_ASSERT(!iCurrentCommand.empty());
   3162                         OSCL_ASSERT(iCurrentCommand.front().iCmd == PVMF_AMR_PARSER_NODE_INIT);
   3163                         CompleteInit();
   3164                         /*
   3165                          * if there was any pending cancel, it was waiting on
   3166                          * this command to complete-- so the cancel is now done.
   3167                          */
   3168                         if (!iCancelCommand.empty())
   3169                         {
   3170                             CommandComplete(iCancelCommand,
   3171                                             iCancelCommand.front(),
   3172                                             PVMFSuccess);
   3173                         }
   3174                     }
   3175                 }
   3176             }
   3177         }
   3178         else if (id == iCPMRequestUsageId)
   3179         {
   3180             oSourceIsCurrent = false;
   3181             if (aResponse.GetCmdStatus() == PVMFSuccess)
   3182             {
   3183                 if (CheckForAMRHeaderAvailability() == PVMFSuccess)
   3184                 {
   3185                     if (ParseAMRFile())
   3186                     {
   3187                         OSCL_ASSERT(!iCurrentCommand.empty());
   3188                         OSCL_ASSERT(iCurrentCommand.front().iCmd == PVMF_AMR_PARSER_NODE_INIT);
   3189                         CompleteInit();
   3190                         /*
   3191                          * if there was any pending cancel, it was waiting on
   3192                          * this command to complete-- so the cancel is now done.
   3193                          */
   3194                         if (!iCancelCommand.empty())
   3195                         {
   3196                             CommandComplete(iCancelCommand,
   3197                                             iCancelCommand.front(),
   3198                                             PVMFSuccess);
   3199                         }
   3200                     }
   3201                 }
   3202             }
   3203             else
   3204             {
   3205                 CompleteInit();
   3206             }
   3207         }
   3208         else if (id == iCPMGetMetaDataKeysCmdId)
   3209         {
   3210             /* End of GetNodeMetaDataKeys */
   3211             PVMFStatus status =
   3212                 CompleteGetMetadataKeys(iCurrentCommand.front());
   3213             CommandComplete(iCurrentCommand,
   3214                             iCurrentCommand.front(),
   3215                             status,
   3216                             NULL,
   3217                             NULL,
   3218                             NULL,
   3219                             NULL);
   3220         }
   3221         else if (id == iCPMUsageCompleteCmdId)
   3222         {
   3223             CloseCPMSession();
   3224         }
   3225         else if (id == iCPMCloseSessionCmdId)
   3226         {
   3227             ResetCPM();
   3228         }
   3229         else if (id == iCPMResetCmdId)
   3230         {
   3231             /* End of Node Reset sequence */
   3232             OSCL_ASSERT(!iCurrentCommand.empty());
   3233             OSCL_ASSERT(iCurrentCommand.front().iCmd == PVMF_AMR_PARSER_NODE_RESET);
   3234             CompleteReset();
   3235         }
   3236         else if (id == iCPMGetMetaDataValuesCmdId)
   3237         {
   3238             /* End of GetNodeMetaDataValues */
   3239             OSCL_ASSERT(!iCurrentCommand.empty());
   3240             OSCL_ASSERT(iCurrentCommand.front().iCmd == PVMF_AMR_PARSER_NODE_GETNODEMETADATAVALUES);
   3241             CompleteGetMetaDataValues();
   3242         }
   3243         else if (id == iCPMGetLicenseCmdId)
   3244         {
   3245             CompleteGetLicense();
   3246         }
   3247         else
   3248         {
   3249             /* Unknown cmd - error */
   3250             CommandComplete(iCurrentCommand,
   3251                             iCurrentCommand.front(),
   3252                             PVMFFailure);
   3253         }
   3254     }
   3255 
   3256     /*
   3257      * if there was any pending cancel, it was waiting on
   3258      * this command to complete-- so the cancel is now done.
   3259      */
   3260     if (!iCancelCommand.empty())
   3261     {
   3262         if (iCancelCommand.front().iCmd != PVMF_AMR_PARSER_NODE_CMD_CANCEL_GET_LICENSE)
   3263         {
   3264             CommandComplete(iCancelCommand,
   3265                             iCancelCommand.front(),
   3266                             PVMFSuccess);
   3267         }
   3268     }
   3269 }
   3270 
   3271 void PVMFAMRFFParserNode::PassDatastreamFactory(PVMFDataStreamFactory& aFactory,
   3272         int32 aFactoryTag,
   3273         const PvmfMimeString* aFactoryConfig)
   3274 {
   3275     OSCL_UNUSED_ARG(aFactoryTag);
   3276     OSCL_UNUSED_ARG(aFactoryConfig);
   3277 
   3278     iDataStreamFactory = &aFactory;
   3279     PVUuid uuid = PVMIDataStreamSyncInterfaceUuid;
   3280     PVInterface* iFace =
   3281         iDataStreamFactory->CreatePVMFCPMPluginAccessInterface(uuid);
   3282     if (iFace != NULL)
   3283     {
   3284         iDataStreamInterface = OSCL_STATIC_CAST(PVMIDataStreamSyncInterface*, iFace);
   3285         iDataStreamInterface->OpenSession(iDataStreamSessionID, PVDS_READ_ONLY);
   3286     }
   3287 }
   3288 
   3289 void
   3290 PVMFAMRFFParserNode::PassDatastreamReadCapacityObserver(PVMFDataStreamReadCapacityObserver* aObserver)
   3291 {
   3292     iDataStreamReadCapacityObserver = aObserver;
   3293 }
   3294 
   3295 void PVMFAMRFFParserNode::CompleteInit()
   3296 {
   3297     PVMF_AMRPARSERNODE_LOGSTACKTRACE((0, "PVMFAMRParserNode::CompleteInit() Called"));
   3298     if (iCPM)
   3299     {
   3300 
   3301         if ((iCPMContentType == PVMF_CPM_FORMAT_OMA1) ||
   3302                 (iCPMContentType == PVMF_CPM_FORMAT_AUTHORIZE_BEFORE_ACCESS))
   3303         {
   3304             if (iApprovedUsage.value.uint32_value !=
   3305                     iRequestedUsage.value.uint32_value)
   3306             {
   3307                 CommandComplete(iCurrentCommand,
   3308                                 iCurrentCommand.front(),
   3309                                 PVMFErrAccessDenied,
   3310                                 NULL, NULL, NULL);
   3311                 return;
   3312             }
   3313         }
   3314     }
   3315     SetState(EPVMFNodeInitialized);
   3316     CommandComplete(iCurrentCommand,
   3317                     iCurrentCommand.front(),
   3318                     PVMFSuccess);
   3319     return;
   3320 }
   3321 
   3322 void PVMFAMRFFParserNode::CompleteGetMetaDataValues()
   3323 {
   3324     CommandComplete(iCurrentCommand,
   3325                     iCurrentCommand.front(),
   3326                     PVMFSuccess);
   3327 }
   3328 
   3329 void PVMFAMRFFParserNode::setFileSize(const uint32 aFileSize)
   3330 {
   3331     iDownloadFileSize = aFileSize;
   3332 }
   3333 
   3334 int32 PVMFAMRFFParserNode::convertSizeToTime(uint32 aFileSize, uint32& aNPTInMS)
   3335 {
   3336     OSCL_UNUSED_ARG(aFileSize);
   3337     OSCL_UNUSED_ARG(aNPTInMS);
   3338     return -1;
   3339 }
   3340 
   3341 void PVMFAMRFFParserNode::setDownloadProgressInterface(PVMFDownloadProgressInterface* aInterface)
   3342 {
   3343     if (aInterface == NULL)
   3344     {
   3345         OSCL_ASSERT(false);
   3346     }
   3347     iDownloadProgressInterface = aInterface;
   3348 }
   3349 
   3350 void PVMFAMRFFParserNode::DataStreamInformationalEvent(const PVMFAsyncEvent& aEvent)
   3351 {
   3352     OSCL_UNUSED_ARG(aEvent);
   3353     OSCL_LEAVE(OsclErrNotSupported);
   3354 }
   3355 
   3356 void PVMFAMRFFParserNode::DataStreamErrorEvent(const PVMFAsyncEvent& aEvent)
   3357 {
   3358     OSCL_UNUSED_ARG(aEvent);
   3359     OSCL_LEAVE(OsclErrNotSupported);
   3360 }
   3361 
   3362 void PVMFAMRFFParserNode::DataStreamCommandCompleted(const PVMFCmdResp& aResponse)
   3363 {
   3364     if (aResponse.GetCmdId() == iRequestReadCapacityNotificationID)
   3365     {
   3366         PVMFStatus cmdStatus = aResponse.GetCmdStatus();
   3367         if (cmdStatus == PVMFSuccess)
   3368         {
   3369             if (CheckForAMRHeaderAvailability() == PVMFSuccess)
   3370             {
   3371                 if (iCPMContentType == PVMF_CPM_FORMAT_AUTHORIZE_BEFORE_ACCESS)
   3372                 {
   3373                     if (ParseAMRFile())
   3374                     {
   3375                         {
   3376                             /* End of Node Init sequence. */
   3377                             OSCL_ASSERT(!iCurrentCommand.empty());
   3378                             OSCL_ASSERT(iCurrentCommand.front().iCmd == PVMF_AMR_PARSER_NODE_INIT);
   3379                             CompleteInit();
   3380                         }
   3381                     }
   3382                 }
   3383                 else
   3384                 {
   3385                     if (ParseAMRFile())
   3386                     {
   3387                         /* End of Node Init sequence. */
   3388                         OSCL_ASSERT(!iCurrentCommand.empty());
   3389                         OSCL_ASSERT(iCurrentCommand.front().iCmd == PVMF_AMR_PARSER_NODE_INIT);
   3390                         CompleteInit();
   3391                     }
   3392                 }
   3393             }
   3394         }
   3395         else
   3396         {
   3397             PVMF_AMRPARSERNODE_LOGERROR((0, "PVMFAMRParserNode::DataStreamCommandCompleted() Failed %d", cmdStatus));
   3398             CommandComplete(iCurrentCommand,
   3399                             iCurrentCommand.front(),
   3400                             PVMFErrResource);
   3401 
   3402         }
   3403     }
   3404     else
   3405     {
   3406         OSCL_ASSERT(false);
   3407     }
   3408 }
   3409 
   3410 void PVMFAMRFFParserNode::playResumeNotification(bool aDownloadComplete)
   3411 {
   3412     iAutoPaused = false;
   3413     iDownloadComplete = aDownloadComplete;
   3414     PVAMRFFNodeTrackPortInfo* trackInfoPtr = NULL;
   3415     if (!GetTrackInfo(iOutPort, trackInfoPtr))
   3416     {
   3417         PVMF_AMRPARSERNODE_LOGERROR((0, "PVMFASFParserNode::playResumeNotification: Error - GetPortContainer failed"));
   3418         return;
   3419     }
   3420     if (trackInfoPtr->oQueueOutgoingMessages == false)
   3421     {
   3422         trackInfoPtr->oQueueOutgoingMessages = true;
   3423     }
   3424 
   3425     PVMF_AMRPARSERNODE_LOGERROR((0, "PVMFAMRParserNode::playResumeNotification() - Auto Resume Triggered - FileSize = %d, NPT = %d isDownloadComplete [%d]", iFileSizeLastConvertedToTime, iLastNPTCalcInConvertSizeToTime, iDownloadComplete));
   3426     PVMF_AMRPARSERNODE_LOGDATATRAFFIC((0, "PVMFAMRParserNode::playResumeNotification() - Auto Resume Triggered - FileSize = %d, NPT = %d", iFileSizeLastConvertedToTime, iLastNPTCalcInConvertSizeToTime));
   3427     RunIfNotReady();
   3428 }
   3429 
   3430 void PVMFAMRFFParserNode::CompleteReset()
   3431 {
   3432     PVMF_AMRPARSERNODE_LOGSTACKTRACE((0, "PVMFAMRParserNode::CompleteReset() Called"));
   3433     /* stop and cleanup */
   3434     ReleaseAllPorts();
   3435     CleanupFileSource();
   3436     SetState(EPVMFNodeIdle);
   3437     CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFSuccess);
   3438     return;
   3439 }
   3440 
   3441 PVMFStatus PVMFAMRFFParserNode::ThreadLogoff()
   3442 {
   3443     PVMF_AMRPARSERNODE_LOGSTACKTRACE((0, "PVMFAMRParserNode::ThreadLogoff() Called"));
   3444     if (iInterfaceState == EPVMFNodeIdle)
   3445     {
   3446         CleanupFileSource();
   3447         iFileServer.Close();
   3448 
   3449         if (IsAdded())
   3450         {
   3451             RemoveFromScheduler();
   3452         }
   3453         iLogger = NULL;
   3454         iDataPathLogger = NULL;
   3455         iClockLogger = NULL;
   3456         SetState(EPVMFNodeCreated);
   3457         return PVMFSuccess;
   3458     }
   3459     PVMF_AMRPARSERNODE_LOGERROR((0, "PVMFAMRParserNode::ThreadLogoff() - Invalid State"));
   3460     return PVMFErrInvalidState;
   3461 }
   3462 
   3463 PVMFStatus PVMFAMRFFParserNode::QueueMediaSample(PVAMRFFNodeTrackPortInfo* aTrackInfoPtr)
   3464 {
   3465     if (iAutoPaused == true)
   3466     {
   3467         aTrackInfoPtr->oQueueOutgoingMessages = false;
   3468         PVMF_AMRPARSERNODE_LOGDATATRAFFIC((0, "PVMFAMRParserNode::QueueMediaSample() - Auto Paused"));
   3469         return PVMFErrBusy;
   3470     }
   3471     if (aTrackInfoPtr->iPort->IsOutgoingQueueBusy())
   3472     {
   3473         aTrackInfoPtr->oQueueOutgoingMessages = false;
   3474         PVMF_AMRPARSERNODE_LOGDATATRAFFIC((0, "PVMFAMRParserNode::QueueMediaSample() Port Outgoing Queue Busy"));
   3475         return PVMFErrBusy;
   3476     }
   3477     if (aTrackInfoPtr->oQueueOutgoingMessages)
   3478     {
   3479         PVMFStatus status;
   3480         if (aTrackInfoPtr->iSendBOS == true)
   3481         {
   3482             status = SendBeginOfMediaStreamCommand(aTrackInfoPtr);
   3483             return status;
   3484         }
   3485 
   3486         if (aTrackInfoPtr->oEOSReached == false)
   3487         {
   3488             PVMFSharedMediaDataPtr mediaDataOut;
   3489             status = RetrieveMediaSample(aTrackInfoPtr, mediaDataOut);
   3490             if (status == PVMFErrBusy)
   3491             {
   3492                 PVMF_AMRPARSERNODE_LOGINFO((0, "PVMFAMRParserNode::QueueMediaSample() RetrieveMediaSample - Mem Pools Busy"));
   3493                 aTrackInfoPtr->oQueueOutgoingMessages = false;
   3494                 if (iAutoPaused == true)
   3495                 {
   3496                     PauseAllMediaRetrieval();
   3497                 }
   3498                 return status;
   3499             }
   3500             else if (status == PVMFSuccess)
   3501             {
   3502                 if (aTrackInfoPtr->oEOSReached == false)
   3503                 {
   3504                     mediaDataOut->setStreamID(iStreamID);
   3505                     PVMFSharedMediaMsgPtr msgOut;
   3506                     convertToPVMFMediaMsg(msgOut, mediaDataOut);
   3507 
   3508                     /* For logging purposes */
   3509                     uint32 markerInfo = mediaDataOut->getMarkerInfo();
   3510                     uint32 noRender = 0;
   3511                     uint32 keyFrameBit = 0;
   3512                     if (markerInfo & PVMF_MEDIA_DATA_MARKER_INFO_NO_RENDER_BIT)
   3513                     {
   3514                         noRender = 1;
   3515                     }
   3516                     if (markerInfo & PVMF_MEDIA_DATA_MARKER_INFO_RANDOM_ACCESS_POINT_BIT)
   3517                     {
   3518                         keyFrameBit = 1;
   3519                     }
   3520 
   3521                     status = aTrackInfoPtr->iPort->QueueOutgoingMsg(msgOut);
   3522 
   3523                     if (status != PVMFSuccess)
   3524                     {
   3525                         PVMF_AMRPARSERNODE_LOGERROR((0, "PVMFAMRParserNode::QueueMediaSample: Error - QueueOutgoingMsg failed"));
   3526                         ReportErrorEvent(PVMFErrPortProcessing);
   3527                     }
   3528                     /* This flag will get reset to false if the connected port is busy */
   3529                     aTrackInfoPtr->oProcessOutgoingMessages = true;
   3530                     return status;
   3531                 }
   3532             }
   3533             else
   3534             {
   3535                 PVMF_AMRPARSERNODE_LOGERROR((0, "PVMFAMRParserNode::QueueMediaSample() - Sample Retrieval Failed"));
   3536                 ReportErrorEvent(PVMFErrCorrupt);
   3537                 return PVMFFailure;
   3538             }
   3539         }
   3540         else
   3541         {
   3542             status = GenerateAndSendEOSCommand(aTrackInfoPtr);
   3543             return status;
   3544         }
   3545     }
   3546     return PVMFSuccess;
   3547 }
   3548 
   3549 
   3550 PVMFStatus PVMFAMRFFParserNode::RetrieveMediaSample(PVAMRFFNodeTrackPortInfo* aTrackInfoPtr,
   3551         PVMFSharedMediaDataPtr& aMediaDataOut)
   3552 {
   3553 
   3554     // Create a data buffer from pool
   3555     int errcode = OsclErrNoResources;
   3556     OsclSharedPtr<PVMFMediaDataImpl> mediaDataImplOut;
   3557     mediaDataImplOut = aTrackInfoPtr->iResizableSimpleMediaMsgAlloc->allocate(MAXTRACKDATASIZE);
   3558 
   3559     if (mediaDataImplOut.GetRep() != NULL)
   3560     {
   3561         errcode = OsclErrNone;
   3562     }
   3563 
   3564     OsclMemPoolResizableAllocatorObserver* resizableAllocObs =
   3565         OSCL_STATIC_CAST(OsclMemPoolResizableAllocatorObserver*, aTrackInfoPtr);
   3566 
   3567     // Enable flag to receive event when next deallocate() is called on pool
   3568     if (errcode != OsclErrNone)
   3569     {
   3570         aTrackInfoPtr->iResizableDataMemoryPool->notifyfreeblockavailable(*resizableAllocObs);
   3571         return PVMFErrBusy;
   3572     }
   3573 
   3574     // Now create a PVMF media data from pool
   3575     errcode = OsclErrNoResources;
   3576     aMediaDataOut = PVMFMediaData::createMediaData(mediaDataImplOut, aTrackInfoPtr->iMediaDataMemPool);
   3577 
   3578     if (aMediaDataOut.GetRep() != NULL)
   3579     {
   3580         errcode = OsclErrNone;
   3581     }
   3582 
   3583     OsclMemPoolFixedChunkAllocatorObserver* fixedChunkObs =
   3584         OSCL_STATIC_CAST(OsclMemPoolFixedChunkAllocatorObserver*, aTrackInfoPtr);
   3585 
   3586     // Enable flag to receive event when next deallocate() is called on pool
   3587     if (errcode != OsclErrNone)
   3588     {
   3589         aTrackInfoPtr->iMediaDataMemPool->notifyfreechunkavailable(*fixedChunkObs);
   3590         return PVMFErrBusy;
   3591     }
   3592 
   3593 
   3594     // Retrieve memory fragment to write to
   3595     OsclRefCounterMemFrag refCtrMemFragOut;
   3596     OsclMemoryFragment memFragOut;
   3597     aMediaDataOut->getMediaFragment(0, refCtrMemFragOut);
   3598     memFragOut.ptr = refCtrMemFragOut.getMemFrag().ptr;
   3599 
   3600     Oscl_Vector<uint32, OsclMemAllocator> payloadSizeVec;
   3601 
   3602     uint32 numsamples = NUM_AMR_FRAMES;
   3603     // Set up the GAU structure
   3604     GAU gau;
   3605     gau.numMediaSamples = numsamples;
   3606     gau.buf.num_fragments = 1;
   3607     gau.buf.buf_states[0] = NULL;
   3608     gau.buf.fragments[0].ptr = refCtrMemFragOut.getMemFrag().ptr;
   3609     gau.buf.fragments[0].len = refCtrMemFragOut.getCapacity();
   3610 
   3611     int32 retval = iAMRParser->GetNextBundledAccessUnits(&numsamples, &gau);
   3612     uint32 actualdatasize = 0;
   3613     for (uint32 i = 0; i < numsamples; ++i)
   3614     {
   3615         actualdatasize += gau.info[i].len;
   3616     }
   3617 
   3618     if (retval == bitstreamObject::EVERYTHING_OK)
   3619     {
   3620         memFragOut.len = actualdatasize;
   3621 
   3622         // Set Actual size
   3623         aMediaDataOut->setMediaFragFilledLen(0, actualdatasize);
   3624 
   3625         // Resize memory fragment
   3626         aTrackInfoPtr->iResizableSimpleMediaMsgAlloc->ResizeMemoryFragment(mediaDataImplOut);
   3627 
   3628 
   3629         // set current timestamp to media msg.
   3630         aTrackInfoPtr->iClockConverter->update_clock(Oscl_Int64_Utils::get_uint64_lower32(aTrackInfoPtr->iContinuousTimeStamp));
   3631 
   3632         uint32 ts32 = Oscl_Int64_Utils::get_uint64_lower32(aTrackInfoPtr->iContinuousTimeStamp);
   3633 
   3634         aMediaDataOut->setSeqNum(aTrackInfoPtr->iSeqNum);
   3635         aMediaDataOut->setTimestamp(ts32);
   3636 
   3637         // update ts by adding the data samples
   3638         aTrackInfoPtr->iContinuousTimeStamp += numsamples * AMR_SAMPLE_DURATION; // i.e 20ms
   3639 
   3640 
   3641         if (aTrackInfoPtr->iSeqNum == 0)
   3642         {
   3643             aMediaDataOut->setFormatSpecificInfo(aTrackInfoPtr->iFormatSpecificConfig);
   3644         }
   3645         aTrackInfoPtr->iSeqNum += 1;
   3646 
   3647         // Set M bit to 1 always - ASF FF only outputs complete frames
   3648         uint32 markerInfo = 0;
   3649         markerInfo |= PVMF_MEDIA_DATA_MARKER_INFO_M_BIT;
   3650 
   3651         // Reset random access point if first frame after repositioning
   3652         if (aTrackInfoPtr->iFirstFrame)
   3653         {
   3654             markerInfo |= PVMF_MEDIA_DATA_MARKER_INFO_RANDOM_ACCESS_POINT_BIT;
   3655             aTrackInfoPtr->iFirstFrame = false;
   3656         }
   3657         mediaDataImplOut->setMarkerInfo(markerInfo);
   3658     }
   3659     else if (retval == bitstreamObject::DATA_INSUFFICIENT)
   3660     {
   3661         payloadSizeVec.clear();
   3662         if (iDownloadProgressInterface != NULL)
   3663         {
   3664             if (iDownloadComplete)
   3665             {
   3666                 aTrackInfoPtr->oEOSReached = true;
   3667                 return PVMFSuccess;
   3668             }
   3669             iDownloadProgressInterface->requestResumeNotification(aTrackInfoPtr->iContinuousTimeStamp,
   3670                     iDownloadComplete);
   3671             iAutoPaused = true;
   3672             PVMF_AMRPARSERNODE_LOGERROR((0, "PVMFAMRParserNode::RetrieveMediaSample() - Auto Pause Triggered - TS=%d", aTrackInfoPtr->iContinuousTimeStamp));
   3673             PVMF_AMRPARSERNODE_LOGDATATRAFFIC((0, "PVMFAMRParserNode::RetrieveMediaSample() - Auto Pause Triggered - TS=%d", aTrackInfoPtr->iContinuousTimeStamp));
   3674             return PVMFErrBusy;
   3675         }
   3676         else
   3677         {
   3678             // if we recieve Insufficient data for local playback from parser library that means
   3679             // its end of track, so change track state to send end of track.
   3680             aTrackInfoPtr->oEOSReached = true;
   3681         }
   3682     }
   3683     else if (retval == bitstreamObject::END_OF_FILE)
   3684     {
   3685         aTrackInfoPtr->oEOSReached = true;
   3686     }
   3687     else
   3688     {
   3689         PVMF_AMRPARSERNODE_LOGERROR((0, "PVMFAMRParserNode::RetrieveMediaSample() - Sample Retrieval Failed"));
   3690         return PVMFFailure;
   3691     }
   3692 
   3693     return PVMFSuccess;
   3694 }
   3695 
   3696 
   3697 void PVMFAMRFFParserNode::PauseAllMediaRetrieval()
   3698 {
   3699     PVAMRFFNodeTrackPortInfo* trackInfoPtr = NULL;
   3700     if (!GetTrackInfo(iOutPort, trackInfoPtr))
   3701     {
   3702         PVMF_AMRPARSERNODE_LOGERROR((0, "PVMFAMRParserNode::PauseAllMediaRetrieval: Error - GetPortContainer failed"));
   3703         return;
   3704     }
   3705     trackInfoPtr->oQueueOutgoingMessages = false;
   3706 
   3707     return;
   3708 }
   3709 
   3710 PVMFStatus PVMFAMRFFParserNode:: GenerateAndSendEOSCommand(PVAMRFFNodeTrackPortInfo* aTrackInfoPtr)
   3711 {
   3712     PVMF_AMRPARSERNODE_LOGSTACKTRACE((0, "PVMFAMRParserNode::GenerateAndSendEOSCommand Called"));
   3713     if (aTrackInfoPtr->iPort->IsOutgoingQueueBusy() == true)
   3714     {
   3715         /* come back later */
   3716         PVMF_AMRPARSERNODE_LOGDATATRAFFIC((0, "PVMFAMRParserNode::GenerateAndSendEOSCommand: Waiting - Output Queue Busy"));
   3717         return PVMFErrBusy;
   3718     }
   3719 
   3720     if ((aTrackInfoPtr->oEOSSent == false) && (aTrackInfoPtr->oEOSReached == true))
   3721     {
   3722         PVMFSharedMediaCmdPtr sharedMediaCmdPtr = PVMFMediaCmd::createMediaCmd();
   3723 
   3724         sharedMediaCmdPtr->setFormatID(PVMF_MEDIA_CMD_EOS_FORMAT_ID);
   3725 
   3726         sharedMediaCmdPtr->setStreamID(iStreamID);
   3727 
   3728         sharedMediaCmdPtr->setSeqNum(aTrackInfoPtr->iSeqNum++);
   3729 
   3730         uint32 ts32 = Oscl_Int64_Utils::get_uint64_lower32(aTrackInfoPtr->iContinuousTimeStamp);
   3731         sharedMediaCmdPtr->setTimestamp(ts32);
   3732 
   3733         PVMFSharedMediaMsgPtr msg;
   3734         convertToPVMFMediaCmdMsg(msg, sharedMediaCmdPtr);
   3735 
   3736         PVMFStatus status = aTrackInfoPtr->iPort->QueueOutgoingMsg(msg);
   3737         if (status != PVMFSuccess)
   3738         {
   3739             ReportErrorEvent(PVMFErrPortProcessing, (OsclAny*)(aTrackInfoPtr->iPort));
   3740             PVMF_AMRPARSERNODE_LOGERROR((0, "PVMFAMRParserNode::GenerateAndSendEOSCommand: Error Sending EOS"));
   3741             return status;
   3742         }
   3743         aTrackInfoPtr->oEOSSent = true;
   3744         aTrackInfoPtr->oQueueOutgoingMessages = false;
   3745         aTrackInfoPtr->oProcessOutgoingMessages = true;
   3746         return (status);
   3747     }
   3748     aTrackInfoPtr->oQueueOutgoingMessages = false;
   3749     return PVMFFailure;
   3750 
   3751 }
   3752 bool PVMFAMRFFParserNode::RetrieveTrackData(PVAMRFFNodeTrackPortInfo& aTrackPortInfo)
   3753 {
   3754     // Create a data buffer from pool
   3755     int errcode = 0;
   3756     OsclSharedPtr<PVMFMediaDataImpl> mediaDataImplOut;
   3757     OSCL_TRY(errcode, mediaDataImplOut = aTrackPortInfo.iMediaDataImplAlloc->allocate(MAXTRACKDATASIZE));
   3758 
   3759     if (errcode != 0)
   3760     {
   3761         if (errcode == OsclErrNoResources)
   3762         {
   3763             aTrackPortInfo.iTrackDataMemoryPool->notifyfreechunkavailable(aTrackPortInfo);  // Enable flag to receive event when next deallocate() is called on pool
   3764             return false;
   3765         }
   3766         else if (errcode == OsclErrNoMemory)
   3767         {
   3768             // Memory allocation for the pool failed
   3769             ReportErrorEvent(PVMFErrNoMemory, NULL);
   3770             return false;
   3771         }
   3772         else if (errcode == OsclErrArgument)
   3773         {
   3774             // Invalid parameters passed to mempool
   3775             ReportErrorEvent(PVMFErrArgument, NULL);
   3776             return false;
   3777         }
   3778         else
   3779         {
   3780             // General error
   3781             ReportErrorEvent(PVMFFailure, NULL);
   3782             return false;
   3783         }
   3784 
   3785     }
   3786 
   3787     // Now create a PVMF media data from pool
   3788     errcode = OsclErrNoResources;
   3789     PVMFSharedMediaDataPtr mediadataout;
   3790     mediadataout = PVMFMediaData::createMediaData(mediaDataImplOut, aTrackPortInfo.iMediaDataMemPool);
   3791 
   3792     if (mediadataout.GetRep() != NULL)
   3793     {
   3794         errcode = OsclErrNone;
   3795     }
   3796     else
   3797     {
   3798         aTrackPortInfo.iMediaDataMemPool->notifyfreechunkavailable(aTrackPortInfo);     // Enable flag to receive event when next deallocate() is called on pool
   3799         return false;
   3800     }
   3801 
   3802     // Set the random access point flag if first frame
   3803     if (aTrackPortInfo.iFirstFrame == true)
   3804     {
   3805         uint32 markerInfo = 0;
   3806         markerInfo |= PVMF_MEDIA_DATA_MARKER_INFO_RANDOM_ACCESS_POINT_BIT;
   3807         mediaDataImplOut->setMarkerInfo(markerInfo);
   3808         aTrackPortInfo.iFirstFrame = false;
   3809     }
   3810 
   3811     // Retrieve memory fragment to write to
   3812     OsclRefCounterMemFrag refCtrMemFragOut;
   3813     mediadataout->getMediaFragment(0, refCtrMemFragOut);
   3814 
   3815     // Retrieve one bundle of samples from the file format parser
   3816     // Temporary retrieve 32 frames since AMR MDF needs 32 frames
   3817     uint32 numsamples = NUM_AMR_FRAMES;
   3818 
   3819     // Set up the GAU structure
   3820     GAU gau;
   3821     gau.numMediaSamples = numsamples;
   3822     gau.buf.num_fragments = 1;
   3823     gau.buf.buf_states[0] = NULL;
   3824     gau.buf.fragments[0].ptr = refCtrMemFragOut.getMemFrag().ptr;
   3825     gau.buf.fragments[0].len = refCtrMemFragOut.getCapacity();
   3826 
   3827     int32 retval = iAMRParser->GetNextBundledAccessUnits(&numsamples, &gau);
   3828 
   3829     // Determine actual size of the retrieved data by summing each sample length in GAU
   3830     uint32 actualdatasize = 0;
   3831     for (uint32 i = 0; i < numsamples; ++i)
   3832     {
   3833         actualdatasize += gau.info[i].len;
   3834     }
   3835 
   3836     if (retval == bitstreamObject::EVERYTHING_OK)
   3837     {
   3838         // Set buffer size
   3839         mediadataout->setMediaFragFilledLen(0, actualdatasize);
   3840 
   3841         // Save the media data in the trackport info
   3842         aTrackPortInfo.iMediaData = mediadataout;
   3843 
   3844         // Retrieve timestamp and convert to milliseconds
   3845 
   3846 
   3847         aTrackPortInfo.iClockConverter->update_clock(Oscl_Int64_Utils::get_uint64_lower32(aTrackPortInfo.iContinuousTimeStamp));
   3848 
   3849         uint32 timestamp = Oscl_Int64_Utils::get_uint64_lower32(aTrackPortInfo.iContinuousTimeStamp);
   3850         // Set the media data's timestamp
   3851         aTrackPortInfo.iMediaData->setTimestamp(timestamp);
   3852 
   3853 
   3854         // compute "next" ts based on the duration of the samples that we obtained
   3855         aTrackPortInfo.iContinuousTimeStamp += numsamples * AMR_SAMPLE_DURATION; // i.e 20ms
   3856 
   3857         // Set the sequence number
   3858         aTrackPortInfo.iMediaData->setSeqNum(aTrackPortInfo.iSeqNum++);
   3859 
   3860         return true;
   3861     }
   3862     else if (retval == bitstreamObject::READ_ERROR)
   3863     {
   3864         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFAMRFFParserNode::RetrieveTrackData() AMR Parser READ_ERROR"));
   3865         PVUuid erruuid = PVMFFileFormatEventTypesUUID;
   3866         int32 errcode = PVMFFFErrFileRead;
   3867         ReportErrorEvent(PVMFErrResource, NULL, &erruuid, &errcode);
   3868         return false;
   3869     }
   3870     else if (retval == bitstreamObject::END_OF_FILE)
   3871     {
   3872         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFAMRFFParserNode::RetrieveTrackData() AMR Parser End Of File!"));
   3873         if (SendEndOfTrackCommand(aTrackPortInfo))
   3874         {
   3875             // EOS message sent so change state
   3876             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVMFAMRFFParserNode::RetrieveTrackData() Sending EOS message succeeded"));
   3877             return false;
   3878         }
   3879         else
   3880         {
   3881             // EOS message could not be queued so keep in same state and try again later
   3882             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVMFAMRFFParserNode::RetrieveTrackData() Sending EOS message failed"));
   3883             return true;
   3884         }
   3885     }
   3886     else
   3887     {
   3888         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFAMRFFParserNode::RetrieveTrackData() AMR Parser Unknown Error!"));
   3889         PVUuid erruuid = PVMFFileFormatEventTypesUUID;
   3890         int32 errcode = PVMFFFErrInvalidData;
   3891         ReportErrorEvent(PVMFErrCorrupt, NULL, &erruuid, &errcode);
   3892         return false;
   3893     }
   3894 }
   3895 
   3896 PVMFStatus PVMFAMRFFParserNode::SendBeginOfMediaStreamCommand(PVAMRFFNodeTrackPortInfo* aTrackPortInfoPtr)
   3897 {
   3898     PVMFSharedMediaCmdPtr sharedMediaCmdPtr = PVMFMediaCmd::createMediaCmd();
   3899     sharedMediaCmdPtr->setFormatID(PVMF_MEDIA_CMD_BOS_FORMAT_ID);
   3900 
   3901     uint32 timestamp = Oscl_Int64_Utils::get_uint64_lower32(aTrackPortInfoPtr->iContinuousTimeStamp);
   3902     sharedMediaCmdPtr->setTimestamp(timestamp);
   3903 
   3904     PVMFSharedMediaMsgPtr mediaMsgOut;
   3905     convertToPVMFMediaCmdMsg(mediaMsgOut, sharedMediaCmdPtr);
   3906     mediaMsgOut->setStreamID(iStreamID);
   3907 
   3908     PVMFStatus status =  aTrackPortInfoPtr->iPort->QueueOutgoingMsg(mediaMsgOut);
   3909     if (status != PVMFSuccess)
   3910     {
   3911         // Output queue is busy, so wait for the output queue being ready
   3912         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
   3913                         (0, "PVMFAMRFFParserNode::SendBeginOfMediaStreamCommand: Outgoing queue busy. "));
   3914         return status;
   3915     }
   3916     aTrackPortInfoPtr->iSendBOS = false;
   3917     aTrackPortInfoPtr->oProcessOutgoingMessages = true;
   3918     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFAMRFFParserNode::SendBeginOfMediaStreamCommand() BOS Sent StreamId %d ", iStreamID));
   3919     return status;
   3920 }
   3921 
   3922 PVMFCommandId
   3923 PVMFAMRFFParserNode::GetLicense(PVMFSessionId aSessionId,
   3924                                 OSCL_wString& aContentName,
   3925                                 OsclAny* aData,
   3926                                 uint32 aDataSize,
   3927                                 int32 aTimeoutMsec,
   3928                                 OsclAny* aContextData)
   3929 {
   3930     PVMF_AMRPARSERNODE_LOGDATATRAFFIC((0, "PVMFAMRFFParserNode::GetLicense - Wide called"));
   3931     PVMFAMRFFNodeCommand cmd;
   3932     cmd.PVMFAMRFFNodeCommand::Construct(aSessionId,
   3933                                         PVMF_AMR_PARSER_NODE_GET_LICENSE_W,
   3934                                         aContentName,
   3935                                         aData,
   3936                                         aDataSize,
   3937                                         aTimeoutMsec,
   3938                                         aContextData);
   3939     return QueueCommandL(cmd);
   3940 }
   3941 
   3942 PVMFCommandId
   3943 PVMFAMRFFParserNode::GetLicense(PVMFSessionId aSessionId,
   3944                                 OSCL_String&  aContentName,
   3945                                 OsclAny* aData,
   3946                                 uint32 aDataSize,
   3947                                 int32 aTimeoutMsec,
   3948                                 OsclAny* aContextData)
   3949 {
   3950     PVMF_AMRPARSERNODE_LOGDATATRAFFIC((0, "PVMFAMRFFParserNode::GetLicense - Wide called"));
   3951     PVMFAMRFFNodeCommand cmd;
   3952     cmd.PVMFAMRFFNodeCommand::Construct(aSessionId,
   3953                                         PVMF_AMR_PARSER_NODE_GET_LICENSE,
   3954                                         aContentName,
   3955                                         aData,
   3956                                         aDataSize,
   3957                                         aTimeoutMsec,
   3958                                         aContextData);
   3959     return QueueCommandL(cmd);
   3960 }
   3961 
   3962 PVMFStatus PVMFAMRFFParserNode::DoGetLicense(PVMFAMRFFNodeCommand& aCmd,
   3963         bool aWideCharVersion)
   3964 {
   3965     if (iCPMLicenseInterface == NULL)
   3966     {
   3967         return PVMFErrNotSupported;
   3968     }
   3969 
   3970     if (aWideCharVersion == true)
   3971     {
   3972         OSCL_wString* contentName = NULL;
   3973         OsclAny* data = NULL;
   3974         uint32 dataSize = 0;
   3975         int32 timeoutMsec = 0;
   3976         aCmd.PVMFAMRFFNodeCommand::Parse(contentName,
   3977                                          data,
   3978                                          dataSize,
   3979                                          timeoutMsec);
   3980         iCPMGetLicenseCmdId =
   3981             iCPMLicenseInterface->GetLicense(iCPMSessionID,
   3982                                              *contentName,
   3983                                              data,
   3984                                              dataSize,
   3985                                              timeoutMsec);
   3986     }
   3987     else
   3988     {
   3989         OSCL_String* contentName = NULL;
   3990         OsclAny* data = NULL;
   3991         uint32 dataSize = 0;
   3992         int32 timeoutMsec = 0;
   3993         aCmd.PVMFAMRFFNodeCommand::Parse(contentName,
   3994                                          data,
   3995                                          dataSize,
   3996                                          timeoutMsec);
   3997         iCPMGetLicenseCmdId =
   3998             iCPMLicenseInterface->GetLicense(iCPMSessionID,
   3999                                              *contentName,
   4000                                              data,
   4001                                              dataSize,
   4002                                              timeoutMsec);
   4003     }
   4004     return PVMFPending;
   4005 }
   4006 
   4007 void PVMFAMRFFParserNode::CompleteGetLicense()
   4008 {
   4009     CommandComplete(iCurrentCommand,
   4010                     iCurrentCommand.front(),
   4011                     PVMFSuccess);
   4012 }
   4013 
   4014 PVMFCommandId
   4015 PVMFAMRFFParserNode::CancelGetLicense(PVMFSessionId aSessionId, PVMFCommandId aCmdId, OsclAny* aContextData)
   4016 {
   4017     PVMF_AMRPARSERNODE_LOGDATATRAFFIC((0, "PVMFAMRFFParserNode::CancelGetLicense - called"));
   4018     PVMFAMRFFNodeCommand cmd;
   4019     cmd.PVMFAMRFFNodeCommandBase::Construct(aSessionId, PVMF_AMR_PARSER_NODE_CMD_CANCEL_GET_LICENSE, aCmdId, aContextData);
   4020     return QueueCommandL(cmd);
   4021 }
   4022 
   4023 PVMFStatus PVMFAMRFFParserNode::DoCancelGetLicense(PVMFAMRFFNodeCommand& aCmd)
   4024 {
   4025     PVMF_AMRPARSERNODE_LOGDATATRAFFIC((0, "PVMFAMRFFParserNode::DoCancelGetLicense() Called"));
   4026     PVMFStatus status = PVMFErrArgument;
   4027 
   4028     if (iCPMLicenseInterface == NULL)
   4029     {
   4030         status = PVMFErrNotSupported;
   4031     }
   4032     else
   4033     {
   4034         /* extract the command ID from the parameters.*/
   4035         PVMFCommandId id;
   4036         aCmd.PVMFAMRFFNodeCommandBase::Parse(id);
   4037 
   4038         /* first check "current" command if any */
   4039         PVMFAMRFFNodeCommand* cmd = iCurrentCommand.FindById(id);
   4040         if (cmd)
   4041         {
   4042             if (cmd->iCmd == PVMF_AMR_PARSER_NODE_GET_LICENSE_W || cmd->iCmd == PVMF_AMR_PARSER_NODE_GET_LICENSE)
   4043             {
   4044                 iCPMCancelGetLicenseCmdId =
   4045                     iCPMLicenseInterface->CancelGetLicense(iCPMSessionID, iCPMGetLicenseCmdId);
   4046 
   4047                 /*
   4048                  * the queued commands are all asynchronous commands to the
   4049                  * CPM module. CancelGetLicense can cancel only for GetLicense cmd.
   4050                  * We need to wait CPMCommandCompleted.
   4051                  */
   4052                 return PVMFPending;
   4053             }
   4054         }
   4055 
   4056         /*
   4057          * next check input queue.
   4058          * start at element 1 since this cancel command is element 0.
   4059          */
   4060         cmd = iInputCommands.FindById(id, 1);
   4061         if (cmd)
   4062         {
   4063             if (cmd->iCmd == PVMF_AMR_PARSER_NODE_GET_LICENSE_W || cmd->iCmd == PVMF_AMR_PARSER_NODE_GET_LICENSE)
   4064             {
   4065                 /* cancel the queued command */
   4066                 CommandComplete(iInputCommands, *cmd, PVMFErrCancelled);
   4067                 /* report cancel success */
   4068                 return PVMFSuccess;
   4069             }
   4070         }
   4071     }
   4072     /* if we get here the command isn't queued so the cancel fails */
   4073     return status;
   4074 }
   4075 
   4076 int32 PVMFAMRFFParserNode::PushBackKeyVal(Oscl_Vector<PvmiKvp, OsclMemAllocator>*& aValueListPtr, PvmiKvp &aKeyVal)
   4077 {
   4078     int32 leavecode = 0;
   4079     OSCL_TRY(leavecode, (*aValueListPtr).push_back(aKeyVal));
   4080     return leavecode;
   4081 }
   4082 
   4083 PVMFStatus PVMFAMRFFParserNode::PushValueToList(Oscl_Vector<OSCL_HeapString<OsclMemAllocator>, OsclMemAllocator> &aRefMetaDataKeys, PVMFMetadataList *&aKeyListPtr, uint32 aLcv)
   4084 {
   4085     int32 leavecode = 0;
   4086     OSCL_TRY(leavecode, aKeyListPtr->push_back(aRefMetaDataKeys[aLcv]));
   4087     OSCL_FIRST_CATCH_ANY(leavecode, PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFAMRFFParserNode::PushValueToList() Memory allocation failure when copying metadata key")); return PVMFErrNoMemory);
   4088     return PVMFSuccess;
   4089 }
   4090 
   4091